blob: 0ee8d864250a1dcc4580a41672d2d001e84ba554 [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 Halavatib5e433e2018-02-07 07:41:10457 request.traffic_annotation =
458 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:52459
vishal.b62985ca92015-04-17 08:45:51460 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:07461 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:09462 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16463 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:27464
Ryan Sleevib8d7ea02018-05-07 20:01:01465 for (auto* provider : providers) {
466 session_deps_.socket_factory->AddSocketDataProvider(provider);
[email protected]5a60c8b2011-10-19 20:14:29467 }
initial.commit586acc5fe2008-07-26 22:42:52468
[email protected]49639fa2011-12-20 23:22:41469 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52470
eroman24bc6a12015-05-06 19:55:48471 EXPECT_TRUE(log.bound().IsCapturing());
bnc691fda62016-08-12 00:43:16472 int rv = trans.Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:01473 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:52474
[email protected]ff007e162009-05-23 09:13:15475 out.rv = callback.WaitForResult();
bnc691fda62016-08-12 00:43:16476 out.total_received_bytes = trans.GetTotalReceivedBytes();
477 out.total_sent_bytes = trans.GetTotalSentBytes();
[email protected]58e32bb2013-01-21 18:23:25478
479 // Even in the failure cases that use this function, connections are always
480 // successfully established before the error.
bnc691fda62016-08-12 00:43:16481 EXPECT_TRUE(trans.GetLoadTimingInfo(&out.load_timing_info));
[email protected]58e32bb2013-01-21 18:23:25482 TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
483
[email protected]ff007e162009-05-23 09:13:15484 if (out.rv != OK)
485 return out;
486
bnc691fda62016-08-12 00:43:16487 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50488 // Can't use ASSERT_* inside helper functions like this, so
489 // return an error.
wezca1070932016-05-26 20:30:52490 if (!response || !response->headers) {
[email protected]fe2255a2011-09-20 19:37:50491 out.rv = ERR_UNEXPECTED;
492 return out;
493 }
[email protected]ff007e162009-05-23 09:13:15494 out.status_line = response->headers->GetStatusLine();
495
Tsuyoshi Horo01faed62019-02-20 22:11:37496 EXPECT_EQ("127.0.0.1", response->remote_endpoint.ToStringWithoutPort());
497 EXPECT_EQ(80, response->remote_endpoint.port());
[email protected]6d81b482011-02-22 19:47:19498
ttuttled9dbc652015-09-29 20:00:59499 bool got_endpoint =
bnc691fda62016-08-12 00:43:16500 trans.GetRemoteEndpoint(&out.remote_endpoint_after_start);
ttuttled9dbc652015-09-29 20:00:59501 EXPECT_EQ(got_endpoint,
502 out.remote_endpoint_after_start.address().size() > 0);
503
bnc691fda62016-08-12 00:43:16504 rv = ReadTransaction(&trans, &out.response_data);
robpercival214763f2016-07-01 23:27:01505 EXPECT_THAT(rv, IsOk());
[email protected]b2fcd0e2010-12-01 15:19:40506
mmenke43758e62015-05-04 21:09:46507 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40508 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:39509 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00510 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
511 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:39512 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00513 entries, pos, NetLogEventType::HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
514 NetLogEventPhase::NONE);
[email protected]ff007e162009-05-23 09:13:15515
[email protected]f3da152d2012-06-02 01:00:57516 std::string line;
517 EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
518 EXPECT_EQ("GET / HTTP/1.1\r\n", line);
519
[email protected]79e1fd62013-06-20 06:50:04520 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:16521 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:04522 std::string value;
523 EXPECT_TRUE(request_headers.GetHeader("Host", &value));
bncce36dca22015-04-21 22:11:23524 EXPECT_EQ("www.example.org", value);
[email protected]79e1fd62013-06-20 06:50:04525 EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
526 EXPECT_EQ("keep-alive", value);
527
528 std::string response_headers;
529 EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
bncce36dca22015-04-21 22:11:23530 EXPECT_EQ("['Host: www.example.org','Connection: keep-alive']",
[email protected]79e1fd62013-06-20 06:50:04531 response_headers);
[email protected]3deb9a52010-11-11 00:24:40532
bnc691fda62016-08-12 00:43:16533 out.total_received_bytes = trans.GetTotalReceivedBytes();
sclittlefb249892015-09-10 21:33:22534 // The total number of sent bytes should not have changed.
bnc691fda62016-08-12 00:43:16535 EXPECT_EQ(out.total_sent_bytes, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:22536
bnc691fda62016-08-12 00:43:16537 trans.GetConnectionAttempts(&out.connection_attempts);
[email protected]aecfbf22008-10-16 02:02:47538 return out;
[email protected]ff007e162009-05-23 09:13:15539 }
initial.commit586acc5fe2008-07-26 22:42:52540
Ryan Sleevib8d7ea02018-05-07 20:01:01541 SimpleGetHelperResult SimpleGetHelper(base::span<const MockRead> data_reads) {
sclittlefb249892015-09-10 21:33:22542 MockWrite data_writes[] = {
543 MockWrite("GET / HTTP/1.1\r\n"
544 "Host: www.example.org\r\n"
545 "Connection: keep-alive\r\n\r\n"),
546 };
[email protected]5a60c8b2011-10-19 20:14:29547
Ryan Sleevib8d7ea02018-05-07 20:01:01548 StaticSocketDataProvider reads(data_reads, data_writes);
sclittlefb249892015-09-10 21:33:22549 StaticSocketDataProvider* data[] = {&reads};
Ryan Sleevib8d7ea02018-05-07 20:01:01550 SimpleGetHelperResult out = SimpleGetHelperForData(data);
sclittlefb249892015-09-10 21:33:22551
Ryan Sleevib8d7ea02018-05-07 20:01:01552 EXPECT_EQ(CountWriteBytes(data_writes), out.total_sent_bytes);
sclittlefb249892015-09-10 21:33:22553 return out;
[email protected]b8015c42013-12-24 15:18:19554 }
555
bnc032658ba2016-09-26 18:17:15556 void AddSSLSocketData() {
557 ssl_.next_proto = kProtoHTTP2;
Ryan Sleevi4f832092017-11-21 23:25:49558 ssl_.ssl_info.cert =
559 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
560 ASSERT_TRUE(ssl_.ssl_info.cert);
bnc032658ba2016-09-26 18:17:15561 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_);
562 }
563
[email protected]ff007e162009-05-23 09:13:15564 void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
565 int expected_status);
initial.commit586acc5fe2008-07-26 22:42:52566
[email protected]ff007e162009-05-23 09:13:15567 void ConnectStatusHelper(const MockRead& status);
[email protected]bb88e1d32013-05-03 23:11:07568
[email protected]bb88e1d32013-05-03 23:11:07569 void CheckErrorIsPassedBack(int error, IoMode mode);
570
Matt Menked6fd2a52019-03-20 06:14:36571 const CommonConnectJobParams dummy_connect_job_params_;
572
Douglas Creager134b52e2018-11-09 18:00:14573 // These clocks are defined here, even though they're only used in the
574 // Reporting tests below, since they need to be destroyed after
575 // |session_deps_|.
576 base::SimpleTestClock clock_;
577 base::SimpleTestTickClock tick_clock_;
578
[email protected]4bd46222013-05-14 19:32:23579 SpdyTestUtil spdy_util_;
[email protected]bb88e1d32013-05-03 23:11:07580 SpdySessionDependencies session_deps_;
bnc032658ba2016-09-26 18:17:15581 SSLSocketDataProvider ssl_;
[email protected]483fa202013-05-14 01:07:03582
583 // Original socket limits. Some tests set these. Safest to always restore
584 // them once each test has been run.
585 int old_max_group_sockets_;
586 int old_max_pool_sockets_;
[email protected]ff007e162009-05-23 09:13:15587};
[email protected]231d5a32008-09-13 00:45:27588
[email protected]448d4ca52012-03-04 04:12:23589namespace {
590
ryansturm49a8cb12016-06-15 16:51:09591class BeforeHeadersSentHandler {
[email protected]597a1ab2014-06-26 08:12:27592 public:
ryansturm49a8cb12016-06-15 16:51:09593 BeforeHeadersSentHandler()
594 : observed_before_headers_sent_with_proxy_(false),
595 observed_before_headers_sent_(false) {}
[email protected]597a1ab2014-06-26 08:12:27596
ryansturm49a8cb12016-06-15 16:51:09597 void OnBeforeHeadersSent(const ProxyInfo& proxy_info,
598 HttpRequestHeaders* request_headers) {
599 observed_before_headers_sent_ = true;
600 if (!proxy_info.is_http() && !proxy_info.is_https() &&
601 !proxy_info.is_quic()) {
602 return;
603 }
604 observed_before_headers_sent_with_proxy_ = true;
[email protected]597a1ab2014-06-26 08:12:27605 observed_proxy_server_uri_ = proxy_info.proxy_server().ToURI();
606 }
607
ryansturm49a8cb12016-06-15 16:51:09608 bool observed_before_headers_sent_with_proxy() const {
609 return observed_before_headers_sent_with_proxy_;
610 }
611
612 bool observed_before_headers_sent() const {
613 return observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27614 }
615
616 std::string observed_proxy_server_uri() const {
617 return observed_proxy_server_uri_;
618 }
619
620 private:
ryansturm49a8cb12016-06-15 16:51:09621 bool observed_before_headers_sent_with_proxy_;
622 bool observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27623 std::string observed_proxy_server_uri_;
624
ryansturm49a8cb12016-06-15 16:51:09625 DISALLOW_COPY_AND_ASSIGN(BeforeHeadersSentHandler);
[email protected]597a1ab2014-06-26 08:12:27626};
627
[email protected]15a5ccf82008-10-23 19:57:43628// Fill |str| with a long header list that consumes >= |size| bytes.
629void FillLargeHeadersString(std::string* str, int size) {
thestig9d3bb0c2015-01-24 00:49:51630 const char row[] =
[email protected]4ddaf2502008-10-23 18:26:19631 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
632 const int sizeof_row = strlen(row);
633 const int num_rows = static_cast<int>(
634 ceil(static_cast<float>(size) / sizeof_row));
635 const int sizeof_data = num_rows * sizeof_row;
636 DCHECK(sizeof_data >= size);
[email protected]15a5ccf82008-10-23 19:57:43637 str->reserve(sizeof_data);
[email protected]372d34a2008-11-05 21:30:51638
[email protected]4ddaf2502008-10-23 18:26:19639 for (int i = 0; i < num_rows; ++i)
[email protected]15a5ccf82008-10-23 19:57:43640 str->append(row, sizeof_row);
[email protected]4ddaf2502008-10-23 18:26:19641}
642
thakis84dff942015-07-28 20:47:38643#if defined(NTLM_PORTABLE)
Zentaro Kavanagh6ccee512017-09-28 18:34:09644uint64_t MockGetMSTime() {
645 // Tue, 23 May 2017 20:13:07 +0000
646 return 131400439870000000;
647}
648
[email protected]385a4672009-03-11 22:21:29649// Alternative functions that eliminate randomness and dependency on the local
650// host name so that the generated NTLM messages are reproducible.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:37651void MockGenerateRandom(uint8_t* output, size_t n) {
652 // This is set to 0xaa because the client challenge for testing in
653 // [MS-NLMP] Section 4.2.1 is 8 bytes of 0xaa.
654 memset(output, 0xaa, n);
[email protected]385a4672009-03-11 22:21:29655}
656
[email protected]fe2bc6a2009-03-23 16:52:20657std::string MockGetHostName() {
Zentaro Kavanagh5b27a6e22017-09-25 23:00:37658 return ntlm::test::kHostnameAscii;
[email protected]385a4672009-03-11 22:21:29659}
thakis84dff942015-07-28 20:47:38660#endif // defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29661
Matt Menked6fd2a52019-03-20 06:14:36662class CaptureGroupIdTransportSocketPool : public TransportClientSocketPool {
[email protected]04e5be32009-06-26 20:00:31663 public:
Matt Menked6fd2a52019-03-20 06:14:36664 explicit CaptureGroupIdTransportSocketPool(
665 const CommonConnectJobParams* common_connect_job_params)
666 : TransportClientSocketPool(0,
667 0,
668 base::TimeDelta(),
669 common_connect_job_params,
670 nullptr /* ssl_config_service */) {}
[email protected]e60e47a2010-07-14 03:37:18671
Matt Menkef6edce752019-03-19 17:21:56672 const ClientSocketPool::GroupId& last_group_id_received() const {
673 return last_group_id_;
[email protected]d80a4322009-08-14 07:07:49674 }
675
Tarun Bansal162eabe52018-01-20 01:16:39676 bool socket_requested() const { return socket_requested_; }
677
Matt Menke28ac03e2019-02-25 22:25:50678 int RequestSocket(
Matt Menkef6edce752019-03-19 17:21:56679 const ClientSocketPool::GroupId& group_id,
Matt Menkebd12b7e2019-03-25 21:12:03680 scoped_refptr<ClientSocketPool::SocketParams> socket_params,
Matt Menke28ac03e2019-02-25 22:25:50681 RequestPriority priority,
682 const SocketTag& socket_tag,
683 ClientSocketPool::RespectLimits respect_limits,
684 ClientSocketHandle* handle,
685 CompletionOnceCallback callback,
686 const ClientSocketPool::ProxyAuthCallback& proxy_auth_callback,
687 const NetLogWithSource& net_log) override {
Matt Menkef6edce752019-03-19 17:21:56688 last_group_id_ = group_id;
Tarun Bansal162eabe52018-01-20 01:16:39689 socket_requested_ = true;
[email protected]04e5be32009-06-26 20:00:31690 return ERR_IO_PENDING;
691 }
Matt Menkef6edce752019-03-19 17:21:56692 void CancelRequest(const ClientSocketPool::GroupId& group_id,
dmichaeld6e570d2014-12-18 22:30:57693 ClientSocketHandle* handle) override {}
Matt Menkef6edce752019-03-19 17:21:56694 void ReleaseSocket(const ClientSocketPool::GroupId& group_id,
danakj1fd259a02016-04-16 03:17:09695 std::unique_ptr<StreamSocket> socket,
dmichaeld6e570d2014-12-18 22:30:57696 int id) override {}
697 void CloseIdleSockets() override {}
Matt Menkef6edce752019-03-19 17:21:56698 void CloseIdleSocketsInGroup(
699 const ClientSocketPool::GroupId& group_id) override {}
dmichaeld6e570d2014-12-18 22:30:57700 int IdleSocketCount() const override { return 0; }
Matt Menkef6edce752019-03-19 17:21:56701 size_t IdleSocketCountInGroup(
702 const ClientSocketPool::GroupId& group_id) const override {
[email protected]04e5be32009-06-26 20:00:31703 return 0;
704 }
Matt Menkef6edce752019-03-19 17:21:56705 LoadState GetLoadState(const ClientSocketPool::GroupId& group_id,
dmichaeld6e570d2014-12-18 22:30:57706 const ClientSocketHandle* handle) const override {
[email protected]04e5be32009-06-26 20:00:31707 return LOAD_STATE_IDLE;
708 }
[email protected]d80a4322009-08-14 07:07:49709
710 private:
Matt Menkef6edce752019-03-19 17:21:56711 ClientSocketPool::GroupId last_group_id_;
Tarun Bansal162eabe52018-01-20 01:16:39712 bool socket_requested_ = false;
[email protected]04e5be32009-06-26 20:00:31713};
714
[email protected]231d5a32008-09-13 00:45:27715//-----------------------------------------------------------------------------
716
[email protected]79cb5c12011-09-12 13:12:04717// Helper functions for validating that AuthChallengeInfo's are correctly
718// configured for common cases.
719bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
720 if (!auth_challenge)
721 return false;
722 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43723 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04724 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19725 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04726 return true;
727}
728
729bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
730 if (!auth_challenge)
731 return false;
732 EXPECT_TRUE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43733 EXPECT_EQ("http://myproxy:70", auth_challenge->challenger.Serialize());
734 EXPECT_EQ("MyRealm1", auth_challenge->realm);
735 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
736 return true;
737}
738
739bool CheckBasicSecureProxyAuth(const AuthChallengeInfo* auth_challenge) {
740 if (!auth_challenge)
741 return false;
742 EXPECT_TRUE(auth_challenge->is_proxy);
743 EXPECT_EQ("https://myproxy:70", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04744 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19745 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04746 return true;
747}
748
749bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
750 if (!auth_challenge)
751 return false;
752 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43753 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04754 EXPECT_EQ("digestive", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19755 EXPECT_EQ(kDigestAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04756 return true;
757}
758
thakis84dff942015-07-28 20:47:38759#if defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04760bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
761 if (!auth_challenge)
762 return false;
763 EXPECT_FALSE(auth_challenge->is_proxy);
Zentaro Kavanagh1890a3d2018-01-29 19:52:55764 EXPECT_EQ("https://server", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04765 EXPECT_EQ(std::string(), auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19766 EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04767 return true;
768}
David Benjamin5cb91132018-04-06 05:54:49769
770bool CheckNTLMProxyAuth(const AuthChallengeInfo* auth_challenge) {
771 if (!auth_challenge)
772 return false;
773 EXPECT_TRUE(auth_challenge->is_proxy);
774 EXPECT_EQ("http://server", auth_challenge->challenger.Serialize());
775 EXPECT_EQ(std::string(), auth_challenge->realm);
776 EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
777 return true;
778}
thakis84dff942015-07-28 20:47:38779#endif // defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04780
[email protected]448d4ca52012-03-04 04:12:23781} // namespace
782
bncd16676a2016-07-20 16:23:01783TEST_F(HttpNetworkTransactionTest, Basic) {
danakj1fd259a02016-04-16 03:17:09784 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16785 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]231d5a32008-09-13 00:45:27786}
787
bncd16676a2016-07-20 16:23:01788TEST_F(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27789 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35790 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
791 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06792 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27793 };
Ryan Sleevib8d7ea02018-05-07 20:01:01794 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01795 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27796 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
797 EXPECT_EQ("hello world", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01798 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22799 EXPECT_EQ(reads_size, out.total_received_bytes);
ttuttle1f2d7e92015-04-28 16:17:47800 EXPECT_EQ(0u, out.connection_attempts.size());
ttuttled9dbc652015-09-29 20:00:59801
802 EXPECT_FALSE(out.remote_endpoint_after_start.address().empty());
[email protected]231d5a32008-09-13 00:45:27803}
804
805// Response with no status line.
bncd16676a2016-07-20 16:23:01806TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27807 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35808 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06809 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27810 };
Ryan Sleevib8d7ea02018-05-07 20:01:01811 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41812 EXPECT_THAT(out.rv, IsOk());
813 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
814 EXPECT_EQ("hello world", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01815 int64_t reads_size = CountReadBytes(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41816 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27817}
818
mmenkea7da6da2016-09-01 21:56:52819// Response with no status line, and a weird port. Should fail by default.
820TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPort) {
821 MockRead data_reads[] = {
822 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
823 };
824
Ryan Sleevib8d7ea02018-05-07 20:01:01825 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
mmenkea7da6da2016-09-01 21:56:52826 session_deps_.socket_factory->AddSocketDataProvider(&data);
827
828 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
829
krasinc06a72a2016-12-21 03:42:46830 HttpRequestInfo request;
bnc87dcefc2017-05-25 12:47:58831 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:19832 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenkea7da6da2016-09-01 21:56:52833
mmenkea7da6da2016-09-01 21:56:52834 request.method = "GET";
835 request.url = GURL("http://www.example.com:2000/");
Ramin Halavatib5e433e2018-02-07 07:41:10836 request.traffic_annotation =
837 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
838
mmenkea7da6da2016-09-01 21:56:52839 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20840 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52841 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_INVALID_HTTP_RESPONSE));
842}
843
Shivani Sharmafdcaefd2017-11-02 00:12:26844// Tests that request info can be destroyed after the headers phase is complete.
845TEST_F(HttpNetworkTransactionTest, SimpleGETNoReadDestroyRequestInfo) {
846 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
847 auto trans =
848 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
849
850 MockRead data_reads[] = {
851 MockRead("HTTP/1.0 200 OK\r\n"), MockRead("Connection: keep-alive\r\n"),
852 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, 0),
853 };
Ryan Sleevib8d7ea02018-05-07 20:01:01854 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
Shivani Sharmafdcaefd2017-11-02 00:12:26855 session_deps_.socket_factory->AddSocketDataProvider(&data);
856
857 TestCompletionCallback callback;
858
859 {
860 auto request = std::make_unique<HttpRequestInfo>();
861 request->method = "GET";
862 request->url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:10863 request->traffic_annotation =
864 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Shivani Sharmafdcaefd2017-11-02 00:12:26865
866 int rv =
867 trans->Start(request.get(), callback.callback(), NetLogWithSource());
868
869 EXPECT_THAT(callback.GetResult(rv), IsOk());
870 } // Let request info be destroyed.
871
872 trans.reset();
873}
874
mmenkea7da6da2016-09-01 21:56:52875// Response with no status line, and a weird port. Option to allow weird ports
876// enabled.
877TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPortAllowed) {
878 MockRead data_reads[] = {
879 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
880 };
881
Ryan Sleevib8d7ea02018-05-07 20:01:01882 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
mmenkea7da6da2016-09-01 21:56:52883 session_deps_.socket_factory->AddSocketDataProvider(&data);
884 session_deps_.http_09_on_non_default_ports_enabled = true;
885 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
886
krasinc06a72a2016-12-21 03:42:46887 HttpRequestInfo request;
bnc87dcefc2017-05-25 12:47:58888 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:19889 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenkea7da6da2016-09-01 21:56:52890
mmenkea7da6da2016-09-01 21:56:52891 request.method = "GET";
892 request.url = GURL("http://www.example.com:2000/");
Ramin Halavatib5e433e2018-02-07 07:41:10893 request.traffic_annotation =
894 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
895
mmenkea7da6da2016-09-01 21:56:52896 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20897 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52898 EXPECT_THAT(callback.GetResult(rv), IsOk());
899
900 const HttpResponseInfo* info = trans->GetResponseInfo();
901 ASSERT_TRUE(info->headers);
902 EXPECT_EQ("HTTP/0.9 200 OK", info->headers->GetStatusLine());
903
904 // Don't bother to read the body - that's verified elsewhere, important thing
905 // is that the option to allow HTTP/0.9 on non-default ports is respected.
906}
907
[email protected]231d5a32008-09-13 00:45:27908// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01909TEST_F(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27910 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35911 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06912 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27913 };
Ryan Sleevib8d7ea02018-05-07 20:01:01914 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01915 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27916 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
917 EXPECT_EQ("DATA", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01918 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22919 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27920}
921
922// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01923TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27924 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35925 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06926 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27927 };
Ryan Sleevib8d7ea02018-05-07 20:01:01928 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01929 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27930 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
931 EXPECT_EQ("DATA", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01932 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22933 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27934}
935
936// Beyond 4 bytes of slop and it should fail to find a status line.
bncd16676a2016-07-20 16:23:01937TEST_F(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27938 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35939 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06940 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27941 };
Ryan Sleevib8d7ea02018-05-07 20:01:01942 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41943 EXPECT_THAT(out.rv, IsOk());
944 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
945 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01946 int64_t reads_size = CountReadBytes(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41947 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27948}
949
950// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
bncd16676a2016-07-20 16:23:01951TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27952 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35953 MockRead("\n"),
954 MockRead("\n"),
955 MockRead("Q"),
956 MockRead("J"),
957 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06958 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27959 };
Ryan Sleevib8d7ea02018-05-07 20:01:01960 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01961 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27962 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
963 EXPECT_EQ("DATA", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01964 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22965 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27966}
967
968// Close the connection before enough bytes to have a status line.
bncd16676a2016-07-20 16:23:01969TEST_F(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:27970 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35971 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:06972 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27973 };
Ryan Sleevib8d7ea02018-05-07 20:01:01974 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41975 EXPECT_THAT(out.rv, IsOk());
976 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
977 EXPECT_EQ("HTT", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01978 int64_t reads_size = CountReadBytes(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41979 EXPECT_EQ(reads_size, out.total_received_bytes);
initial.commit586acc5fe2008-07-26 22:42:52980}
981
[email protected]f9d44aa2008-09-23 23:57:17982// Simulate a 204 response, lacking a Content-Length header, sent over a
983// persistent connection. The response should still terminate since a 204
984// cannot have a response body.
bncd16676a2016-07-20 16:23:01985TEST_F(HttpNetworkTransactionTest, StopsReading204) {
[email protected]b8015c42013-12-24 15:18:19986 char junk[] = "junk";
[email protected]f9d44aa2008-09-23 23:57:17987 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35988 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
[email protected]b8015c42013-12-24 15:18:19989 MockRead(junk), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:06990 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:17991 };
Ryan Sleevib8d7ea02018-05-07 20:01:01992 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01993 EXPECT_THAT(out.rv, IsOk());
[email protected]f9d44aa2008-09-23 23:57:17994 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
995 EXPECT_EQ("", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01996 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22997 int64_t response_size = reads_size - strlen(junk);
998 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]f9d44aa2008-09-23 23:57:17999}
1000
[email protected]0877e3d2009-10-17 22:29:571001// A simple request using chunked encoding with some extra data after.
bncd16676a2016-07-20 16:23:011002TEST_F(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]b8015c42013-12-24 15:18:191003 std::string final_chunk = "0\r\n\r\n";
1004 std::string extra_data = "HTTP/1.1 200 OK\r\n";
1005 std::string last_read = final_chunk + extra_data;
[email protected]0877e3d2009-10-17 22:29:571006 MockRead data_reads[] = {
1007 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
1008 MockRead("5\r\nHello\r\n"),
1009 MockRead("1\r\n"),
1010 MockRead(" \r\n"),
1011 MockRead("5\r\nworld\r\n"),
[email protected]b8015c42013-12-24 15:18:191012 MockRead(last_read.data()),
[email protected]8ddf8322012-02-23 18:08:061013 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:571014 };
Ryan Sleevib8d7ea02018-05-07 20:01:011015 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011016 EXPECT_THAT(out.rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:571017 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1018 EXPECT_EQ("Hello world", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:011019 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:221020 int64_t response_size = reads_size - extra_data.size();
1021 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]0877e3d2009-10-17 22:29:571022}
1023
[email protected]9fe44f52010-09-23 18:36:001024// Next tests deal with http://crbug.com/56344.
1025
bncd16676a2016-07-20 16:23:011026TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001027 MultipleContentLengthHeadersNoTransferEncoding) {
1028 MockRead data_reads[] = {
1029 MockRead("HTTP/1.1 200 OK\r\n"),
1030 MockRead("Content-Length: 10\r\n"),
1031 MockRead("Content-Length: 5\r\n\r\n"),
1032 };
Ryan Sleevib8d7ea02018-05-07 20:01:011033 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011034 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]9fe44f52010-09-23 18:36:001035}
1036
bncd16676a2016-07-20 16:23:011037TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:041038 DuplicateContentLengthHeadersNoTransferEncoding) {
1039 MockRead data_reads[] = {
1040 MockRead("HTTP/1.1 200 OK\r\n"),
1041 MockRead("Content-Length: 5\r\n"),
1042 MockRead("Content-Length: 5\r\n\r\n"),
1043 MockRead("Hello"),
1044 };
Ryan Sleevib8d7ea02018-05-07 20:01:011045 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011046 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041047 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1048 EXPECT_EQ("Hello", out.response_data);
1049}
1050
bncd16676a2016-07-20 16:23:011051TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:041052 ComplexContentLengthHeadersNoTransferEncoding) {
1053 // More than 2 dupes.
1054 {
1055 MockRead data_reads[] = {
1056 MockRead("HTTP/1.1 200 OK\r\n"),
1057 MockRead("Content-Length: 5\r\n"),
1058 MockRead("Content-Length: 5\r\n"),
1059 MockRead("Content-Length: 5\r\n\r\n"),
1060 MockRead("Hello"),
1061 };
Ryan Sleevib8d7ea02018-05-07 20:01:011062 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011063 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041064 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1065 EXPECT_EQ("Hello", out.response_data);
1066 }
1067 // HTTP/1.0
1068 {
1069 MockRead data_reads[] = {
1070 MockRead("HTTP/1.0 200 OK\r\n"),
1071 MockRead("Content-Length: 5\r\n"),
1072 MockRead("Content-Length: 5\r\n"),
1073 MockRead("Content-Length: 5\r\n\r\n"),
1074 MockRead("Hello"),
1075 };
Ryan Sleevib8d7ea02018-05-07 20:01:011076 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011077 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041078 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
1079 EXPECT_EQ("Hello", out.response_data);
1080 }
1081 // 2 dupes and one mismatched.
1082 {
1083 MockRead data_reads[] = {
1084 MockRead("HTTP/1.1 200 OK\r\n"),
1085 MockRead("Content-Length: 10\r\n"),
1086 MockRead("Content-Length: 10\r\n"),
1087 MockRead("Content-Length: 5\r\n\r\n"),
1088 };
Ryan Sleevib8d7ea02018-05-07 20:01:011089 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011090 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]44b52042010-10-29 22:48:041091 }
1092}
1093
bncd16676a2016-07-20 16:23:011094TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001095 MultipleContentLengthHeadersTransferEncoding) {
1096 MockRead data_reads[] = {
1097 MockRead("HTTP/1.1 200 OK\r\n"),
1098 MockRead("Content-Length: 666\r\n"),
1099 MockRead("Content-Length: 1337\r\n"),
1100 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
1101 MockRead("5\r\nHello\r\n"),
1102 MockRead("1\r\n"),
1103 MockRead(" \r\n"),
1104 MockRead("5\r\nworld\r\n"),
1105 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:061106 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:001107 };
Ryan Sleevib8d7ea02018-05-07 20:01:011108 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011109 EXPECT_THAT(out.rv, IsOk());
[email protected]9fe44f52010-09-23 18:36:001110 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1111 EXPECT_EQ("Hello world", out.response_data);
1112}
1113
[email protected]1628fe92011-10-04 23:04:551114// Next tests deal with http://crbug.com/98895.
1115
1116// Checks that a single Content-Disposition header results in no error.
bncd16676a2016-07-20 16:23:011117TEST_F(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:551118 MockRead data_reads[] = {
1119 MockRead("HTTP/1.1 200 OK\r\n"),
1120 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
1121 MockRead("Content-Length: 5\r\n\r\n"),
1122 MockRead("Hello"),
1123 };
Ryan Sleevib8d7ea02018-05-07 20:01:011124 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011125 EXPECT_THAT(out.rv, IsOk());
[email protected]1628fe92011-10-04 23:04:551126 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1127 EXPECT_EQ("Hello", out.response_data);
1128}
1129
[email protected]54a9c6e52012-03-21 20:10:591130// Checks that two identical Content-Disposition headers result in no error.
bncd16676a2016-07-20 16:23:011131TEST_F(HttpNetworkTransactionTest, TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551132 MockRead data_reads[] = {
1133 MockRead("HTTP/1.1 200 OK\r\n"),
1134 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1135 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1136 MockRead("Content-Length: 5\r\n\r\n"),
1137 MockRead("Hello"),
1138 };
Ryan Sleevib8d7ea02018-05-07 20:01:011139 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011140 EXPECT_THAT(out.rv, IsOk());
[email protected]54a9c6e52012-03-21 20:10:591141 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1142 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:551143}
1144
1145// Checks that two distinct Content-Disposition headers result in an error.
bncd16676a2016-07-20 16:23:011146TEST_F(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551147 MockRead data_reads[] = {
1148 MockRead("HTTP/1.1 200 OK\r\n"),
1149 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1150 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
1151 MockRead("Content-Length: 5\r\n\r\n"),
1152 MockRead("Hello"),
1153 };
Ryan Sleevib8d7ea02018-05-07 20:01:011154 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011155 EXPECT_THAT(out.rv,
1156 IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION));
[email protected]1628fe92011-10-04 23:04:551157}
1158
[email protected]54a9c6e52012-03-21 20:10:591159// Checks that two identical Location headers result in no error.
1160// Also tests Location header behavior.
bncd16676a2016-07-20 16:23:011161TEST_F(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551162 MockRead data_reads[] = {
1163 MockRead("HTTP/1.1 302 Redirect\r\n"),
1164 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:591165 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:551166 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061167 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551168 };
1169
1170 HttpRequestInfo request;
1171 request.method = "GET";
1172 request.url = GURL("http://redirect.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101173 request.traffic_annotation =
1174 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1628fe92011-10-04 23:04:551175
danakj1fd259a02016-04-16 03:17:091176 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161177 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1628fe92011-10-04 23:04:551178
Ryan Sleevib8d7ea02018-05-07 20:01:011179 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071180 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:551181
[email protected]49639fa2011-12-20 23:22:411182 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:551183
tfarina42834112016-09-22 13:38:201184 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011185 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1628fe92011-10-04 23:04:551186
robpercival214763f2016-07-01 23:27:011187 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]1628fe92011-10-04 23:04:551188
bnc691fda62016-08-12 00:43:161189 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521190 ASSERT_TRUE(response);
1191 ASSERT_TRUE(response->headers);
[email protected]1628fe92011-10-04 23:04:551192 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
1193 std::string url;
1194 EXPECT_TRUE(response->headers->IsRedirect(&url));
1195 EXPECT_EQ("http://good.com/", url);
tbansal2ecbbc72016-10-06 17:15:471196 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]1628fe92011-10-04 23:04:551197}
1198
[email protected]1628fe92011-10-04 23:04:551199// Checks that two distinct Location headers result in an error.
bncd16676a2016-07-20 16:23:011200TEST_F(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551201 MockRead data_reads[] = {
1202 MockRead("HTTP/1.1 302 Redirect\r\n"),
1203 MockRead("Location: http://good.com/\r\n"),
1204 MockRead("Location: http://evil.com/\r\n"),
1205 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061206 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551207 };
Ryan Sleevib8d7ea02018-05-07 20:01:011208 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011209 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION));
[email protected]1628fe92011-10-04 23:04:551210}
1211
[email protected]ef0faf2e72009-03-05 23:27:231212// Do a request using the HEAD method. Verify that we don't try to read the
1213// message body (since HEAD has none).
bncd16676a2016-07-20 16:23:011214TEST_F(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:421215 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:231216 request.method = "HEAD";
bncce36dca22015-04-21 22:11:231217 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:101218 request.traffic_annotation =
1219 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ef0faf2e72009-03-05 23:27:231220
danakj1fd259a02016-04-16 03:17:091221 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161222 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:091223 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:161224 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:091225 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
1226 base::Unretained(&headers_handler)));
[email protected]cb9bf6ca2011-01-28 13:15:271227
[email protected]ef0faf2e72009-03-05 23:27:231228 MockWrite data_writes1[] = {
csharrisonf473dd192015-08-18 13:54:131229 MockWrite("HEAD / HTTP/1.1\r\n"
1230 "Host: www.example.org\r\n"
1231 "Connection: keep-alive\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231232 };
1233 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:231234 MockRead("HTTP/1.1 404 Not Found\r\n"), MockRead("Server: Blah\r\n"),
1235 MockRead("Content-Length: 1234\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231236
mmenked39192ee2015-12-09 00:57:231237 // No response body because the test stops reading here.
1238 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]ef0faf2e72009-03-05 23:27:231239 };
1240
Ryan Sleevib8d7ea02018-05-07 20:01:011241 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:071242 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:231243
[email protected]49639fa2011-12-20 23:22:411244 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:231245
tfarina42834112016-09-22 13:38:201246 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011247 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ef0faf2e72009-03-05 23:27:231248
1249 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:011250 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231251
bnc691fda62016-08-12 00:43:161252 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521253 ASSERT_TRUE(response);
[email protected]ef0faf2e72009-03-05 23:27:231254
1255 // Check that the headers got parsed.
wezca1070932016-05-26 20:30:521256 EXPECT_TRUE(response->headers);
[email protected]ef0faf2e72009-03-05 23:27:231257 EXPECT_EQ(1234, response->headers->GetContentLength());
1258 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471259 EXPECT_TRUE(response->proxy_server.is_direct());
ryansturm49a8cb12016-06-15 16:51:091260 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
1261 EXPECT_FALSE(headers_handler.observed_before_headers_sent_with_proxy());
[email protected]ef0faf2e72009-03-05 23:27:231262
1263 std::string server_header;
olli.raulaee489a52016-01-25 08:37:101264 size_t iter = 0;
[email protected]ef0faf2e72009-03-05 23:27:231265 bool has_server_header = response->headers->EnumerateHeader(
1266 &iter, "Server", &server_header);
1267 EXPECT_TRUE(has_server_header);
1268 EXPECT_EQ("Blah", server_header);
1269
1270 // Reading should give EOF right away, since there is no message body
1271 // (despite non-zero content-length).
1272 std::string response_data;
bnc691fda62016-08-12 00:43:161273 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011274 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231275 EXPECT_EQ("", response_data);
1276}
1277
bncd16676a2016-07-20 16:23:011278TEST_F(HttpNetworkTransactionTest, ReuseConnection) {
danakj1fd259a02016-04-16 03:17:091279 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:521280
1281 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351282 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1283 MockRead("hello"),
1284 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1285 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061286 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521287 };
Ryan Sleevib8d7ea02018-05-07 20:01:011288 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071289 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521290
[email protected]0b0bf032010-09-21 18:08:501291 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521292 "hello", "world"
1293 };
1294
1295 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:421296 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521297 request.method = "GET";
bncce36dca22015-04-21 22:11:231298 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:101299 request.traffic_annotation =
1300 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:521301
bnc691fda62016-08-12 00:43:161302 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271303
[email protected]49639fa2011-12-20 23:22:411304 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521305
tfarina42834112016-09-22 13:38:201306 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011307 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521308
1309 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011310 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521311
bnc691fda62016-08-12 00:43:161312 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521313 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521314
wezca1070932016-05-26 20:30:521315 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251316 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471317 EXPECT_TRUE(response->proxy_server.is_direct());
initial.commit586acc5fe2008-07-26 22:42:521318
1319 std::string response_data;
bnc691fda62016-08-12 00:43:161320 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011321 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251322 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521323 }
1324}
1325
bncd16676a2016-07-20 16:23:011326TEST_F(HttpNetworkTransactionTest, Ignores100) {
danakj1fd259a02016-04-16 03:17:091327 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:221328 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:191329 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:221330 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:271331
[email protected]1c773ea12009-04-28 19:58:421332 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521333 request.method = "POST";
1334 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271335 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:101336 request.traffic_annotation =
1337 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:521338
shivanishab9a143952016-09-19 17:23:411339 // Check the upload progress returned before initialization is correct.
1340 UploadProgress progress = request.upload_data_stream->GetUploadProgress();
1341 EXPECT_EQ(0u, progress.size());
1342 EXPECT_EQ(0u, progress.position());
1343
danakj1fd259a02016-04-16 03:17:091344 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161345 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271346
initial.commit586acc5fe2008-07-26 22:42:521347 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351348 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1349 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1350 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061351 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521352 };
Ryan Sleevib8d7ea02018-05-07 20:01:011353 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071354 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521355
[email protected]49639fa2011-12-20 23:22:411356 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521357
tfarina42834112016-09-22 13:38:201358 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011359 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521360
1361 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011362 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521363
bnc691fda62016-08-12 00:43:161364 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521365 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521366
wezca1070932016-05-26 20:30:521367 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251368 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521369
1370 std::string response_data;
bnc691fda62016-08-12 00:43:161371 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011372 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251373 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521374}
1375
[email protected]3a2d3662009-03-27 03:49:141376// This test is almost the same as Ignores100 above, but the response contains
1377// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571378// HTTP/1.1 and the two status headers are read in one read.
bncd16676a2016-07-20 16:23:011379TEST_F(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421380 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141381 request.method = "GET";
1382 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101383 request.traffic_annotation =
1384 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3a2d3662009-03-27 03:49:141385
danakj1fd259a02016-04-16 03:17:091386 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161387 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271388
[email protected]3a2d3662009-03-27 03:49:141389 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571390 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1391 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141392 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061393 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141394 };
Ryan Sleevib8d7ea02018-05-07 20:01:011395 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071396 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141397
[email protected]49639fa2011-12-20 23:22:411398 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141399
tfarina42834112016-09-22 13:38:201400 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011401 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3a2d3662009-03-27 03:49:141402
1403 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011404 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141405
bnc691fda62016-08-12 00:43:161406 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521407 ASSERT_TRUE(response);
[email protected]3a2d3662009-03-27 03:49:141408
wezca1070932016-05-26 20:30:521409 EXPECT_TRUE(response->headers);
[email protected]3a2d3662009-03-27 03:49:141410 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1411
1412 std::string response_data;
bnc691fda62016-08-12 00:43:161413 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011414 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141415 EXPECT_EQ("hello world", response_data);
1416}
1417
Andrew Comminos517a92c2019-01-14 17:49:561418TEST_F(HttpNetworkTransactionTest, LoadTimingMeasuresTimeToFirstByteForHttp) {
1419 static const base::TimeDelta kDelayAfterFirstByte =
Andrew Comminos1f2ff1cc2018-12-14 05:22:381420 base::TimeDelta::FromMilliseconds(10);
1421
1422 HttpRequestInfo request;
1423 request.method = "GET";
1424 request.url = GURL("http://www.foo.com/");
1425 request.traffic_annotation =
1426 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1427
1428 std::vector<MockWrite> data_writes = {
1429 MockWrite(ASYNC, 0,
1430 "GET / HTTP/1.1\r\n"
1431 "Host: www.foo.com\r\n"
1432 "Connection: keep-alive\r\n\r\n"),
1433 };
1434
1435 std::vector<MockRead> data_reads = {
1436 // Write one byte of the status line, followed by a pause.
1437 MockRead(ASYNC, 1, "H"),
1438 MockRead(ASYNC, ERR_IO_PENDING, 2),
1439 MockRead(ASYNC, 3, "TTP/1.1 200 OK\r\n\r\n"),
1440 MockRead(ASYNC, 4, "hello world"),
1441 MockRead(SYNCHRONOUS, OK, 5),
1442 };
1443
1444 SequencedSocketData data(data_reads, data_writes);
1445 session_deps_.socket_factory->AddSocketDataProvider(&data);
1446
1447 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1448
1449 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1450
1451 TestCompletionCallback callback;
1452
1453 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1454 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1455
1456 data.RunUntilPaused();
1457 ASSERT_TRUE(data.IsPaused());
Andrew Comminos517a92c2019-01-14 17:49:561458 FastForwardBy(kDelayAfterFirstByte);
Andrew Comminos1f2ff1cc2018-12-14 05:22:381459 data.Resume();
1460
1461 rv = callback.WaitForResult();
1462 EXPECT_THAT(rv, IsOk());
1463
1464 const HttpResponseInfo* response = trans.GetResponseInfo();
1465 ASSERT_TRUE(response);
1466
1467 EXPECT_TRUE(response->headers);
1468 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1469
1470 LoadTimingInfo load_timing_info;
1471 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
1472 EXPECT_FALSE(load_timing_info.receive_headers_start.is_null());
1473 EXPECT_FALSE(load_timing_info.connect_timing.connect_end.is_null());
Andrew Comminos517a92c2019-01-14 17:49:561474 // Ensure we didn't include the delay in the TTFB time.
1475 EXPECT_EQ(load_timing_info.receive_headers_start,
1476 load_timing_info.connect_timing.connect_end);
1477 // Ensure that the mock clock advanced at all.
1478 EXPECT_EQ(base::TimeTicks::Now() - load_timing_info.receive_headers_start,
1479 kDelayAfterFirstByte);
Andrew Comminos1f2ff1cc2018-12-14 05:22:381480
1481 std::string response_data;
1482 rv = ReadTransaction(&trans, &response_data);
1483 EXPECT_THAT(rv, IsOk());
1484 EXPECT_EQ("hello world", response_data);
1485}
1486
1487// Tests that the time-to-first-byte reported in a transaction's load timing
1488// info uses the first response, even if 1XX/informational.
1489void HttpNetworkTransactionTest::Check100ResponseTiming(bool use_spdy) {
Andrew Comminos517a92c2019-01-14 17:49:561490 static const base::TimeDelta kDelayAfter100Response =
Andrew Comminos1f2ff1cc2018-12-14 05:22:381491 base::TimeDelta::FromMilliseconds(10);
1492
1493 HttpRequestInfo request;
1494 request.method = "GET";
1495 request.url = GURL("https://www.foo.com/");
1496 request.traffic_annotation =
1497 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1498
1499 SSLSocketDataProvider ssl(ASYNC, OK);
1500 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
1501
1502 std::vector<MockWrite> data_writes;
1503 std::vector<MockRead> data_reads;
1504
1505 spdy::SpdySerializedFrame spdy_req(
1506 spdy_util_.ConstructSpdyGet(request.url.spec().c_str(), 1, LOWEST));
1507
1508 spdy::SpdyHeaderBlock spdy_resp1_headers;
1509 spdy_resp1_headers[spdy::kHttp2StatusHeader] = "100";
1510 spdy::SpdySerializedFrame spdy_resp1(
1511 spdy_util_.ConstructSpdyReply(1, spdy_resp1_headers.Clone()));
1512 spdy::SpdySerializedFrame spdy_resp2(
1513 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
1514 spdy::SpdySerializedFrame spdy_data(
1515 spdy_util_.ConstructSpdyDataFrame(1, "hello world", true));
1516
1517 if (use_spdy) {
1518 ssl.next_proto = kProtoHTTP2;
1519
1520 data_writes = {CreateMockWrite(spdy_req, 0)};
1521
1522 data_reads = {
1523 CreateMockRead(spdy_resp1, 1), MockRead(ASYNC, ERR_IO_PENDING, 2),
1524 CreateMockRead(spdy_resp2, 3), CreateMockRead(spdy_data, 4),
1525 MockRead(SYNCHRONOUS, OK, 5),
1526 };
1527 } else {
1528 data_writes = {
1529 MockWrite(ASYNC, 0,
1530 "GET / HTTP/1.1\r\n"
1531 "Host: www.foo.com\r\n"
1532 "Connection: keep-alive\r\n\r\n"),
1533 };
1534
1535 data_reads = {
1536 MockRead(ASYNC, 1, "HTTP/1.1 100 Continue\r\n\r\n"),
1537 MockRead(ASYNC, ERR_IO_PENDING, 2),
1538
1539 MockRead(ASYNC, 3, "HTTP/1.1 200 OK\r\n\r\n"),
1540 MockRead(ASYNC, 4, "hello world"),
1541 MockRead(SYNCHRONOUS, OK, 5),
1542 };
1543 }
1544
1545 SequencedSocketData data(data_reads, data_writes);
1546 session_deps_.socket_factory->AddSocketDataProvider(&data);
1547
1548 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1549
1550 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1551
1552 TestCompletionCallback callback;
1553
1554 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1555 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1556
1557 data.RunUntilPaused();
1558 // We should now have parsed the 100 response and hit ERR_IO_PENDING. Insert
1559 // the delay before parsing the 200 response.
1560 ASSERT_TRUE(data.IsPaused());
Andrew Comminos517a92c2019-01-14 17:49:561561 FastForwardBy(kDelayAfter100Response);
Andrew Comminos1f2ff1cc2018-12-14 05:22:381562 data.Resume();
1563
1564 rv = callback.WaitForResult();
1565 EXPECT_THAT(rv, IsOk());
1566
1567 const HttpResponseInfo* response = trans.GetResponseInfo();
1568 ASSERT_TRUE(response);
1569
1570 LoadTimingInfo load_timing_info;
1571 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
1572 EXPECT_FALSE(load_timing_info.receive_headers_start.is_null());
1573 EXPECT_FALSE(load_timing_info.connect_timing.connect_end.is_null());
Andrew Comminos517a92c2019-01-14 17:49:561574 // Ensure we didn't include the delay in the TTFB time.
1575 EXPECT_EQ(load_timing_info.receive_headers_start,
1576 load_timing_info.connect_timing.connect_end);
1577 // Ensure that the mock clock advanced at all.
1578 EXPECT_EQ(base::TimeTicks::Now() - load_timing_info.receive_headers_start,
1579 kDelayAfter100Response);
Andrew Comminos1f2ff1cc2018-12-14 05:22:381580
1581 std::string response_data;
1582 rv = ReadTransaction(&trans, &response_data);
1583 EXPECT_THAT(rv, IsOk());
1584 EXPECT_EQ("hello world", response_data);
1585}
1586
Andrew Comminos517a92c2019-01-14 17:49:561587TEST_F(HttpNetworkTransactionTest, MeasuresTimeToFirst100ResponseForHttp) {
Andrew Comminos1f2ff1cc2018-12-14 05:22:381588 Check100ResponseTiming(false /* use_spdy */);
1589}
1590
Andrew Comminos517a92c2019-01-14 17:49:561591TEST_F(HttpNetworkTransactionTest, MeasuresTimeToFirst100ResponseForSpdy) {
Andrew Comminos1f2ff1cc2018-12-14 05:22:381592 Check100ResponseTiming(true /* use_spdy */);
1593}
1594
bncd16676a2016-07-20 16:23:011595TEST_F(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
zmo9528c9f42015-08-04 22:12:081596 HttpRequestInfo request;
1597 request.method = "POST";
1598 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101599 request.traffic_annotation =
1600 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
zmo9528c9f42015-08-04 22:12:081601
danakj1fd259a02016-04-16 03:17:091602 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161603 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zmo9528c9f42015-08-04 22:12:081604
1605 MockRead data_reads[] = {
1606 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1607 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381608 };
Ryan Sleevib8d7ea02018-05-07 20:01:011609 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
zmo9528c9f42015-08-04 22:12:081610 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381611
zmo9528c9f42015-08-04 22:12:081612 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381613
tfarina42834112016-09-22 13:38:201614 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011615 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381616
zmo9528c9f42015-08-04 22:12:081617 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011618 EXPECT_THAT(rv, IsOk());
[email protected]ee9410e72010-01-07 01:42:381619
zmo9528c9f42015-08-04 22:12:081620 std::string response_data;
bnc691fda62016-08-12 00:43:161621 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011622 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:081623 EXPECT_EQ("", response_data);
[email protected]ee9410e72010-01-07 01:42:381624}
1625
bncd16676a2016-07-20 16:23:011626TEST_F(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381627 HttpRequestInfo request;
1628 request.method = "POST";
1629 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101630 request.traffic_annotation =
1631 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ee9410e72010-01-07 01:42:381632
danakj1fd259a02016-04-16 03:17:091633 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161634 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271635
[email protected]ee9410e72010-01-07 01:42:381636 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061637 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381638 };
Ryan Sleevib8d7ea02018-05-07 20:01:011639 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071640 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381641
[email protected]49639fa2011-12-20 23:22:411642 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381643
tfarina42834112016-09-22 13:38:201644 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011645 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381646
1647 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011648 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]ee9410e72010-01-07 01:42:381649}
1650
[email protected]23e482282013-06-14 16:08:021651void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511652 const MockWrite* write_failure,
1653 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421654 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521655 request.method = "GET";
1656 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101657 request.traffic_annotation =
1658 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:521659
vishal.b62985ca92015-04-17 08:45:511660 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071661 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091662 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271663
[email protected]202965992011-12-07 23:04:511664 // Written data for successfully sending both requests.
1665 MockWrite data1_writes[] = {
1666 MockWrite("GET / HTTP/1.1\r\n"
1667 "Host: www.foo.com\r\n"
1668 "Connection: keep-alive\r\n\r\n"),
1669 MockWrite("GET / HTTP/1.1\r\n"
1670 "Host: www.foo.com\r\n"
1671 "Connection: keep-alive\r\n\r\n")
1672 };
1673
1674 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521675 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351676 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1677 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061678 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521679 };
[email protected]202965992011-12-07 23:04:511680
1681 if (write_failure) {
[email protected]a34f61ee2014-03-18 20:59:491682 ASSERT_FALSE(read_failure);
[email protected]202965992011-12-07 23:04:511683 data1_writes[1] = *write_failure;
1684 } else {
1685 ASSERT_TRUE(read_failure);
1686 data1_reads[2] = *read_failure;
1687 }
1688
Ryan Sleevib8d7ea02018-05-07 20:01:011689 StaticSocketDataProvider data1(data1_reads, data1_writes);
[email protected]bb88e1d32013-05-03 23:11:071690 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521691
1692 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351693 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1694 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061695 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521696 };
Ryan Sleevib8d7ea02018-05-07 20:01:011697 StaticSocketDataProvider data2(data2_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071698 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521699
thestig9d3bb0c2015-01-24 00:49:511700 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521701 "hello", "world"
1702 };
1703
mikecironef22f9812016-10-04 03:40:191704 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521705 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411706 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521707
bnc691fda62016-08-12 00:43:161708 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
initial.commit586acc5fe2008-07-26 22:42:521709
tfarina42834112016-09-22 13:38:201710 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011711 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521712
1713 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011714 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521715
[email protected]58e32bb2013-01-21 18:23:251716 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161717 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:251718 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1719 if (i == 0) {
1720 first_socket_log_id = load_timing_info.socket_log_id;
1721 } else {
1722 // The second request should be using a new socket.
1723 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1724 }
1725
bnc691fda62016-08-12 00:43:161726 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521727 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521728
wezca1070932016-05-26 20:30:521729 EXPECT_TRUE(response->headers);
tbansal2ecbbc72016-10-06 17:15:471730 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]3d2a59b2008-09-26 19:44:251731 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521732
1733 std::string response_data;
bnc691fda62016-08-12 00:43:161734 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011735 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251736 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521737 }
1738}
[email protected]3d2a59b2008-09-26 19:44:251739
[email protected]a34f61ee2014-03-18 20:59:491740void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1741 const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:101742 const MockRead* read_failure,
1743 bool use_spdy) {
[email protected]a34f61ee2014-03-18 20:59:491744 HttpRequestInfo request;
1745 request.method = "GET";
[email protected]09356c652014-03-25 15:36:101746 request.url = GURL("https://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101747 request.traffic_annotation =
1748 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]a34f61ee2014-03-18 20:59:491749
vishal.b62985ca92015-04-17 08:45:511750 TestNetLog net_log;
[email protected]a34f61ee2014-03-18 20:59:491751 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091752 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a34f61ee2014-03-18 20:59:491753
[email protected]09356c652014-03-25 15:36:101754 SSLSocketDataProvider ssl1(ASYNC, OK);
1755 SSLSocketDataProvider ssl2(ASYNC, OK);
1756 if (use_spdy) {
bnc3cf2a592016-08-11 14:48:361757 ssl1.next_proto = kProtoHTTP2;
1758 ssl2.next_proto = kProtoHTTP2;
[email protected]09356c652014-03-25 15:36:101759 }
1760 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1761 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]a34f61ee2014-03-18 20:59:491762
[email protected]09356c652014-03-25 15:36:101763 // SPDY versions of the request and response.
Ryan Hamilton0239aac2018-05-19 00:03:131764 spdy::SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
bnc38dcd392016-02-09 23:19:491765 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
Ryan Hamilton0239aac2018-05-19 00:03:131766 spdy::SpdySerializedFrame spdy_response(
Raul Tambre94493c652019-03-11 17:18:351767 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:131768 spdy::SpdySerializedFrame spdy_data(
Bence Békyd74f4382018-02-20 18:26:191769 spdy_util_.ConstructSpdyDataFrame(1, "hello", true));
[email protected]a34f61ee2014-03-18 20:59:491770
[email protected]09356c652014-03-25 15:36:101771 // HTTP/1.1 versions of the request and response.
1772 const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1773 "Host: www.foo.com\r\n"
1774 "Connection: keep-alive\r\n\r\n";
1775 const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1776 const char kHttpData[] = "hello";
1777
1778 std::vector<MockRead> data1_reads;
1779 std::vector<MockWrite> data1_writes;
[email protected]a34f61ee2014-03-18 20:59:491780 if (write_failure) {
1781 ASSERT_FALSE(read_failure);
[email protected]09356c652014-03-25 15:36:101782 data1_writes.push_back(*write_failure);
1783 data1_reads.push_back(MockRead(ASYNC, OK));
[email protected]a34f61ee2014-03-18 20:59:491784 } else {
1785 ASSERT_TRUE(read_failure);
[email protected]09356c652014-03-25 15:36:101786 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411787 data1_writes.push_back(CreateMockWrite(spdy_request));
[email protected]09356c652014-03-25 15:36:101788 } else {
1789 data1_writes.push_back(MockWrite(kHttpRequest));
1790 }
1791 data1_reads.push_back(*read_failure);
[email protected]a34f61ee2014-03-18 20:59:491792 }
1793
Ryan Sleevib8d7ea02018-05-07 20:01:011794 StaticSocketDataProvider data1(data1_reads, data1_writes);
[email protected]a34f61ee2014-03-18 20:59:491795 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1796
[email protected]09356c652014-03-25 15:36:101797 std::vector<MockRead> data2_reads;
1798 std::vector<MockWrite> data2_writes;
1799
1800 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411801 data2_writes.push_back(CreateMockWrite(spdy_request, 0, ASYNC));
[email protected]09356c652014-03-25 15:36:101802
bncdf80d44fd2016-07-15 20:27:411803 data2_reads.push_back(CreateMockRead(spdy_response, 1, ASYNC));
1804 data2_reads.push_back(CreateMockRead(spdy_data, 2, ASYNC));
[email protected]09356c652014-03-25 15:36:101805 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1806 } else {
1807 data2_writes.push_back(
1808 MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1809
1810 data2_reads.push_back(
1811 MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1812 data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1813 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1814 }
Ryan Sleevib8d7ea02018-05-07 20:01:011815 SequencedSocketData data2(data2_reads, data2_writes);
[email protected]a34f61ee2014-03-18 20:59:491816 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1817
1818 // Preconnect a socket.
nharper8cdb0fb2016-04-22 21:34:591819 session->http_stream_factory()->PreconnectStreams(1, request);
[email protected]a34f61ee2014-03-18 20:59:491820 // Wait for the preconnect to complete.
1821 // TODO(davidben): Some way to wait for an idle socket count might be handy.
1822 base::RunLoop().RunUntilIdle();
Matt Menke9d5e2c92019-02-05 01:42:231823 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]a34f61ee2014-03-18 20:59:491824
1825 // Make the request.
1826 TestCompletionCallback callback;
1827
bnc691fda62016-08-12 00:43:161828 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a34f61ee2014-03-18 20:59:491829
tfarina42834112016-09-22 13:38:201830 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011831 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a34f61ee2014-03-18 20:59:491832
1833 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011834 EXPECT_THAT(rv, IsOk());
[email protected]a34f61ee2014-03-18 20:59:491835
1836 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161837 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]09356c652014-03-25 15:36:101838 TestLoadTimingNotReused(
1839 load_timing_info,
1840 CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]a34f61ee2014-03-18 20:59:491841
bnc691fda62016-08-12 00:43:161842 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521843 ASSERT_TRUE(response);
[email protected]a34f61ee2014-03-18 20:59:491844
wezca1070932016-05-26 20:30:521845 EXPECT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:021846 if (response->was_fetched_via_spdy) {
1847 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
1848 } else {
1849 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1850 }
[email protected]a34f61ee2014-03-18 20:59:491851
1852 std::string response_data;
bnc691fda62016-08-12 00:43:161853 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011854 EXPECT_THAT(rv, IsOk());
[email protected]09356c652014-03-25 15:36:101855 EXPECT_EQ(kHttpData, response_data);
[email protected]a34f61ee2014-03-18 20:59:491856}
1857
Biljith Jayan45a41722017-08-16 18:43:141858// Test that we do not retry indefinitely when a server sends an error like
1859// ERR_SPDY_PING_FAILED, ERR_SPDY_SERVER_REFUSED_STREAM,
1860// ERR_QUIC_HANDSHAKE_FAILED or ERR_QUIC_PROTOCOL_ERROR.
1861TEST_F(HttpNetworkTransactionTest, FiniteRetriesOnIOError) {
1862 HttpRequestInfo request;
1863 request.method = "GET";
1864 request.url = GURL("https://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101865 request.traffic_annotation =
1866 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Biljith Jayan45a41722017-08-16 18:43:141867
1868 // Check whether we give up after the third try.
1869
1870 // Construct an HTTP2 request and a "Go away" response.
Ryan Hamilton0239aac2018-05-19 00:03:131871 spdy::SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
Biljith Jayan45a41722017-08-16 18:43:141872 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
Ryan Hamilton0239aac2018-05-19 00:03:131873 spdy::SpdySerializedFrame spdy_response_go_away(
1874 spdy_util_.ConstructSpdyGoAway(0));
Ryan Sleevib8d7ea02018-05-07 20:01:011875 MockRead data_read1[] = {CreateMockRead(spdy_response_go_away)};
1876 MockWrite data_write[] = {CreateMockWrite(spdy_request, 0)};
Biljith Jayan45a41722017-08-16 18:43:141877
1878 // Three go away responses.
Ryan Sleevib8d7ea02018-05-07 20:01:011879 StaticSocketDataProvider data1(data_read1, data_write);
1880 StaticSocketDataProvider data2(data_read1, data_write);
1881 StaticSocketDataProvider data3(data_read1, data_write);
Biljith Jayan45a41722017-08-16 18:43:141882
1883 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1884 AddSSLSocketData();
1885 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1886 AddSSLSocketData();
1887 session_deps_.socket_factory->AddSocketDataProvider(&data3);
1888 AddSSLSocketData();
1889
1890 TestCompletionCallback callback;
1891 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1892 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1893
1894 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1895 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1896
1897 rv = callback.WaitForResult();
1898 EXPECT_THAT(rv, IsError(ERR_SPDY_SERVER_REFUSED_STREAM));
1899}
1900
1901TEST_F(HttpNetworkTransactionTest, RetryTwiceOnIOError) {
1902 HttpRequestInfo request;
1903 request.method = "GET";
1904 request.url = GURL("https://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101905 request.traffic_annotation =
1906 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Biljith Jayan45a41722017-08-16 18:43:141907
1908 // Check whether we try atleast thrice before giving up.
1909
1910 // Construct an HTTP2 request and a "Go away" response.
Ryan Hamilton0239aac2018-05-19 00:03:131911 spdy::SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
Biljith Jayan45a41722017-08-16 18:43:141912 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
Ryan Hamilton0239aac2018-05-19 00:03:131913 spdy::SpdySerializedFrame spdy_response_go_away(
1914 spdy_util_.ConstructSpdyGoAway(0));
Ryan Sleevib8d7ea02018-05-07 20:01:011915 MockRead data_read1[] = {CreateMockRead(spdy_response_go_away)};
1916 MockWrite data_write[] = {CreateMockWrite(spdy_request, 0)};
Biljith Jayan45a41722017-08-16 18:43:141917
1918 // Construct a non error HTTP2 response.
Ryan Hamilton0239aac2018-05-19 00:03:131919 spdy::SpdySerializedFrame spdy_response_no_error(
Biljith Jayan45a41722017-08-16 18:43:141920 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:131921 spdy::SpdySerializedFrame spdy_data(
1922 spdy_util_.ConstructSpdyDataFrame(1, true));
Biljith Jayan45a41722017-08-16 18:43:141923 MockRead data_read2[] = {CreateMockRead(spdy_response_no_error, 1),
1924 CreateMockRead(spdy_data, 2)};
1925
1926 // Two error responses.
Ryan Sleevib8d7ea02018-05-07 20:01:011927 StaticSocketDataProvider data1(data_read1, data_write);
1928 StaticSocketDataProvider data2(data_read1, data_write);
Biljith Jayan45a41722017-08-16 18:43:141929 // Followed by a success response.
Ryan Sleevib8d7ea02018-05-07 20:01:011930 SequencedSocketData data3(data_read2, data_write);
Biljith Jayan45a41722017-08-16 18:43:141931
1932 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1933 AddSSLSocketData();
1934 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1935 AddSSLSocketData();
1936 session_deps_.socket_factory->AddSocketDataProvider(&data3);
1937 AddSSLSocketData();
1938
1939 TestCompletionCallback callback;
1940 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1941 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1942
1943 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1944 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1945
1946 rv = callback.WaitForResult();
1947 EXPECT_THAT(rv, IsOk());
1948}
1949
bncd16676a2016-07-20 16:23:011950TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061951 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
Raul Tambre94493c652019-03-11 17:18:351952 KeepAliveConnectionResendRequestTest(&write_failure, nullptr);
[email protected]202965992011-12-07 23:04:511953}
1954
bncd16676a2016-07-20 16:23:011955TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061956 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
Raul Tambre94493c652019-03-11 17:18:351957 KeepAliveConnectionResendRequestTest(nullptr, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251958}
1959
bncd16676a2016-07-20 16:23:011960TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061961 MockRead read_failure(SYNCHRONOUS, OK); // EOF
Raul Tambre94493c652019-03-11 17:18:351962 KeepAliveConnectionResendRequestTest(nullptr, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251963}
1964
[email protected]d58ceea82014-06-04 10:55:541965// Make sure that on a 408 response (Request Timeout), the request is retried,
1966// if the socket was a reused keep alive socket.
bncd16676a2016-07-20 16:23:011967TEST_F(HttpNetworkTransactionTest, KeepAlive408) {
[email protected]d58ceea82014-06-04 10:55:541968 MockRead read_failure(SYNCHRONOUS,
1969 "HTTP/1.1 408 Request Timeout\r\n"
1970 "Connection: Keep-Alive\r\n"
1971 "Content-Length: 6\r\n\r\n"
1972 "Pickle");
Raul Tambre94493c652019-03-11 17:18:351973 KeepAliveConnectionResendRequestTest(nullptr, &read_failure);
[email protected]d58ceea82014-06-04 10:55:541974}
1975
bncd16676a2016-07-20 16:23:011976TEST_F(HttpNetworkTransactionTest, PreconnectErrorNotConnectedOnWrite) {
[email protected]a34f61ee2014-03-18 20:59:491977 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
Raul Tambre94493c652019-03-11 17:18:351978 PreconnectErrorResendRequestTest(&write_failure, nullptr, false);
[email protected]a34f61ee2014-03-18 20:59:491979}
1980
bncd16676a2016-07-20 16:23:011981TEST_F(HttpNetworkTransactionTest, PreconnectErrorReset) {
[email protected]a34f61ee2014-03-18 20:59:491982 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
Raul Tambre94493c652019-03-11 17:18:351983 PreconnectErrorResendRequestTest(nullptr, &read_failure, false);
[email protected]a34f61ee2014-03-18 20:59:491984}
1985
bncd16676a2016-07-20 16:23:011986TEST_F(HttpNetworkTransactionTest, PreconnectErrorEOF) {
[email protected]a34f61ee2014-03-18 20:59:491987 MockRead read_failure(SYNCHRONOUS, OK); // EOF
Raul Tambre94493c652019-03-11 17:18:351988 PreconnectErrorResendRequestTest(nullptr, &read_failure, false);
[email protected]09356c652014-03-25 15:36:101989}
1990
bncd16676a2016-07-20 16:23:011991TEST_F(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:101992 MockRead read_failure(ASYNC, OK); // EOF
Raul Tambre94493c652019-03-11 17:18:351993 PreconnectErrorResendRequestTest(nullptr, &read_failure, false);
[email protected]09356c652014-03-25 15:36:101994}
1995
[email protected]d58ceea82014-06-04 10:55:541996// Make sure that on a 408 response (Request Timeout), the request is retried,
1997// if the socket was a preconnected (UNUSED_IDLE) socket.
bncd16676a2016-07-20 16:23:011998TEST_F(HttpNetworkTransactionTest, RetryOnIdle408) {
[email protected]d58ceea82014-06-04 10:55:541999 MockRead read_failure(SYNCHRONOUS,
2000 "HTTP/1.1 408 Request Timeout\r\n"
2001 "Connection: Keep-Alive\r\n"
2002 "Content-Length: 6\r\n\r\n"
2003 "Pickle");
Raul Tambre94493c652019-03-11 17:18:352004 KeepAliveConnectionResendRequestTest(nullptr, &read_failure);
2005 PreconnectErrorResendRequestTest(nullptr, &read_failure, false);
[email protected]d58ceea82014-06-04 10:55:542006}
2007
bncd16676a2016-07-20 16:23:012008TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorNotConnectedOnWrite) {
[email protected]09356c652014-03-25 15:36:102009 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
Raul Tambre94493c652019-03-11 17:18:352010 PreconnectErrorResendRequestTest(&write_failure, nullptr, true);
[email protected]09356c652014-03-25 15:36:102011}
2012
bncd16676a2016-07-20 16:23:012013TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
[email protected]09356c652014-03-25 15:36:102014 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
Raul Tambre94493c652019-03-11 17:18:352015 PreconnectErrorResendRequestTest(nullptr, &read_failure, true);
[email protected]09356c652014-03-25 15:36:102016}
2017
bncd16676a2016-07-20 16:23:012018TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
[email protected]09356c652014-03-25 15:36:102019 MockRead read_failure(SYNCHRONOUS, OK); // EOF
Raul Tambre94493c652019-03-11 17:18:352020 PreconnectErrorResendRequestTest(nullptr, &read_failure, true);
[email protected]09356c652014-03-25 15:36:102021}
2022
bncd16676a2016-07-20 16:23:012023TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:102024 MockRead read_failure(ASYNC, OK); // EOF
Raul Tambre94493c652019-03-11 17:18:352025 PreconnectErrorResendRequestTest(nullptr, &read_failure, true);
[email protected]a34f61ee2014-03-18 20:59:492026}
2027
bncd16676a2016-07-20 16:23:012028TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:422029 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:252030 request.method = "GET";
bncce36dca22015-04-21 22:11:232031 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102032 request.traffic_annotation =
2033 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3d2a59b2008-09-26 19:44:252034
danakj1fd259a02016-04-16 03:17:092035 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162036 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272037
[email protected]3d2a59b2008-09-26 19:44:252038 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:062039 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:352040 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
2041 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:062042 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:252043 };
Ryan Sleevib8d7ea02018-05-07 20:01:012044 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:072045 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:252046
[email protected]49639fa2011-12-20 23:22:412047 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:252048
tfarina42834112016-09-22 13:38:202049 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012050 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3d2a59b2008-09-26 19:44:252051
2052 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:012053 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:592054
2055 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:162056 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592057 EXPECT_LT(0u, endpoint.address().size());
[email protected]3d2a59b2008-09-26 19:44:252058}
2059
2060// What do various browsers do when the server closes a non-keepalive
2061// connection without sending any response header or body?
2062//
2063// IE7: error page
2064// Safari 3.1.2 (Windows): error page
2065// Firefox 3.0.1: blank page
2066// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:422067// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
2068// Us: error page (EMPTY_RESPONSE)
bncd16676a2016-07-20 16:23:012069TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:252070 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:062071 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:352072 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
2073 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:062074 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:252075 };
Ryan Sleevib8d7ea02018-05-07 20:01:012076 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:012077 EXPECT_THAT(out.rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]3d2a59b2008-09-26 19:44:252078}
[email protected]1826a402014-01-08 15:40:482079
[email protected]7a5378b2012-11-04 03:25:172080// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
2081// tests. There was a bug causing HttpNetworkTransaction to hang in the
2082// destructor in such situations.
2083// See http://crbug.com/154712 and http://crbug.com/156609.
bncd16676a2016-07-20 16:23:012084TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:172085 HttpRequestInfo request;
2086 request.method = "GET";
bncce36dca22015-04-21 22:11:232087 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102088 request.traffic_annotation =
2089 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7a5378b2012-11-04 03:25:172090
danakj1fd259a02016-04-16 03:17:092091 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:582092 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:192093 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:172094
2095 MockRead data_reads[] = {
2096 MockRead("HTTP/1.0 200 OK\r\n"),
2097 MockRead("Connection: keep-alive\r\n"),
2098 MockRead("Content-Length: 100\r\n\r\n"),
2099 MockRead("hello"),
2100 MockRead(SYNCHRONOUS, 0),
2101 };
Ryan Sleevib8d7ea02018-05-07 20:01:012102 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:072103 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:172104
2105 TestCompletionCallback callback;
2106
tfarina42834112016-09-22 13:38:202107 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012108 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:172109
2110 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:012111 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:172112
Victor Costan9c7302b2018-08-27 16:39:442113 scoped_refptr<IOBufferWithSize> io_buf =
2114 base::MakeRefCounted<IOBufferWithSize>(100);
[email protected]90499482013-06-01 00:39:502115 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:172116 if (rv == ERR_IO_PENDING)
2117 rv = callback.WaitForResult();
2118 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:502119 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
robpercival214763f2016-07-01 23:27:012120 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:172121
2122 trans.reset();
fdoray92e35a72016-06-10 15:54:552123 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:172124 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2125}
2126
bncd16676a2016-07-20 16:23:012127TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:172128 HttpRequestInfo request;
2129 request.method = "GET";
bncce36dca22015-04-21 22:11:232130 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102131 request.traffic_annotation =
2132 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7a5378b2012-11-04 03:25:172133
danakj1fd259a02016-04-16 03:17:092134 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:582135 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:192136 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:172137
2138 MockRead data_reads[] = {
2139 MockRead("HTTP/1.0 200 OK\r\n"),
2140 MockRead("Connection: keep-alive\r\n"),
2141 MockRead("Content-Length: 100\r\n\r\n"),
2142 MockRead(SYNCHRONOUS, 0),
2143 };
Ryan Sleevib8d7ea02018-05-07 20:01:012144 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:072145 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:172146
2147 TestCompletionCallback callback;
2148
tfarina42834112016-09-22 13:38:202149 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012150 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:172151
2152 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:012153 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:172154
Victor Costan9c7302b2018-08-27 16:39:442155 scoped_refptr<IOBufferWithSize> io_buf(
2156 base::MakeRefCounted<IOBufferWithSize>(100));
[email protected]90499482013-06-01 00:39:502157 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:172158 if (rv == ERR_IO_PENDING)
2159 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:012160 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:172161
2162 trans.reset();
fdoray92e35a72016-06-10 15:54:552163 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:172164 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2165}
2166
[email protected]0b0bf032010-09-21 18:08:502167// Test that we correctly reuse a keep-alive connection after not explicitly
2168// reading the body.
bncd16676a2016-07-20 16:23:012169TEST_F(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:132170 HttpRequestInfo request;
2171 request.method = "GET";
2172 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:102173 request.traffic_annotation =
2174 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]fc31d6a42010-06-24 18:05:132175
vishal.b62985ca92015-04-17 08:45:512176 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:072177 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:092178 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272179
mmenkecc2298e2015-12-07 18:20:182180 const char* request_data =
2181 "GET / HTTP/1.1\r\n"
2182 "Host: www.foo.com\r\n"
2183 "Connection: keep-alive\r\n\r\n";
2184 MockWrite data_writes[] = {
2185 MockWrite(ASYNC, 0, request_data), MockWrite(ASYNC, 2, request_data),
2186 MockWrite(ASYNC, 4, request_data), MockWrite(ASYNC, 6, request_data),
2187 MockWrite(ASYNC, 8, request_data), MockWrite(ASYNC, 10, request_data),
2188 MockWrite(ASYNC, 12, request_data), MockWrite(ASYNC, 14, request_data),
2189 MockWrite(ASYNC, 17, request_data), MockWrite(ASYNC, 20, request_data),
2190 };
2191
[email protected]0b0bf032010-09-21 18:08:502192 // Note that because all these reads happen in the same
2193 // StaticSocketDataProvider, it shows that the same socket is being reused for
2194 // all transactions.
mmenkecc2298e2015-12-07 18:20:182195 MockRead data_reads[] = {
2196 MockRead(ASYNC, 1, "HTTP/1.1 204 No Content\r\n\r\n"),
2197 MockRead(ASYNC, 3, "HTTP/1.1 205 Reset Content\r\n\r\n"),
2198 MockRead(ASYNC, 5, "HTTP/1.1 304 Not Modified\r\n\r\n"),
2199 MockRead(ASYNC, 7,
2200 "HTTP/1.1 302 Found\r\n"
2201 "Content-Length: 0\r\n\r\n"),
2202 MockRead(ASYNC, 9,
2203 "HTTP/1.1 302 Found\r\n"
2204 "Content-Length: 5\r\n\r\n"
2205 "hello"),
2206 MockRead(ASYNC, 11,
2207 "HTTP/1.1 301 Moved Permanently\r\n"
2208 "Content-Length: 0\r\n\r\n"),
2209 MockRead(ASYNC, 13,
2210 "HTTP/1.1 301 Moved Permanently\r\n"
2211 "Content-Length: 5\r\n\r\n"
2212 "hello"),
[email protected]fc31d6a42010-06-24 18:05:132213
mmenkecc2298e2015-12-07 18:20:182214 // In the next two rounds, IsConnectedAndIdle returns false, due to
2215 // the set_busy_before_sync_reads(true) call, while the
2216 // HttpNetworkTransaction is being shut down, but the socket is still
2217 // reuseable. See http://crbug.com/544255.
2218 MockRead(ASYNC, 15,
2219 "HTTP/1.1 200 Hunky-Dory\r\n"
2220 "Content-Length: 5\r\n\r\n"),
2221 MockRead(SYNCHRONOUS, 16, "hello"),
[email protected]fc31d6a42010-06-24 18:05:132222
mmenkecc2298e2015-12-07 18:20:182223 MockRead(ASYNC, 18,
2224 "HTTP/1.1 200 Hunky-Dory\r\n"
2225 "Content-Length: 5\r\n\r\n"
2226 "he"),
2227 MockRead(SYNCHRONOUS, 19, "llo"),
2228
2229 // The body of the final request is actually read.
2230 MockRead(ASYNC, 21, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
2231 MockRead(ASYNC, 22, "hello"),
2232 };
Ryan Sleevib8d7ea02018-05-07 20:01:012233 SequencedSocketData data(data_reads, data_writes);
mmenkecc2298e2015-12-07 18:20:182234 data.set_busy_before_sync_reads(true);
2235 session_deps_.socket_factory->AddSocketDataProvider(&data);
2236
Avi Drissman4365a4782018-12-28 19:26:242237 const int kNumUnreadBodies = base::size(data_writes) - 1;
[email protected]0b0bf032010-09-21 18:08:502238 std::string response_lines[kNumUnreadBodies];
2239
mikecironef22f9812016-10-04 03:40:192240 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
mmenkecc2298e2015-12-07 18:20:182241 for (size_t i = 0; i < kNumUnreadBodies; ++i) {
[email protected]49639fa2011-12-20 23:22:412242 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:132243
Jeremy Roman0579ed62017-08-29 15:56:192244 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
bnc87dcefc2017-05-25 12:47:582245 session.get());
[email protected]fc31d6a42010-06-24 18:05:132246
tfarina42834112016-09-22 13:38:202247 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012248 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]fc31d6a42010-06-24 18:05:132249
[email protected]58e32bb2013-01-21 18:23:252250 LoadTimingInfo load_timing_info;
2251 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2252 if (i == 0) {
2253 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
2254 first_socket_log_id = load_timing_info.socket_log_id;
2255 } else {
2256 TestLoadTimingReused(load_timing_info);
2257 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
2258 }
2259
[email protected]fc31d6a42010-06-24 18:05:132260 const HttpResponseInfo* response = trans->GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182261 ASSERT_TRUE(response);
[email protected]fc31d6a42010-06-24 18:05:132262
mmenkecc2298e2015-12-07 18:20:182263 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502264 response_lines[i] = response->headers->GetStatusLine();
2265
mmenkecc2298e2015-12-07 18:20:182266 // Delete the transaction without reading the response bodies. Then spin
2267 // the message loop, so the response bodies are drained.
2268 trans.reset();
2269 base::RunLoop().RunUntilIdle();
[email protected]fc31d6a42010-06-24 18:05:132270 }
[email protected]0b0bf032010-09-21 18:08:502271
2272 const char* const kStatusLines[] = {
mmenkecc2298e2015-12-07 18:20:182273 "HTTP/1.1 204 No Content",
2274 "HTTP/1.1 205 Reset Content",
2275 "HTTP/1.1 304 Not Modified",
2276 "HTTP/1.1 302 Found",
2277 "HTTP/1.1 302 Found",
2278 "HTTP/1.1 301 Moved Permanently",
2279 "HTTP/1.1 301 Moved Permanently",
2280 "HTTP/1.1 200 Hunky-Dory",
2281 "HTTP/1.1 200 Hunky-Dory",
[email protected]0b0bf032010-09-21 18:08:502282 };
2283
Avi Drissman4365a4782018-12-28 19:26:242284 static_assert(kNumUnreadBodies == base::size(kStatusLines),
mostynb91e0da982015-01-20 19:17:272285 "forgot to update kStatusLines");
[email protected]0b0bf032010-09-21 18:08:502286
2287 for (int i = 0; i < kNumUnreadBodies; ++i)
2288 EXPECT_EQ(kStatusLines[i], response_lines[i]);
2289
[email protected]49639fa2011-12-20 23:22:412290 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:162291 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202292 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012293 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:162294 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182295 ASSERT_TRUE(response);
2296 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502297 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2298 std::string response_data;
bnc691fda62016-08-12 00:43:162299 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:012300 EXPECT_THAT(rv, IsOk());
[email protected]0b0bf032010-09-21 18:08:502301 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:132302}
2303
mmenke5f94fda2016-06-02 20:54:132304// Sockets that receive extra data after a response is complete should not be
2305// reused.
bncd16676a2016-07-20 16:23:012306TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData1) {
mmenke5f94fda2016-06-02 20:54:132307 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2308 MockWrite data_writes1[] = {
2309 MockWrite("HEAD / HTTP/1.1\r\n"
2310 "Host: www.borked.com\r\n"
2311 "Connection: keep-alive\r\n\r\n"),
2312 };
2313
2314 MockRead data_reads1[] = {
2315 MockRead("HTTP/1.1 200 OK\r\n"
2316 "Connection: keep-alive\r\n"
2317 "Content-Length: 22\r\n\r\n"
2318 "This server is borked."),
2319 };
2320
2321 MockWrite data_writes2[] = {
2322 MockWrite("GET /foo HTTP/1.1\r\n"
2323 "Host: www.borked.com\r\n"
2324 "Connection: keep-alive\r\n\r\n"),
2325 };
2326
2327 MockRead data_reads2[] = {
2328 MockRead("HTTP/1.1 200 OK\r\n"
2329 "Content-Length: 3\r\n\r\n"
2330 "foo"),
2331 };
Ryan Sleevib8d7ea02018-05-07 20:01:012332 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke5f94fda2016-06-02 20:54:132333 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:012334 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke5f94fda2016-06-02 20:54:132335 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2336
2337 TestCompletionCallback callback;
2338 HttpRequestInfo request1;
2339 request1.method = "HEAD";
2340 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e2018-02-07 07:41:102341 request1.traffic_annotation =
2342 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132343
bnc87dcefc2017-05-25 12:47:582344 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192345 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202346 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012347 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132348
2349 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2350 ASSERT_TRUE(response1);
2351 ASSERT_TRUE(response1->headers);
2352 EXPECT_EQ(200, response1->headers->response_code());
2353 EXPECT_TRUE(response1->headers->IsKeepAlive());
2354
2355 std::string response_data1;
robpercival214763f2016-07-01 23:27:012356 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132357 EXPECT_EQ("", response_data1);
2358 // Deleting the transaction attempts to release the socket back into the
2359 // socket pool.
2360 trans1.reset();
2361
2362 HttpRequestInfo request2;
2363 request2.method = "GET";
2364 request2.url = GURL("http://www.borked.com/foo");
Ramin Halavatib5e433e2018-02-07 07:41:102365 request2.traffic_annotation =
2366 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132367
bnc87dcefc2017-05-25 12:47:582368 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192369 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202370 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012371 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132372
2373 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2374 ASSERT_TRUE(response2);
2375 ASSERT_TRUE(response2->headers);
2376 EXPECT_EQ(200, response2->headers->response_code());
2377
2378 std::string response_data2;
robpercival214763f2016-07-01 23:27:012379 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132380 EXPECT_EQ("foo", response_data2);
2381}
2382
bncd16676a2016-07-20 16:23:012383TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData2) {
mmenke5f94fda2016-06-02 20:54:132384 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2385 MockWrite data_writes1[] = {
2386 MockWrite("GET / HTTP/1.1\r\n"
2387 "Host: www.borked.com\r\n"
2388 "Connection: keep-alive\r\n\r\n"),
2389 };
2390
2391 MockRead data_reads1[] = {
2392 MockRead("HTTP/1.1 200 OK\r\n"
2393 "Connection: keep-alive\r\n"
2394 "Content-Length: 22\r\n\r\n"
2395 "This server is borked."
2396 "Bonus data!"),
2397 };
2398
2399 MockWrite data_writes2[] = {
2400 MockWrite("GET /foo HTTP/1.1\r\n"
2401 "Host: www.borked.com\r\n"
2402 "Connection: keep-alive\r\n\r\n"),
2403 };
2404
2405 MockRead data_reads2[] = {
2406 MockRead("HTTP/1.1 200 OK\r\n"
2407 "Content-Length: 3\r\n\r\n"
2408 "foo"),
2409 };
Ryan Sleevib8d7ea02018-05-07 20:01:012410 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke5f94fda2016-06-02 20:54:132411 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:012412 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke5f94fda2016-06-02 20:54:132413 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2414
2415 TestCompletionCallback callback;
2416 HttpRequestInfo request1;
2417 request1.method = "GET";
2418 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e2018-02-07 07:41:102419 request1.traffic_annotation =
2420 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132421
bnc87dcefc2017-05-25 12:47:582422 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192423 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202424 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012425 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132426
2427 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2428 ASSERT_TRUE(response1);
2429 ASSERT_TRUE(response1->headers);
2430 EXPECT_EQ(200, response1->headers->response_code());
2431 EXPECT_TRUE(response1->headers->IsKeepAlive());
2432
2433 std::string response_data1;
robpercival214763f2016-07-01 23:27:012434 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132435 EXPECT_EQ("This server is borked.", response_data1);
2436 // Deleting the transaction attempts to release the socket back into the
2437 // socket pool.
2438 trans1.reset();
2439
2440 HttpRequestInfo request2;
2441 request2.method = "GET";
2442 request2.url = GURL("http://www.borked.com/foo");
Ramin Halavatib5e433e2018-02-07 07:41:102443 request2.traffic_annotation =
2444 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132445
bnc87dcefc2017-05-25 12:47:582446 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192447 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202448 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012449 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132450
2451 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2452 ASSERT_TRUE(response2);
2453 ASSERT_TRUE(response2->headers);
2454 EXPECT_EQ(200, response2->headers->response_code());
2455
2456 std::string response_data2;
robpercival214763f2016-07-01 23:27:012457 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132458 EXPECT_EQ("foo", response_data2);
2459}
2460
bncd16676a2016-07-20 16:23:012461TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData3) {
mmenke5f94fda2016-06-02 20:54:132462 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2463 MockWrite data_writes1[] = {
2464 MockWrite("GET / HTTP/1.1\r\n"
2465 "Host: www.borked.com\r\n"
2466 "Connection: keep-alive\r\n\r\n"),
2467 };
2468
2469 MockRead data_reads1[] = {
2470 MockRead("HTTP/1.1 200 OK\r\n"
2471 "Connection: keep-alive\r\n"
2472 "Transfer-Encoding: chunked\r\n\r\n"),
2473 MockRead("16\r\nThis server is borked.\r\n"),
2474 MockRead("0\r\n\r\nBonus data!"),
2475 };
2476
2477 MockWrite data_writes2[] = {
2478 MockWrite("GET /foo HTTP/1.1\r\n"
2479 "Host: www.borked.com\r\n"
2480 "Connection: keep-alive\r\n\r\n"),
2481 };
2482
2483 MockRead data_reads2[] = {
2484 MockRead("HTTP/1.1 200 OK\r\n"
2485 "Content-Length: 3\r\n\r\n"
2486 "foo"),
2487 };
Ryan Sleevib8d7ea02018-05-07 20:01:012488 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke5f94fda2016-06-02 20:54:132489 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:012490 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke5f94fda2016-06-02 20:54:132491 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2492
2493 TestCompletionCallback callback;
2494 HttpRequestInfo request1;
2495 request1.method = "GET";
2496 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e2018-02-07 07:41:102497 request1.traffic_annotation =
2498 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132499
bnc87dcefc2017-05-25 12:47:582500 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192501 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202502 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012503 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132504
2505 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2506 ASSERT_TRUE(response1);
2507 ASSERT_TRUE(response1->headers);
2508 EXPECT_EQ(200, response1->headers->response_code());
2509 EXPECT_TRUE(response1->headers->IsKeepAlive());
2510
2511 std::string response_data1;
robpercival214763f2016-07-01 23:27:012512 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132513 EXPECT_EQ("This server is borked.", response_data1);
2514 // Deleting the transaction attempts to release the socket back into the
2515 // socket pool.
2516 trans1.reset();
2517
2518 HttpRequestInfo request2;
2519 request2.method = "GET";
2520 request2.url = GURL("http://www.borked.com/foo");
Ramin Halavatib5e433e2018-02-07 07:41:102521 request2.traffic_annotation =
2522 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132523
bnc87dcefc2017-05-25 12:47:582524 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192525 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202526 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012527 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132528
2529 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2530 ASSERT_TRUE(response2);
2531 ASSERT_TRUE(response2->headers);
2532 EXPECT_EQ(200, response2->headers->response_code());
2533
2534 std::string response_data2;
robpercival214763f2016-07-01 23:27:012535 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132536 EXPECT_EQ("foo", response_data2);
2537}
2538
2539// This is a little different from the others - it tests the case that the
2540// HttpStreamParser doesn't know if there's extra data on a socket or not when
2541// the HttpNetworkTransaction is torn down, because the response body hasn't
2542// been read from yet, but the request goes through the HttpResponseBodyDrainer.
bncd16676a2016-07-20 16:23:012543TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData4) {
mmenke5f94fda2016-06-02 20:54:132544 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2545 MockWrite data_writes1[] = {
2546 MockWrite("GET / HTTP/1.1\r\n"
2547 "Host: www.borked.com\r\n"
2548 "Connection: keep-alive\r\n\r\n"),
2549 };
2550
2551 MockRead data_reads1[] = {
2552 MockRead("HTTP/1.1 200 OK\r\n"
2553 "Connection: keep-alive\r\n"
2554 "Transfer-Encoding: chunked\r\n\r\n"),
2555 MockRead("16\r\nThis server is borked.\r\n"),
2556 MockRead("0\r\n\r\nBonus data!"),
2557 };
Ryan Sleevib8d7ea02018-05-07 20:01:012558 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke5f94fda2016-06-02 20:54:132559 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2560
2561 TestCompletionCallback callback;
2562 HttpRequestInfo request1;
2563 request1.method = "GET";
2564 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e2018-02-07 07:41:102565 request1.traffic_annotation =
2566 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132567
bnc87dcefc2017-05-25 12:47:582568 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:192569 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
bnc87dcefc2017-05-25 12:47:582570 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012571 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132572
bnc87dcefc2017-05-25 12:47:582573 const HttpResponseInfo* response1 = trans->GetResponseInfo();
mmenke5f94fda2016-06-02 20:54:132574 ASSERT_TRUE(response1);
2575 ASSERT_TRUE(response1->headers);
2576 EXPECT_EQ(200, response1->headers->response_code());
2577 EXPECT_TRUE(response1->headers->IsKeepAlive());
2578
2579 // Deleting the transaction creates an HttpResponseBodyDrainer to read the
2580 // response body.
bnc87dcefc2017-05-25 12:47:582581 trans.reset();
mmenke5f94fda2016-06-02 20:54:132582
2583 // Let the HttpResponseBodyDrainer drain the socket. It should determine the
2584 // socket can't be reused, rather than returning it to the socket pool.
2585 base::RunLoop().RunUntilIdle();
2586
2587 // There should be no idle sockets in the pool.
2588 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2589}
2590
[email protected]038e9a32008-10-08 22:40:162591// Test the request-challenge-retry sequence for basic auth.
2592// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012593TEST_F(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:422594 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:162595 request.method = "GET";
bncce36dca22015-04-21 22:11:232596 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102597 request.traffic_annotation =
2598 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]038e9a32008-10-08 22:40:162599
vishal.b62985ca92015-04-17 08:45:512600 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072601 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092602 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162603 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272604
[email protected]f9ee6b52008-11-08 06:46:232605 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232606 MockWrite(
2607 "GET / HTTP/1.1\r\n"
2608 "Host: www.example.org\r\n"
2609 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:232610 };
2611
[email protected]038e9a32008-10-08 22:40:162612 MockRead data_reads1[] = {
2613 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2614 // Give a couple authenticate options (only the middle one is actually
2615 // supported).
[email protected]22927ad2009-09-21 19:56:192616 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:162617 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2618 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2619 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2620 // Large content-length -- won't matter, as connection will be reset.
2621 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062622 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:162623 };
2624
2625 // After calling trans->RestartWithAuth(), this is the request we should
2626 // be issuing -- the final header line contains the credentials.
2627 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232628 MockWrite(
2629 "GET / HTTP/1.1\r\n"
2630 "Host: www.example.org\r\n"
2631 "Connection: keep-alive\r\n"
2632 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:162633 };
2634
2635 // Lastly, the server responds with the actual content.
2636 MockRead data_reads2[] = {
2637 MockRead("HTTP/1.0 200 OK\r\n"),
2638 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2639 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062640 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:162641 };
2642
Ryan Sleevib8d7ea02018-05-07 20:01:012643 StaticSocketDataProvider data1(data_reads1, data_writes1);
2644 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:072645 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2646 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:162647
[email protected]49639fa2011-12-20 23:22:412648 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:162649
tfarina42834112016-09-22 13:38:202650 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012651 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162652
2653 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012654 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162655
[email protected]58e32bb2013-01-21 18:23:252656 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162657 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
[email protected]58e32bb2013-01-21 18:23:252658 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2659
Ryan Sleevib8d7ea02018-05-07 20:01:012660 int64_t writes_size1 = CountWriteBytes(data_writes1);
bnc691fda62016-08-12 00:43:162661 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012662 int64_t reads_size1 = CountReadBytes(data_reads1);
bnc691fda62016-08-12 00:43:162663 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192664
bnc691fda62016-08-12 00:43:162665 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522666 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042667 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:162668
[email protected]49639fa2011-12-20 23:22:412669 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:162670
bnc691fda62016-08-12 00:43:162671 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012672 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162673
2674 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012675 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162676
[email protected]58e32bb2013-01-21 18:23:252677 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162678 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
[email protected]58e32bb2013-01-21 18:23:252679 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2680 // The load timing after restart should have a new socket ID, and times after
2681 // those of the first load timing.
2682 EXPECT_LE(load_timing_info1.receive_headers_end,
2683 load_timing_info2.connect_timing.connect_start);
2684 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2685
Ryan Sleevib8d7ea02018-05-07 20:01:012686 int64_t writes_size2 = CountWriteBytes(data_writes2);
bnc691fda62016-08-12 00:43:162687 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012688 int64_t reads_size2 = CountReadBytes(data_reads2);
bnc691fda62016-08-12 00:43:162689 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192690
bnc691fda62016-08-12 00:43:162691 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522692 ASSERT_TRUE(response);
2693 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:162694 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:162695}
2696
ttuttled9dbc652015-09-29 20:00:592697// Test the request-challenge-retry sequence for basic auth.
2698// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012699TEST_F(HttpNetworkTransactionTest, BasicAuthWithAddressChange) {
ttuttled9dbc652015-09-29 20:00:592700 HttpRequestInfo request;
2701 request.method = "GET";
2702 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102703 request.traffic_annotation =
2704 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttled9dbc652015-09-29 20:00:592705
2706 TestNetLog log;
2707 MockHostResolver* resolver = new MockHostResolver();
2708 session_deps_.net_log = &log;
2709 session_deps_.host_resolver.reset(resolver);
danakj1fd259a02016-04-16 03:17:092710 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
bnc691fda62016-08-12 00:43:162711 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttled9dbc652015-09-29 20:00:592712
2713 resolver->rules()->ClearRules();
2714 resolver->rules()->AddRule("www.example.org", "127.0.0.1");
2715
2716 MockWrite data_writes1[] = {
2717 MockWrite("GET / HTTP/1.1\r\n"
2718 "Host: www.example.org\r\n"
2719 "Connection: keep-alive\r\n\r\n"),
2720 };
2721
2722 MockRead data_reads1[] = {
2723 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2724 // Give a couple authenticate options (only the middle one is actually
2725 // supported).
2726 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
2727 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2728 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2729 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2730 // Large content-length -- won't matter, as connection will be reset.
2731 MockRead("Content-Length: 10000\r\n\r\n"),
2732 MockRead(SYNCHRONOUS, ERR_FAILED),
2733 };
2734
2735 // After calling trans->RestartWithAuth(), this is the request we should
2736 // be issuing -- the final header line contains the credentials.
2737 MockWrite data_writes2[] = {
2738 MockWrite("GET / HTTP/1.1\r\n"
2739 "Host: www.example.org\r\n"
2740 "Connection: keep-alive\r\n"
2741 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2742 };
2743
2744 // Lastly, the server responds with the actual content.
2745 MockRead data_reads2[] = {
2746 MockRead("HTTP/1.0 200 OK\r\n"),
2747 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2748 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, OK),
2749 };
2750
Ryan Sleevib8d7ea02018-05-07 20:01:012751 StaticSocketDataProvider data1(data_reads1, data_writes1);
2752 StaticSocketDataProvider data2(data_reads2, data_writes2);
ttuttled9dbc652015-09-29 20:00:592753 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2754 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2755
2756 TestCompletionCallback callback1;
2757
bnc691fda62016-08-12 00:43:162758 EXPECT_EQ(OK, callback1.GetResult(trans.Start(&request, callback1.callback(),
tfarina42834112016-09-22 13:38:202759 NetLogWithSource())));
ttuttled9dbc652015-09-29 20:00:592760
2761 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162762 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
ttuttled9dbc652015-09-29 20:00:592763 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2764
Ryan Sleevib8d7ea02018-05-07 20:01:012765 int64_t writes_size1 = CountWriteBytes(data_writes1);
bnc691fda62016-08-12 00:43:162766 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012767 int64_t reads_size1 = CountReadBytes(data_reads1);
bnc691fda62016-08-12 00:43:162768 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592769
bnc691fda62016-08-12 00:43:162770 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592771 ASSERT_TRUE(response);
2772 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2773
2774 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:162775 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592776 ASSERT_FALSE(endpoint.address().empty());
2777 EXPECT_EQ("127.0.0.1:80", endpoint.ToString());
2778
2779 resolver->rules()->ClearRules();
2780 resolver->rules()->AddRule("www.example.org", "127.0.0.2");
2781
2782 TestCompletionCallback callback2;
2783
bnc691fda62016-08-12 00:43:162784 EXPECT_EQ(OK, callback2.GetResult(trans.RestartWithAuth(
ttuttled9dbc652015-09-29 20:00:592785 AuthCredentials(kFoo, kBar), callback2.callback())));
2786
2787 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162788 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
ttuttled9dbc652015-09-29 20:00:592789 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2790 // The load timing after restart should have a new socket ID, and times after
2791 // those of the first load timing.
2792 EXPECT_LE(load_timing_info1.receive_headers_end,
2793 load_timing_info2.connect_timing.connect_start);
2794 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2795
Ryan Sleevib8d7ea02018-05-07 20:01:012796 int64_t writes_size2 = CountWriteBytes(data_writes2);
bnc691fda62016-08-12 00:43:162797 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012798 int64_t reads_size2 = CountReadBytes(data_reads2);
bnc691fda62016-08-12 00:43:162799 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592800
bnc691fda62016-08-12 00:43:162801 response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592802 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:522803 EXPECT_FALSE(response->auth_challenge);
ttuttled9dbc652015-09-29 20:00:592804 EXPECT_EQ(100, response->headers->GetContentLength());
2805
bnc691fda62016-08-12 00:43:162806 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592807 ASSERT_FALSE(endpoint.address().empty());
2808 EXPECT_EQ("127.0.0.2:80", endpoint.ToString());
2809}
2810
David Benjamin83ddfb32018-03-30 01:07:522811// Test that, if the server requests auth indefinitely, HttpNetworkTransaction
2812// will eventually give up.
2813TEST_F(HttpNetworkTransactionTest, BasicAuthForever) {
2814 HttpRequestInfo request;
2815 request.method = "GET";
2816 request.url = GURL("http://www.example.org/");
2817 request.traffic_annotation =
2818 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2819
2820 TestNetLog log;
2821 session_deps_.net_log = &log;
2822 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2823 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
2824
2825 MockWrite data_writes[] = {
2826 MockWrite("GET / HTTP/1.1\r\n"
2827 "Host: www.example.org\r\n"
2828 "Connection: keep-alive\r\n\r\n"),
2829 };
2830
2831 MockRead data_reads[] = {
2832 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2833 // Give a couple authenticate options (only the middle one is actually
2834 // supported).
2835 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
2836 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2837 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2838 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2839 // Large content-length -- won't matter, as connection will be reset.
2840 MockRead("Content-Length: 10000\r\n\r\n"),
2841 MockRead(SYNCHRONOUS, ERR_FAILED),
2842 };
2843
2844 // After calling trans->RestartWithAuth(), this is the request we should
2845 // be issuing -- the final header line contains the credentials.
2846 MockWrite data_writes_restart[] = {
2847 MockWrite("GET / HTTP/1.1\r\n"
2848 "Host: www.example.org\r\n"
2849 "Connection: keep-alive\r\n"
2850 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2851 };
2852
Ryan Sleevib8d7ea02018-05-07 20:01:012853 StaticSocketDataProvider data(data_reads, data_writes);
David Benjamin83ddfb32018-03-30 01:07:522854 session_deps_.socket_factory->AddSocketDataProvider(&data);
2855
2856 TestCompletionCallback callback;
2857 int rv = callback.GetResult(
2858 trans.Start(&request, callback.callback(), NetLogWithSource()));
2859
2860 std::vector<std::unique_ptr<StaticSocketDataProvider>> data_restarts;
2861 for (int i = 0; i < 32; i++) {
2862 // Check the previous response was a 401.
2863 EXPECT_THAT(rv, IsOk());
2864 const HttpResponseInfo* response = trans.GetResponseInfo();
2865 ASSERT_TRUE(response);
2866 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2867
2868 data_restarts.push_back(std::make_unique<StaticSocketDataProvider>(
Ryan Sleevib8d7ea02018-05-07 20:01:012869 data_reads, data_writes_restart));
David Benjamin83ddfb32018-03-30 01:07:522870 session_deps_.socket_factory->AddSocketDataProvider(
2871 data_restarts.back().get());
2872 rv = callback.GetResult(trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
2873 callback.callback()));
2874 }
2875
2876 // After too many tries, the transaction should have given up.
2877 EXPECT_THAT(rv, IsError(ERR_TOO_MANY_RETRIES));
2878}
2879
bncd16676a2016-07-20 16:23:012880TEST_F(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:462881 HttpRequestInfo request;
2882 request.method = "GET";
bncce36dca22015-04-21 22:11:232883 request.url = GURL("http://www.example.org/");
ttuttle859dc7a2015-04-23 19:42:292884 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:102885 request.traffic_annotation =
2886 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]861fcd52009-08-26 02:33:462887
danakj1fd259a02016-04-16 03:17:092888 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162889 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272890
[email protected]861fcd52009-08-26 02:33:462891 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:232892 MockWrite(
2893 "GET / HTTP/1.1\r\n"
2894 "Host: www.example.org\r\n"
2895 "Connection: keep-alive\r\n\r\n"),
[email protected]861fcd52009-08-26 02:33:462896 };
2897
2898 MockRead data_reads[] = {
2899 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2900 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2901 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2902 // Large content-length -- won't matter, as connection will be reset.
2903 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062904 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:462905 };
2906
Ryan Sleevib8d7ea02018-05-07 20:01:012907 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:072908 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:412909 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:462910
tfarina42834112016-09-22 13:38:202911 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012912 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]861fcd52009-08-26 02:33:462913
2914 rv = callback.WaitForResult();
2915 EXPECT_EQ(0, rv);
2916
Ryan Sleevib8d7ea02018-05-07 20:01:012917 int64_t writes_size = CountWriteBytes(data_writes);
bnc691fda62016-08-12 00:43:162918 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012919 int64_t reads_size = CountReadBytes(data_reads);
bnc691fda62016-08-12 00:43:162920 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192921
bnc691fda62016-08-12 00:43:162922 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522923 ASSERT_TRUE(response);
2924 EXPECT_FALSE(response->auth_challenge);
[email protected]861fcd52009-08-26 02:33:462925}
2926
[email protected]2d2697f92009-02-18 21:00:322927// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2928// connection.
bncd16676a2016-07-20 16:23:012929TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
mmenkecc2298e2015-12-07 18:20:182930 // On the second pass, the body read of the auth challenge is synchronous, so
2931 // IsConnectedAndIdle returns false. The socket should still be drained and
2932 // reused. See http://crbug.com/544255.
2933 for (int i = 0; i < 2; ++i) {
2934 HttpRequestInfo request;
2935 request.method = "GET";
2936 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102937 request.traffic_annotation =
2938 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:322939
mmenkecc2298e2015-12-07 18:20:182940 TestNetLog log;
2941 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092942 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272943
mmenkecc2298e2015-12-07 18:20:182944 MockWrite data_writes[] = {
2945 MockWrite(ASYNC, 0,
2946 "GET / HTTP/1.1\r\n"
2947 "Host: www.example.org\r\n"
2948 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322949
bnc691fda62016-08-12 00:43:162950 // After calling trans.RestartWithAuth(), this is the request we should
mmenkecc2298e2015-12-07 18:20:182951 // be issuing -- the final header line contains the credentials.
2952 MockWrite(ASYNC, 6,
2953 "GET / HTTP/1.1\r\n"
2954 "Host: www.example.org\r\n"
2955 "Connection: keep-alive\r\n"
2956 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2957 };
[email protected]2d2697f92009-02-18 21:00:322958
mmenkecc2298e2015-12-07 18:20:182959 MockRead data_reads[] = {
2960 MockRead(ASYNC, 1, "HTTP/1.1 401 Unauthorized\r\n"),
2961 MockRead(ASYNC, 2, "WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2962 MockRead(ASYNC, 3, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2963 MockRead(ASYNC, 4, "Content-Length: 14\r\n\r\n"),
2964 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 5, "Unauthorized\r\n"),
[email protected]2d2697f92009-02-18 21:00:322965
mmenkecc2298e2015-12-07 18:20:182966 // Lastly, the server responds with the actual content.
2967 MockRead(ASYNC, 7, "HTTP/1.1 200 OK\r\n"),
2968 MockRead(ASYNC, 8, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2969 MockRead(ASYNC, 9, "Content-Length: 5\r\n\r\n"),
2970 MockRead(ASYNC, 10, "Hello"),
2971 };
[email protected]2d2697f92009-02-18 21:00:322972
Ryan Sleevib8d7ea02018-05-07 20:01:012973 SequencedSocketData data(data_reads, data_writes);
mmenkecc2298e2015-12-07 18:20:182974 data.set_busy_before_sync_reads(true);
2975 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]2d0a4f92011-05-05 16:38:462976
mmenkecc2298e2015-12-07 18:20:182977 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322978
bnc691fda62016-08-12 00:43:162979 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202980 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012981 ASSERT_THAT(callback1.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322982
mmenkecc2298e2015-12-07 18:20:182983 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162984 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
mmenkecc2298e2015-12-07 18:20:182985 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
[email protected]2d2697f92009-02-18 21:00:322986
bnc691fda62016-08-12 00:43:162987 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182988 ASSERT_TRUE(response);
2989 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322990
mmenkecc2298e2015-12-07 18:20:182991 TestCompletionCallback callback2;
[email protected]58e32bb2013-01-21 18:23:252992
bnc691fda62016-08-12 00:43:162993 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
2994 callback2.callback());
robpercival214763f2016-07-01 23:27:012995 ASSERT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322996
mmenkecc2298e2015-12-07 18:20:182997 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162998 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
mmenkecc2298e2015-12-07 18:20:182999 TestLoadTimingReused(load_timing_info2);
3000 // The load timing after restart should have the same socket ID, and times
3001 // those of the first load timing.
3002 EXPECT_LE(load_timing_info1.receive_headers_end,
3003 load_timing_info2.send_start);
3004 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]2d2697f92009-02-18 21:00:323005
bnc691fda62016-08-12 00:43:163006 response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:183007 ASSERT_TRUE(response);
3008 EXPECT_FALSE(response->auth_challenge);
3009 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:323010
mmenkecc2298e2015-12-07 18:20:183011 std::string response_data;
bnc691fda62016-08-12 00:43:163012 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]2d2697f92009-02-18 21:00:323013
Ryan Sleevib8d7ea02018-05-07 20:01:013014 int64_t writes_size = CountWriteBytes(data_writes);
bnc691fda62016-08-12 00:43:163015 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:013016 int64_t reads_size = CountReadBytes(data_reads);
bnc691fda62016-08-12 00:43:163017 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
mmenkecc2298e2015-12-07 18:20:183018 }
[email protected]2d2697f92009-02-18 21:00:323019}
3020
3021// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3022// connection and with no response body to drain.
bncd16676a2016-07-20 16:23:013023TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:423024 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:323025 request.method = "GET";
bncce36dca22015-04-21 22:11:233026 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:103027 request.traffic_annotation =
3028 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:323029
danakj1fd259a02016-04-16 03:17:093030 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273031
[email protected]2d2697f92009-02-18 21:00:323032 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:163033 MockWrite("GET / HTTP/1.1\r\n"
3034 "Host: www.example.org\r\n"
3035 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323036
bnc691fda62016-08-12 00:43:163037 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:233038 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:163039 MockWrite("GET / HTTP/1.1\r\n"
3040 "Host: www.example.org\r\n"
3041 "Connection: keep-alive\r\n"
3042 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323043 };
3044
[email protected]2d2697f92009-02-18 21:00:323045 MockRead data_reads1[] = {
3046 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
3047 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:313048 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:323049
3050 // Lastly, the server responds with the actual content.
3051 MockRead("HTTP/1.1 200 OK\r\n"),
3052 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:503053 MockRead("Content-Length: 5\r\n\r\n"),
3054 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:323055 };
3056
[email protected]2d0a4f92011-05-05 16:38:463057 // An incorrect reconnect would cause this to be read.
3058 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:063059 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:463060 };
3061
Ryan Sleevib8d7ea02018-05-07 20:01:013062 StaticSocketDataProvider data1(data_reads1, data_writes1);
3063 StaticSocketDataProvider data2(data_reads2, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:073064 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3065 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:323066
[email protected]49639fa2011-12-20 23:22:413067 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323068
bnc691fda62016-08-12 00:43:163069 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:203070 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013071 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:323072
3073 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013074 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:323075
bnc691fda62016-08-12 00:43:163076 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523077 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:043078 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:323079
[email protected]49639fa2011-12-20 23:22:413080 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323081
bnc691fda62016-08-12 00:43:163082 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013083 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:323084
3085 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013086 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:323087
bnc691fda62016-08-12 00:43:163088 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523089 ASSERT_TRUE(response);
3090 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503091 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:323092}
3093
3094// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3095// connection and with a large response body to drain.
bncd16676a2016-07-20 16:23:013096TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:423097 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:323098 request.method = "GET";
bncce36dca22015-04-21 22:11:233099 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:103100 request.traffic_annotation =
3101 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:323102
danakj1fd259a02016-04-16 03:17:093103 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273104
[email protected]2d2697f92009-02-18 21:00:323105 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:163106 MockWrite("GET / HTTP/1.1\r\n"
3107 "Host: www.example.org\r\n"
3108 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323109
bnc691fda62016-08-12 00:43:163110 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:233111 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:163112 MockWrite("GET / HTTP/1.1\r\n"
3113 "Host: www.example.org\r\n"
3114 "Connection: keep-alive\r\n"
3115 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323116 };
3117
3118 // Respond with 5 kb of response body.
3119 std::string large_body_string("Unauthorized");
3120 large_body_string.append(5 * 1024, ' ');
3121 large_body_string.append("\r\n");
3122
3123 MockRead data_reads1[] = {
3124 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
3125 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3126 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3127 // 5134 = 12 + 5 * 1024 + 2
3128 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063129 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:323130
3131 // Lastly, the server responds with the actual content.
3132 MockRead("HTTP/1.1 200 OK\r\n"),
3133 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:503134 MockRead("Content-Length: 5\r\n\r\n"),
3135 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:323136 };
3137
[email protected]2d0a4f92011-05-05 16:38:463138 // An incorrect reconnect would cause this to be read.
3139 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:063140 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:463141 };
3142
Ryan Sleevib8d7ea02018-05-07 20:01:013143 StaticSocketDataProvider data1(data_reads1, data_writes1);
3144 StaticSocketDataProvider data2(data_reads2, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:073145 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3146 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:323147
[email protected]49639fa2011-12-20 23:22:413148 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323149
bnc691fda62016-08-12 00:43:163150 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:203151 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013152 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:323153
3154 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013155 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:323156
bnc691fda62016-08-12 00:43:163157 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523158 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:043159 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:323160
[email protected]49639fa2011-12-20 23:22:413161 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323162
bnc691fda62016-08-12 00:43:163163 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013164 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:323165
3166 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013167 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:323168
bnc691fda62016-08-12 00:43:163169 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523170 ASSERT_TRUE(response);
3171 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503172 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:323173}
3174
3175// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:313176// connection, but the server gets impatient and closes the connection.
bncd16676a2016-07-20 16:23:013177TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:313178 HttpRequestInfo request;
3179 request.method = "GET";
bncce36dca22015-04-21 22:11:233180 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:103181 request.traffic_annotation =
3182 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]11203f012009-11-12 23:02:313183
danakj1fd259a02016-04-16 03:17:093184 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273185
[email protected]11203f012009-11-12 23:02:313186 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233187 MockWrite(
3188 "GET / HTTP/1.1\r\n"
3189 "Host: www.example.org\r\n"
3190 "Connection: keep-alive\r\n\r\n"),
3191 // This simulates the seemingly successful write to a closed connection
3192 // if the bug is not fixed.
3193 MockWrite(
3194 "GET / HTTP/1.1\r\n"
3195 "Host: www.example.org\r\n"
3196 "Connection: keep-alive\r\n"
3197 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:313198 };
3199
3200 MockRead data_reads1[] = {
3201 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
3202 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3203 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3204 MockRead("Content-Length: 14\r\n\r\n"),
3205 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:063206 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:313207 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:063208 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:313209 };
3210
bnc691fda62016-08-12 00:43:163211 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]11203f012009-11-12 23:02:313212 // be issuing -- the final header line contains the credentials.
3213 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:233214 MockWrite(
3215 "GET / HTTP/1.1\r\n"
3216 "Host: www.example.org\r\n"
3217 "Connection: keep-alive\r\n"
3218 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:313219 };
3220
3221 // Lastly, the server responds with the actual content.
3222 MockRead data_reads2[] = {
3223 MockRead("HTTP/1.1 200 OK\r\n"),
3224 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:503225 MockRead("Content-Length: 5\r\n\r\n"),
3226 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:313227 };
3228
Ryan Sleevib8d7ea02018-05-07 20:01:013229 StaticSocketDataProvider data1(data_reads1, data_writes1);
3230 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:073231 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3232 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:313233
[email protected]49639fa2011-12-20 23:22:413234 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:313235
bnc691fda62016-08-12 00:43:163236 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:203237 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013238 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:313239
3240 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013241 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:313242
bnc691fda62016-08-12 00:43:163243 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523244 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:043245 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:313246
[email protected]49639fa2011-12-20 23:22:413247 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:313248
bnc691fda62016-08-12 00:43:163249 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013250 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:313251
3252 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013253 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:313254
bnc691fda62016-08-12 00:43:163255 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523256 ASSERT_TRUE(response);
3257 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503258 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:313259}
3260
[email protected]394816e92010-08-03 07:38:593261// Test the request-challenge-retry sequence for basic auth, over a connection
3262// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013263TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
ttuttle34f63b52015-03-05 04:33:013264 HttpRequestInfo request;
3265 request.method = "GET";
bncce36dca22015-04-21 22:11:233266 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:013267 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293268 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103269 request.traffic_annotation =
3270 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle34f63b52015-03-05 04:33:013271
3272 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593273 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493274 ProxyResolutionService::CreateFixedFromPacResult(
3275 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513276 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:013277 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093278 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013279
3280 // Since we have proxy, should try to establish tunnel.
3281 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543282 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173283 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543284 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013285 };
3286
mmenkee71e15332015-10-07 16:39:543287 // The proxy responds to the connect with a 407, using a non-persistent
ttuttle34f63b52015-03-05 04:33:013288 // connection.
3289 MockRead data_reads1[] = {
3290 // No credentials.
3291 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
3292 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
mmenkee71e15332015-10-07 16:39:543293 };
ttuttle34f63b52015-03-05 04:33:013294
mmenkee71e15332015-10-07 16:39:543295 // Since the first connection couldn't be reused, need to establish another
3296 // once given credentials.
3297 MockWrite data_writes2[] = {
3298 // After calling trans->RestartWithAuth(), this is the request we should
3299 // be issuing -- the final header line contains the credentials.
3300 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173301 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543302 "Proxy-Connection: keep-alive\r\n"
3303 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3304
3305 MockWrite("GET / HTTP/1.1\r\n"
3306 "Host: www.example.org\r\n"
3307 "Connection: keep-alive\r\n\r\n"),
3308 };
3309
3310 MockRead data_reads2[] = {
ttuttle34f63b52015-03-05 04:33:013311 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3312
3313 MockRead("HTTP/1.1 200 OK\r\n"),
3314 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3315 MockRead("Content-Length: 5\r\n\r\n"),
3316 MockRead(SYNCHRONOUS, "hello"),
3317 };
3318
Ryan Sleevib8d7ea02018-05-07 20:01:013319 StaticSocketDataProvider data1(data_reads1, data_writes1);
ttuttle34f63b52015-03-05 04:33:013320 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:013321 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenkee71e15332015-10-07 16:39:543322 session_deps_.socket_factory->AddSocketDataProvider(&data2);
ttuttle34f63b52015-03-05 04:33:013323 SSLSocketDataProvider ssl(ASYNC, OK);
3324 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3325
3326 TestCompletionCallback callback1;
3327
bnc87dcefc2017-05-25 12:47:583328 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193329 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013330
3331 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013332 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:013333
3334 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013335 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463336 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:013337 log.GetEntries(&entries);
3338 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003339 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3340 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013341 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003342 entries, pos,
3343 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3344 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013345
3346 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523347 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013348 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523349 ASSERT_TRUE(response->headers);
ttuttle34f63b52015-03-05 04:33:013350 EXPECT_EQ(407, response->headers->response_code());
3351 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3352 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3353
3354 LoadTimingInfo load_timing_info;
3355 // CONNECT requests and responses are handled at the connect job level, so
3356 // the transaction does not yet have a connection.
3357 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3358
3359 TestCompletionCallback callback2;
3360
3361 rv =
3362 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013363 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:013364
3365 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013366 EXPECT_THAT(rv, IsOk());
ttuttle34f63b52015-03-05 04:33:013367
3368 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523369 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013370
3371 EXPECT_TRUE(response->headers->IsKeepAlive());
3372 EXPECT_EQ(200, response->headers->response_code());
3373 EXPECT_EQ(5, response->headers->GetContentLength());
3374 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3375
3376 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523377 EXPECT_FALSE(response->auth_challenge);
ttuttle34f63b52015-03-05 04:33:013378
3379 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3380 TestLoadTimingNotReusedWithPac(load_timing_info,
3381 CONNECT_TIMING_HAS_SSL_TIMES);
3382
3383 trans.reset();
3384 session->CloseAllConnections();
3385}
3386
3387// Test the request-challenge-retry sequence for basic auth, over a connection
3388// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013389TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) {
[email protected]394816e92010-08-03 07:38:593390 HttpRequestInfo request;
3391 request.method = "GET";
bncce36dca22015-04-21 22:11:233392 request.url = GURL("https://www.example.org/");
[email protected]394816e92010-08-03 07:38:593393 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293394 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103395 request.traffic_annotation =
3396 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]394816e92010-08-03 07:38:593397
[email protected]cb9bf6ca2011-01-28 13:15:273398 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593399 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493400 ProxyResolutionService::CreateFixedFromPacResult(
3401 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513402 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073403 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093404 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273405
[email protected]394816e92010-08-03 07:38:593406 // Since we have proxy, should try to establish tunnel.
3407 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543408 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173409 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543410 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenkee0b5c882015-08-26 20:29:113411 };
3412
mmenkee71e15332015-10-07 16:39:543413 // The proxy responds to the connect with a 407, using a non-persistent
mmenke0fd148d2015-09-30 23:00:083414 // connection.
3415 MockRead data_reads1[] = {
mmenkee71e15332015-10-07 16:39:543416 // No credentials.
3417 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3418 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3419 MockRead("Proxy-Connection: close\r\n\r\n"),
3420 };
mmenkee0b5c882015-08-26 20:29:113421
mmenkee71e15332015-10-07 16:39:543422 MockWrite data_writes2[] = {
3423 // After calling trans->RestartWithAuth(), this is the request we should
3424 // be issuing -- the final header line contains the credentials.
3425 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173426 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543427 "Proxy-Connection: keep-alive\r\n"
3428 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
mmenke0fd148d2015-09-30 23:00:083429
mmenkee71e15332015-10-07 16:39:543430 MockWrite("GET / HTTP/1.1\r\n"
3431 "Host: www.example.org\r\n"
3432 "Connection: keep-alive\r\n\r\n"),
3433 };
3434
3435 MockRead data_reads2[] = {
3436 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3437
3438 MockRead("HTTP/1.1 200 OK\r\n"),
3439 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3440 MockRead("Content-Length: 5\r\n\r\n"),
3441 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:593442 };
3443
Ryan Sleevib8d7ea02018-05-07 20:01:013444 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:073445 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:013446 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenkee71e15332015-10-07 16:39:543447 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8ddf8322012-02-23 18:08:063448 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073449 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:593450
[email protected]49639fa2011-12-20 23:22:413451 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:593452
bnc87dcefc2017-05-25 12:47:583453 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193454 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:503455
[email protected]49639fa2011-12-20 23:22:413456 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013457 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593458
3459 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013460 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463461 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403462 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:593463 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003464 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3465 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593466 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403467 entries, pos,
mikecirone8b85c432016-09-08 19:11:003468 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3469 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593470
3471 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523472 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013473 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523474 ASSERT_TRUE(response->headers);
[email protected]394816e92010-08-03 07:38:593475 EXPECT_EQ(407, response->headers->response_code());
3476 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043477 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:593478
[email protected]029c83b62013-01-24 05:28:203479 LoadTimingInfo load_timing_info;
3480 // CONNECT requests and responses are handled at the connect job level, so
3481 // the transaction does not yet have a connection.
3482 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3483
[email protected]49639fa2011-12-20 23:22:413484 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:593485
[email protected]49639fa2011-12-20 23:22:413486 rv = trans->RestartWithAuth(
3487 AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013488 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593489
3490 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013491 EXPECT_THAT(rv, IsOk());
[email protected]394816e92010-08-03 07:38:593492
3493 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523494 ASSERT_TRUE(response);
[email protected]394816e92010-08-03 07:38:593495
3496 EXPECT_TRUE(response->headers->IsKeepAlive());
3497 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:503498 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:593499 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3500
3501 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523502 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503503
[email protected]029c83b62013-01-24 05:28:203504 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3505 TestLoadTimingNotReusedWithPac(load_timing_info,
3506 CONNECT_TIMING_HAS_SSL_TIMES);
3507
[email protected]0b0bf032010-09-21 18:08:503508 trans.reset();
[email protected]102e27c2011-02-23 01:01:313509 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:593510}
3511
[email protected]11203f012009-11-12 23:02:313512// Test the request-challenge-retry sequence for basic auth, over a keep-alive
ttuttle34f63b52015-03-05 04:33:013513// proxy connection with HTTP/1.0 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013514TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
mmenked39192ee2015-12-09 00:57:233515 // On the second pass, the body read of the auth challenge is synchronous, so
3516 // IsConnectedAndIdle returns false. The socket should still be drained and
3517 // reused. See http://crbug.com/544255.
3518 for (int i = 0; i < 2; ++i) {
3519 HttpRequestInfo request;
3520 request.method = "GET";
3521 request.url = GURL("https://www.example.org/");
3522 // Ensure that proxy authentication is attempted even
3523 // when the no authentication data flag is set.
3524 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103525 request.traffic_annotation =
3526 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle34f63b52015-03-05 04:33:013527
mmenked39192ee2015-12-09 00:57:233528 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593529 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493530 ProxyResolutionService::CreateFixed("myproxy:70",
3531 TRAFFIC_ANNOTATION_FOR_TESTS);
mmenked39192ee2015-12-09 00:57:233532 BoundTestNetLog log;
3533 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093534 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013535
bnc691fda62016-08-12 00:43:163536 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013537
mmenked39192ee2015-12-09 00:57:233538 // Since we have proxy, should try to establish tunnel.
3539 MockWrite data_writes1[] = {
3540 MockWrite(ASYNC, 0,
3541 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3542 "Host: www.example.org:443\r\n"
3543 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013544
bnc691fda62016-08-12 00:43:163545 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233546 // be issuing -- the final header line contains the credentials.
3547 MockWrite(ASYNC, 3,
3548 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3549 "Host: www.example.org:443\r\n"
3550 "Proxy-Connection: keep-alive\r\n"
3551 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3552 };
ttuttle34f63b52015-03-05 04:33:013553
mmenked39192ee2015-12-09 00:57:233554 // The proxy responds to the connect with a 407, using a persistent
3555 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3556 MockRead data_reads1[] = {
3557 // No credentials.
3558 MockRead(ASYNC, 1,
3559 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3560 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3561 "Proxy-Connection: keep-alive\r\n"
3562 "Content-Length: 10\r\n\r\n"),
3563 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
ttuttle34f63b52015-03-05 04:33:013564
mmenked39192ee2015-12-09 00:57:233565 // Wrong credentials (wrong password).
3566 MockRead(ASYNC, 4,
3567 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3568 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3569 "Proxy-Connection: keep-alive\r\n"
3570 "Content-Length: 10\r\n\r\n"),
3571 // No response body because the test stops reading here.
3572 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3573 };
ttuttle34f63b52015-03-05 04:33:013574
Ryan Sleevib8d7ea02018-05-07 20:01:013575 SequencedSocketData data1(data_reads1, data_writes1);
mmenked39192ee2015-12-09 00:57:233576 data1.set_busy_before_sync_reads(true);
3577 session_deps_.socket_factory->AddSocketDataProvider(&data1);
ttuttle34f63b52015-03-05 04:33:013578
mmenked39192ee2015-12-09 00:57:233579 TestCompletionCallback callback1;
ttuttle34f63b52015-03-05 04:33:013580
bnc691fda62016-08-12 00:43:163581 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013582 EXPECT_THAT(callback1.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013583
mmenked39192ee2015-12-09 00:57:233584 TestNetLogEntry::List entries;
3585 log.GetEntries(&entries);
3586 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003587 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3588 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233589 ExpectLogContainsSomewhere(
3590 entries, pos,
mikecirone8b85c432016-09-08 19:11:003591 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3592 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013593
bnc691fda62016-08-12 00:43:163594 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233595 ASSERT_TRUE(response);
3596 ASSERT_TRUE(response->headers);
3597 EXPECT_TRUE(response->headers->IsKeepAlive());
3598 EXPECT_EQ(407, response->headers->response_code());
3599 EXPECT_EQ(10, response->headers->GetContentLength());
3600 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3601 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013602
mmenked39192ee2015-12-09 00:57:233603 TestCompletionCallback callback2;
ttuttle34f63b52015-03-05 04:33:013604
mmenked39192ee2015-12-09 00:57:233605 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163606 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3607 callback2.callback());
robpercival214763f2016-07-01 23:27:013608 EXPECT_THAT(callback2.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013609
bnc691fda62016-08-12 00:43:163610 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233611 ASSERT_TRUE(response);
3612 ASSERT_TRUE(response->headers);
3613 EXPECT_TRUE(response->headers->IsKeepAlive());
3614 EXPECT_EQ(407, response->headers->response_code());
3615 EXPECT_EQ(10, response->headers->GetContentLength());
3616 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3617 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013618
mmenked39192ee2015-12-09 00:57:233619 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3620 // out of scope.
3621 session->CloseAllConnections();
3622 }
ttuttle34f63b52015-03-05 04:33:013623}
3624
3625// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3626// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013627TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
mmenked39192ee2015-12-09 00:57:233628 // On the second pass, the body read of the auth challenge is synchronous, so
3629 // IsConnectedAndIdle returns false. The socket should still be drained and
3630 // reused. See http://crbug.com/544255.
3631 for (int i = 0; i < 2; ++i) {
3632 HttpRequestInfo request;
3633 request.method = "GET";
3634 request.url = GURL("https://www.example.org/");
3635 // Ensure that proxy authentication is attempted even
3636 // when the no authentication data flag is set.
3637 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103638 request.traffic_annotation =
3639 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenked39192ee2015-12-09 00:57:233640
3641 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593642 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493643 ProxyResolutionService::CreateFixed("myproxy:70",
3644 TRAFFIC_ANNOTATION_FOR_TESTS);
mmenked39192ee2015-12-09 00:57:233645 BoundTestNetLog log;
3646 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093647 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenked39192ee2015-12-09 00:57:233648
bnc691fda62016-08-12 00:43:163649 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenked39192ee2015-12-09 00:57:233650
3651 // Since we have proxy, should try to establish tunnel.
3652 MockWrite data_writes1[] = {
3653 MockWrite(ASYNC, 0,
3654 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3655 "Host: www.example.org:443\r\n"
3656 "Proxy-Connection: keep-alive\r\n\r\n"),
3657
bnc691fda62016-08-12 00:43:163658 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233659 // be issuing -- the final header line contains the credentials.
3660 MockWrite(ASYNC, 3,
3661 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3662 "Host: www.example.org:443\r\n"
3663 "Proxy-Connection: keep-alive\r\n"
3664 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3665 };
3666
3667 // The proxy responds to the connect with a 407, using a persistent
3668 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3669 MockRead data_reads1[] = {
3670 // No credentials.
3671 MockRead(ASYNC, 1,
3672 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3673 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3674 "Content-Length: 10\r\n\r\n"),
3675 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
3676
3677 // Wrong credentials (wrong password).
3678 MockRead(ASYNC, 4,
3679 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3680 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3681 "Content-Length: 10\r\n\r\n"),
3682 // No response body because the test stops reading here.
3683 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3684 };
3685
Ryan Sleevib8d7ea02018-05-07 20:01:013686 SequencedSocketData data1(data_reads1, data_writes1);
mmenked39192ee2015-12-09 00:57:233687 data1.set_busy_before_sync_reads(true);
3688 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3689
3690 TestCompletionCallback callback1;
3691
bnc691fda62016-08-12 00:43:163692 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013693 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233694
3695 TestNetLogEntry::List entries;
3696 log.GetEntries(&entries);
3697 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003698 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3699 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233700 ExpectLogContainsSomewhere(
3701 entries, pos,
mikecirone8b85c432016-09-08 19:11:003702 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3703 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233704
bnc691fda62016-08-12 00:43:163705 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233706 ASSERT_TRUE(response);
3707 ASSERT_TRUE(response->headers);
3708 EXPECT_TRUE(response->headers->IsKeepAlive());
3709 EXPECT_EQ(407, response->headers->response_code());
3710 EXPECT_EQ(10, response->headers->GetContentLength());
3711 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3712 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
Wojciech Dzierżanowski0950c372019-04-02 19:29:503713 EXPECT_FALSE(response->did_use_http_auth);
mmenked39192ee2015-12-09 00:57:233714
3715 TestCompletionCallback callback2;
3716
3717 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163718 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3719 callback2.callback());
robpercival214763f2016-07-01 23:27:013720 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233721
bnc691fda62016-08-12 00:43:163722 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233723 ASSERT_TRUE(response);
3724 ASSERT_TRUE(response->headers);
3725 EXPECT_TRUE(response->headers->IsKeepAlive());
3726 EXPECT_EQ(407, response->headers->response_code());
3727 EXPECT_EQ(10, response->headers->GetContentLength());
3728 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3729 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
Wojciech Dzierżanowski0950c372019-04-02 19:29:503730 EXPECT_TRUE(response->did_use_http_auth);
mmenked39192ee2015-12-09 00:57:233731
3732 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3733 // out of scope.
3734 session->CloseAllConnections();
3735 }
3736}
3737
3738// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3739// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel, in
3740// the case the server sends extra data on the original socket, so it can't be
3741// reused.
bncd16676a2016-07-20 16:23:013742TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveExtraData) {
[email protected]cb9bf6ca2011-01-28 13:15:273743 HttpRequestInfo request;
3744 request.method = "GET";
bncce36dca22015-04-21 22:11:233745 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273746 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293747 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103748 request.traffic_annotation =
3749 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:273750
[email protected]2d2697f92009-02-18 21:00:323751 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593752 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493753 ProxyResolutionService::CreateFixedFromPacResult(
3754 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513755 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073756 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093757 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:323758
[email protected]2d2697f92009-02-18 21:00:323759 // Since we have proxy, should try to establish tunnel.
3760 MockWrite data_writes1[] = {
mmenked39192ee2015-12-09 00:57:233761 MockWrite(ASYNC, 0,
3762 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173763 "Host: www.example.org:443\r\n"
3764 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233765 };
[email protected]2d2697f92009-02-18 21:00:323766
mmenked39192ee2015-12-09 00:57:233767 // The proxy responds to the connect with a 407, using a persistent, but sends
3768 // extra data, so the socket cannot be reused.
3769 MockRead data_reads1[] = {
3770 // No credentials.
3771 MockRead(ASYNC, 1,
3772 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3773 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3774 "Content-Length: 10\r\n\r\n"),
3775 MockRead(SYNCHRONOUS, 2, "0123456789"),
3776 MockRead(SYNCHRONOUS, 3, "I'm broken!"),
3777 };
3778
3779 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:233780 // After calling trans->RestartWithAuth(), this is the request we should
3781 // be issuing -- the final header line contains the credentials.
mmenked39192ee2015-12-09 00:57:233782 MockWrite(ASYNC, 0,
3783 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173784 "Host: www.example.org:443\r\n"
3785 "Proxy-Connection: keep-alive\r\n"
mmenked39192ee2015-12-09 00:57:233786 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3787
3788 MockWrite(ASYNC, 2,
3789 "GET / HTTP/1.1\r\n"
3790 "Host: www.example.org\r\n"
3791 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323792 };
3793
mmenked39192ee2015-12-09 00:57:233794 MockRead data_reads2[] = {
3795 MockRead(ASYNC, 1, "HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323796
mmenked39192ee2015-12-09 00:57:233797 MockRead(ASYNC, 3,
3798 "HTTP/1.1 200 OK\r\n"
3799 "Content-Type: text/html; charset=iso-8859-1\r\n"
3800 "Content-Length: 5\r\n\r\n"),
3801 // No response body because the test stops reading here.
3802 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 4),
[email protected]2d2697f92009-02-18 21:00:323803 };
3804
Ryan Sleevib8d7ea02018-05-07 20:01:013805 SequencedSocketData data1(data_reads1, data_writes1);
mmenked39192ee2015-12-09 00:57:233806 data1.set_busy_before_sync_reads(true);
[email protected]bb88e1d32013-05-03 23:11:073807 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:013808 SequencedSocketData data2(data_reads2, data_writes2);
mmenked39192ee2015-12-09 00:57:233809 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3810 SSLSocketDataProvider ssl(ASYNC, OK);
3811 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d2697f92009-02-18 21:00:323812
[email protected]49639fa2011-12-20 23:22:413813 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323814
bnc87dcefc2017-05-25 12:47:583815 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193816 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d2697f92009-02-18 21:00:323817
mmenked39192ee2015-12-09 00:57:233818 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013819 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233820
mmenke43758e62015-05-04 21:09:463821 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403822 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:393823 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003824 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3825 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:393826 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403827 entries, pos,
mikecirone8b85c432016-09-08 19:11:003828 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3829 NetLogEventPhase::NONE);
[email protected]2d2697f92009-02-18 21:00:323830
[email protected]1c773ea12009-04-28 19:58:423831 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243832 ASSERT_TRUE(response);
3833 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:323834 EXPECT_TRUE(response->headers->IsKeepAlive());
3835 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423836 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043837 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:323838
mmenked39192ee2015-12-09 00:57:233839 LoadTimingInfo load_timing_info;
3840 // CONNECT requests and responses are handled at the connect job level, so
3841 // the transaction does not yet have a connection.
3842 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3843
[email protected]49639fa2011-12-20 23:22:413844 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323845
mmenked39192ee2015-12-09 00:57:233846 rv =
3847 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013848 EXPECT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:323849
[email protected]2d2697f92009-02-18 21:00:323850 EXPECT_TRUE(response->headers->IsKeepAlive());
mmenked39192ee2015-12-09 00:57:233851 EXPECT_EQ(200, response->headers->response_code());
3852 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:423853 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]e772db3f2010-07-12 18:11:133854
mmenked39192ee2015-12-09 00:57:233855 // The password prompt info should not be set.
3856 EXPECT_FALSE(response->auth_challenge);
3857
3858 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3859 TestLoadTimingNotReusedWithPac(load_timing_info,
3860 CONNECT_TIMING_HAS_SSL_TIMES);
3861
3862 trans.reset();
[email protected]102e27c2011-02-23 01:01:313863 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:323864}
3865
mmenkee71e15332015-10-07 16:39:543866// Test the case a proxy closes a socket while the challenge body is being
3867// drained.
bncd16676a2016-07-20 16:23:013868TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHangupDuringBody) {
mmenkee71e15332015-10-07 16:39:543869 HttpRequestInfo request;
3870 request.method = "GET";
3871 request.url = GURL("https://www.example.org/");
3872 // Ensure that proxy authentication is attempted even
3873 // when the no authentication data flag is set.
3874 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103875 request.traffic_annotation =
3876 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenkee71e15332015-10-07 16:39:543877
3878 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:493879 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
3880 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:093881 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenkee71e15332015-10-07 16:39:543882
bnc691fda62016-08-12 00:43:163883 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkee71e15332015-10-07 16:39:543884
3885 // Since we have proxy, should try to establish tunnel.
3886 MockWrite data_writes1[] = {
3887 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173888 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543889 "Proxy-Connection: keep-alive\r\n\r\n"),
3890 };
3891
3892 // The proxy responds to the connect with a 407, using a persistent
3893 // connection.
3894 MockRead data_reads1[] = {
3895 // No credentials.
3896 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3897 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3898 MockRead("Content-Length: 10\r\n\r\n"), MockRead("spam!"),
3899 // Server hands up in the middle of the body.
3900 MockRead(ASYNC, ERR_CONNECTION_CLOSED),
3901 };
3902
3903 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:163904 // After calling trans.RestartWithAuth(), this is the request we should
mmenkee71e15332015-10-07 16:39:543905 // be issuing -- the final header line contains the credentials.
3906 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173907 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543908 "Proxy-Connection: keep-alive\r\n"
3909 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3910
3911 MockWrite("GET / HTTP/1.1\r\n"
3912 "Host: www.example.org\r\n"
3913 "Connection: keep-alive\r\n\r\n"),
3914 };
3915
3916 MockRead data_reads2[] = {
3917 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3918
3919 MockRead("HTTP/1.1 200 OK\r\n"),
3920 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3921 MockRead("Content-Length: 5\r\n\r\n"),
3922 MockRead(SYNCHRONOUS, "hello"),
3923 };
3924
Ryan Sleevib8d7ea02018-05-07 20:01:013925 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenkee71e15332015-10-07 16:39:543926 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:013927 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenkee71e15332015-10-07 16:39:543928 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3929 SSLSocketDataProvider ssl(ASYNC, OK);
3930 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3931
3932 TestCompletionCallback callback;
3933
tfarina42834112016-09-22 13:38:203934 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013935 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543936
bnc691fda62016-08-12 00:43:163937 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543938 ASSERT_TRUE(response);
3939 ASSERT_TRUE(response->headers);
3940 EXPECT_TRUE(response->headers->IsKeepAlive());
3941 EXPECT_EQ(407, response->headers->response_code());
3942 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3943
bnc691fda62016-08-12 00:43:163944 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
robpercival214763f2016-07-01 23:27:013945 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543946
bnc691fda62016-08-12 00:43:163947 response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543948 ASSERT_TRUE(response);
3949 ASSERT_TRUE(response->headers);
3950 EXPECT_TRUE(response->headers->IsKeepAlive());
3951 EXPECT_EQ(200, response->headers->response_code());
3952 std::string body;
bnc691fda62016-08-12 00:43:163953 EXPECT_THAT(ReadTransaction(&trans, &body), IsOk());
mmenkee71e15332015-10-07 16:39:543954 EXPECT_EQ("hello", body);
3955}
3956
[email protected]a8e9b162009-03-12 00:06:443957// Test that we don't read the response body when we fail to establish a tunnel,
3958// even if the user cancels the proxy's auth attempt.
bncd16676a2016-07-20 16:23:013959TEST_F(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:273960 HttpRequestInfo request;
3961 request.method = "GET";
bncce36dca22015-04-21 22:11:233962 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:103963 request.traffic_annotation =
3964 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:273965
[email protected]a8e9b162009-03-12 00:06:443966 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:493967 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
3968 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]a8e9b162009-03-12 00:06:443969
danakj1fd259a02016-04-16 03:17:093970 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:443971
bnc691fda62016-08-12 00:43:163972 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a8e9b162009-03-12 00:06:443973
[email protected]a8e9b162009-03-12 00:06:443974 // Since we have proxy, should try to establish tunnel.
3975 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173976 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3977 "Host: www.example.org:443\r\n"
3978 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:443979 };
3980
3981 // The proxy responds to the connect with a 407.
3982 MockRead data_reads[] = {
ttuttle7933c112015-01-06 00:55:243983 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3984 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3985 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233986 MockRead("0123456789"),
ttuttle7933c112015-01-06 00:55:243987 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]a8e9b162009-03-12 00:06:443988 };
3989
Ryan Sleevib8d7ea02018-05-07 20:01:013990 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:073991 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:443992
[email protected]49639fa2011-12-20 23:22:413993 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:443994
tfarina42834112016-09-22 13:38:203995 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013996 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a8e9b162009-03-12 00:06:443997
3998 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013999 EXPECT_THAT(rv, IsOk());
[email protected]a8e9b162009-03-12 00:06:444000
bnc691fda62016-08-12 00:43:164001 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:244002 ASSERT_TRUE(response);
4003 ASSERT_TRUE(response->headers);
[email protected]a8e9b162009-03-12 00:06:444004 EXPECT_TRUE(response->headers->IsKeepAlive());
4005 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:424006 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:444007
4008 std::string response_data;
bnc691fda62016-08-12 00:43:164009 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:014010 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]e60e47a2010-07-14 03:37:184011
4012 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:314013 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:444014}
4015
ttuttle7933c112015-01-06 00:55:244016// Test that we don't pass extraneous headers from the proxy's response to the
4017// caller when the proxy responds to CONNECT with 407.
bncd16676a2016-07-20 16:23:014018TEST_F(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
ttuttle7933c112015-01-06 00:55:244019 HttpRequestInfo request;
4020 request.method = "GET";
bncce36dca22015-04-21 22:11:234021 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104022 request.traffic_annotation =
4023 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle7933c112015-01-06 00:55:244024
4025 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:494026 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
4027 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle7933c112015-01-06 00:55:244028
danakj1fd259a02016-04-16 03:17:094029 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle7933c112015-01-06 00:55:244030
bnc691fda62016-08-12 00:43:164031 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle7933c112015-01-06 00:55:244032
4033 // Since we have proxy, should try to establish tunnel.
4034 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:174035 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4036 "Host: www.example.org:443\r\n"
4037 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle7933c112015-01-06 00:55:244038 };
4039
4040 // The proxy responds to the connect with a 407.
4041 MockRead data_reads[] = {
4042 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4043 MockRead("X-Foo: bar\r\n"),
4044 MockRead("Set-Cookie: foo=bar\r\n"),
4045 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4046 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:234047 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
ttuttle7933c112015-01-06 00:55:244048 };
4049
Ryan Sleevib8d7ea02018-05-07 20:01:014050 StaticSocketDataProvider data(data_reads, data_writes);
ttuttle7933c112015-01-06 00:55:244051 session_deps_.socket_factory->AddSocketDataProvider(&data);
4052
4053 TestCompletionCallback callback;
4054
tfarina42834112016-09-22 13:38:204055 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014056 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle7933c112015-01-06 00:55:244057
4058 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:014059 EXPECT_THAT(rv, IsOk());
ttuttle7933c112015-01-06 00:55:244060
bnc691fda62016-08-12 00:43:164061 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:244062 ASSERT_TRUE(response);
4063 ASSERT_TRUE(response->headers);
4064 EXPECT_TRUE(response->headers->IsKeepAlive());
4065 EXPECT_EQ(407, response->headers->response_code());
4066 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4067 EXPECT_FALSE(response->headers->HasHeader("X-Foo"));
4068 EXPECT_FALSE(response->headers->HasHeader("Set-Cookie"));
4069
4070 std::string response_data;
bnc691fda62016-08-12 00:43:164071 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:014072 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
ttuttle7933c112015-01-06 00:55:244073
4074 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
4075 session->CloseAllConnections();
4076}
4077
[email protected]8fdbcd22010-05-05 02:54:524078// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
4079// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
bncd16676a2016-07-20 16:23:014080TEST_F(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:524081 HttpRequestInfo request;
4082 request.method = "GET";
bncce36dca22015-04-21 22:11:234083 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104084 request.traffic_annotation =
4085 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8fdbcd22010-05-05 02:54:524086
[email protected]cb9bf6ca2011-01-28 13:15:274087 // We are using a DIRECT connection (i.e. no proxy) for this session.
danakj1fd259a02016-04-16 03:17:094088 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:164089 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:274090
[email protected]8fdbcd22010-05-05 02:54:524091 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:234092 MockWrite(
4093 "GET / HTTP/1.1\r\n"
4094 "Host: www.example.org\r\n"
4095 "Connection: keep-alive\r\n\r\n"),
[email protected]8fdbcd22010-05-05 02:54:524096 };
4097
4098 MockRead data_reads1[] = {
4099 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
4100 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4101 // Large content-length -- won't matter, as connection will be reset.
4102 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064103 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:524104 };
4105
Ryan Sleevib8d7ea02018-05-07 20:01:014106 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:074107 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:524108
[email protected]49639fa2011-12-20 23:22:414109 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:524110
tfarina42834112016-09-22 13:38:204111 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014112 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8fdbcd22010-05-05 02:54:524113
4114 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:014115 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
[email protected]8fdbcd22010-05-05 02:54:524116}
4117
[email protected]7a67a8152010-11-05 18:31:104118// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
4119// through a non-authenticating proxy. The request should fail with
4120// ERR_UNEXPECTED_PROXY_AUTH.
4121// Note that it is impossible to detect if an HTTP server returns a 407 through
4122// a non-authenticating proxy - there is nothing to indicate whether the
4123// response came from the proxy or the server, so it is treated as if the proxy
4124// issued the challenge.
bncd16676a2016-07-20 16:23:014125TEST_F(HttpNetworkTransactionTest, HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:274126 HttpRequestInfo request;
4127 request.method = "GET";
bncce36dca22015-04-21 22:11:234128 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104129 request.traffic_annotation =
4130 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:274131
Ramin Halavatica8d5252018-03-12 05:33:494132 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
4133 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:514134 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074135 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094136 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:104137
[email protected]7a67a8152010-11-05 18:31:104138 // Since we have proxy, should try to establish tunnel.
4139 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174140 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4141 "Host: www.example.org:443\r\n"
4142 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:104143
rsleevidb16bb02015-11-12 23:47:174144 MockWrite("GET / HTTP/1.1\r\n"
4145 "Host: www.example.org\r\n"
4146 "Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:104147 };
4148
4149 MockRead data_reads1[] = {
4150 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4151
4152 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
4153 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4154 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:064155 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:104156 };
4157
Ryan Sleevib8d7ea02018-05-07 20:01:014158 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:074159 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:064160 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074161 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:104162
[email protected]49639fa2011-12-20 23:22:414163 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:104164
bnc691fda62016-08-12 00:43:164165 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]7a67a8152010-11-05 18:31:104166
bnc691fda62016-08-12 00:43:164167 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014168 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a67a8152010-11-05 18:31:104169
4170 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014171 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
mmenke43758e62015-05-04 21:09:464172 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:404173 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:104174 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:004175 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
4176 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:104177 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:404178 entries, pos,
mikecirone8b85c432016-09-08 19:11:004179 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
4180 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:104181}
[email protected]2df19bb2010-08-25 20:13:464182
mmenke2a1781d2015-10-07 19:25:334183// Test a proxy auth scheme that allows default credentials and a proxy server
4184// that uses non-persistent connections.
bncd16676a2016-07-20 16:23:014185TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334186 AuthAllowsDefaultCredentialsTunnelConnectionClose) {
4187 HttpRequestInfo request;
4188 request.method = "GET";
4189 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104190 request.traffic_annotation =
4191 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334192
4193 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594194 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494195 ProxyResolutionService::CreateFixedFromPacResult(
4196 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334197
Jeremy Roman0579ed62017-08-29 15:56:194198 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334199 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194200 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334201 mock_handler->set_allows_default_credentials(true);
4202 auth_handler_factory->AddMockHandler(mock_handler.release(),
4203 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484204 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334205
4206 // Add NetLog just so can verify load timing information gets a NetLog ID.
4207 NetLog net_log;
4208 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094209 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334210
4211 // Since we have proxy, should try to establish tunnel.
4212 MockWrite data_writes1[] = {
4213 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174214 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334215 "Proxy-Connection: keep-alive\r\n\r\n"),
4216 };
4217
4218 // The proxy responds to the connect with a 407, using a non-persistent
4219 // connection.
4220 MockRead data_reads1[] = {
4221 // No credentials.
4222 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4223 MockRead("Proxy-Authenticate: Mock\r\n"),
4224 MockRead("Proxy-Connection: close\r\n\r\n"),
4225 };
4226
4227 // Since the first connection couldn't be reused, need to establish another
4228 // once given credentials.
4229 MockWrite data_writes2[] = {
4230 // After calling trans->RestartWithAuth(), this is the request we should
4231 // be issuing -- the final header line contains the credentials.
4232 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174233 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334234 "Proxy-Connection: keep-alive\r\n"
4235 "Proxy-Authorization: auth_token\r\n\r\n"),
4236
4237 MockWrite("GET / HTTP/1.1\r\n"
4238 "Host: www.example.org\r\n"
4239 "Connection: keep-alive\r\n\r\n"),
4240 };
4241
4242 MockRead data_reads2[] = {
4243 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
4244
4245 MockRead("HTTP/1.1 200 OK\r\n"),
4246 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4247 MockRead("Content-Length: 5\r\n\r\n"),
4248 MockRead(SYNCHRONOUS, "hello"),
4249 };
4250
Ryan Sleevib8d7ea02018-05-07 20:01:014251 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke2a1781d2015-10-07 19:25:334252 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:014253 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke2a1781d2015-10-07 19:25:334254 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4255 SSLSocketDataProvider ssl(ASYNC, OK);
4256 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4257
bnc87dcefc2017-05-25 12:47:584258 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194259 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334260
4261 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204262 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014263 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334264
4265 const HttpResponseInfo* response = trans->GetResponseInfo();
4266 ASSERT_TRUE(response);
4267 ASSERT_TRUE(response->headers);
4268 EXPECT_FALSE(response->headers->IsKeepAlive());
4269 EXPECT_EQ(407, response->headers->response_code());
4270 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4271 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
wezca1070932016-05-26 20:30:524272 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:334273
4274 LoadTimingInfo load_timing_info;
4275 // CONNECT requests and responses are handled at the connect job level, so
4276 // the transaction does not yet have a connection.
4277 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4278
4279 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014280 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334281 response = trans->GetResponseInfo();
4282 ASSERT_TRUE(response);
4283 ASSERT_TRUE(response->headers);
4284 EXPECT_TRUE(response->headers->IsKeepAlive());
4285 EXPECT_EQ(200, response->headers->response_code());
4286 EXPECT_EQ(5, response->headers->GetContentLength());
4287 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4288
4289 // The password prompt info should not be set.
4290 EXPECT_FALSE(response->auth_challenge);
4291
4292 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4293 TestLoadTimingNotReusedWithPac(load_timing_info,
4294 CONNECT_TIMING_HAS_SSL_TIMES);
4295
4296 trans.reset();
4297 session->CloseAllConnections();
4298}
4299
4300// Test a proxy auth scheme that allows default credentials and a proxy server
4301// that hangs up when credentials are initially sent.
bncd16676a2016-07-20 16:23:014302TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334303 AuthAllowsDefaultCredentialsTunnelServerClosesConnection) {
4304 HttpRequestInfo request;
4305 request.method = "GET";
4306 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104307 request.traffic_annotation =
4308 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334309
4310 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594311 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494312 ProxyResolutionService::CreateFixedFromPacResult(
4313 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334314
Jeremy Roman0579ed62017-08-29 15:56:194315 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334316 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194317 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334318 mock_handler->set_allows_default_credentials(true);
4319 auth_handler_factory->AddMockHandler(mock_handler.release(),
4320 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484321 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334322
4323 // Add NetLog just so can verify load timing information gets a NetLog ID.
4324 NetLog net_log;
4325 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094326 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334327
4328 // Should try to establish tunnel.
4329 MockWrite data_writes1[] = {
4330 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174331 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334332 "Proxy-Connection: keep-alive\r\n\r\n"),
4333
4334 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174335 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334336 "Proxy-Connection: keep-alive\r\n"
4337 "Proxy-Authorization: auth_token\r\n\r\n"),
4338 };
4339
4340 // The proxy responds to the connect with a 407, using a non-persistent
4341 // connection.
4342 MockRead data_reads1[] = {
4343 // No credentials.
4344 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4345 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4346 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4347 };
4348
4349 // Since the first connection was closed, need to establish another once given
4350 // credentials.
4351 MockWrite data_writes2[] = {
4352 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174353 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334354 "Proxy-Connection: keep-alive\r\n"
4355 "Proxy-Authorization: auth_token\r\n\r\n"),
4356
4357 MockWrite("GET / HTTP/1.1\r\n"
4358 "Host: www.example.org\r\n"
4359 "Connection: keep-alive\r\n\r\n"),
4360 };
4361
4362 MockRead data_reads2[] = {
4363 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
4364
4365 MockRead("HTTP/1.1 200 OK\r\n"),
4366 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4367 MockRead("Content-Length: 5\r\n\r\n"),
4368 MockRead(SYNCHRONOUS, "hello"),
4369 };
4370
Ryan Sleevib8d7ea02018-05-07 20:01:014371 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke2a1781d2015-10-07 19:25:334372 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:014373 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke2a1781d2015-10-07 19:25:334374 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4375 SSLSocketDataProvider ssl(ASYNC, OK);
4376 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4377
bnc87dcefc2017-05-25 12:47:584378 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194379 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334380
4381 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204382 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014383 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334384
4385 const HttpResponseInfo* response = trans->GetResponseInfo();
4386 ASSERT_TRUE(response);
4387 ASSERT_TRUE(response->headers);
4388 EXPECT_TRUE(response->headers->IsKeepAlive());
4389 EXPECT_EQ(407, response->headers->response_code());
4390 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4391 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4392 EXPECT_FALSE(response->auth_challenge);
4393
4394 LoadTimingInfo load_timing_info;
4395 // CONNECT requests and responses are handled at the connect job level, so
4396 // the transaction does not yet have a connection.
4397 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4398
4399 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014400 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334401
4402 response = trans->GetResponseInfo();
4403 ASSERT_TRUE(response);
4404 ASSERT_TRUE(response->headers);
4405 EXPECT_TRUE(response->headers->IsKeepAlive());
4406 EXPECT_EQ(200, response->headers->response_code());
4407 EXPECT_EQ(5, response->headers->GetContentLength());
4408 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4409
4410 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524411 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:334412
4413 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4414 TestLoadTimingNotReusedWithPac(load_timing_info,
4415 CONNECT_TIMING_HAS_SSL_TIMES);
4416
4417 trans.reset();
4418 session->CloseAllConnections();
4419}
4420
4421// Test a proxy auth scheme that allows default credentials and a proxy server
4422// that hangs up when credentials are initially sent, and hangs up again when
4423// they are retried.
bncd16676a2016-07-20 16:23:014424TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334425 AuthAllowsDefaultCredentialsTunnelServerClosesConnectionTwice) {
4426 HttpRequestInfo request;
4427 request.method = "GET";
4428 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104429 request.traffic_annotation =
4430 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334431
4432 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594433 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494434 ProxyResolutionService::CreateFixedFromPacResult(
4435 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334436
Jeremy Roman0579ed62017-08-29 15:56:194437 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334438 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194439 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334440 mock_handler->set_allows_default_credentials(true);
4441 auth_handler_factory->AddMockHandler(mock_handler.release(),
4442 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484443 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334444
4445 // Add NetLog just so can verify load timing information gets a NetLog ID.
4446 NetLog net_log;
4447 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094448 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334449
4450 // Should try to establish tunnel.
4451 MockWrite data_writes1[] = {
4452 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174453 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334454 "Proxy-Connection: keep-alive\r\n\r\n"),
4455
4456 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174457 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334458 "Proxy-Connection: keep-alive\r\n"
4459 "Proxy-Authorization: auth_token\r\n\r\n"),
4460 };
4461
4462 // The proxy responds to the connect with a 407, and then hangs up after the
4463 // second request is sent.
4464 MockRead data_reads1[] = {
4465 // No credentials.
4466 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4467 MockRead("Content-Length: 0\r\n"),
4468 MockRead("Proxy-Connection: keep-alive\r\n"),
4469 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4470 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4471 };
4472
4473 // HttpNetworkTransaction sees a reused connection that was closed with
4474 // ERR_CONNECTION_CLOSED, realized it might have been a race, so retries the
4475 // request.
4476 MockWrite data_writes2[] = {
4477 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174478 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334479 "Proxy-Connection: keep-alive\r\n\r\n"),
4480 };
4481
4482 // The proxy, having had more than enough of us, just hangs up.
4483 MockRead data_reads2[] = {
4484 // No credentials.
4485 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4486 };
4487
Ryan Sleevib8d7ea02018-05-07 20:01:014488 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke2a1781d2015-10-07 19:25:334489 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:014490 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke2a1781d2015-10-07 19:25:334491 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4492
bnc87dcefc2017-05-25 12:47:584493 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194494 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334495
4496 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204497 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014498 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334499
4500 const HttpResponseInfo* response = trans->GetResponseInfo();
4501 ASSERT_TRUE(response);
4502 ASSERT_TRUE(response->headers);
4503 EXPECT_TRUE(response->headers->IsKeepAlive());
4504 EXPECT_EQ(407, response->headers->response_code());
4505 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4506 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4507 EXPECT_FALSE(response->auth_challenge);
4508
4509 LoadTimingInfo load_timing_info;
4510 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4511
4512 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014513 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_EMPTY_RESPONSE));
mmenke2a1781d2015-10-07 19:25:334514
4515 trans.reset();
4516 session->CloseAllConnections();
4517}
4518
Asanka Herathbc3f8f62018-11-16 23:08:304519// This test exercises an odd edge case where the proxy closes the connection
4520// after the authentication handshake is complete. Presumably this technique is
4521// used in lieu of returning a 403 or 5xx status code when the authentication
4522// succeeds, but the user is not authorized to connect to the destination
4523// server. There's no standard for what a proxy should do to indicate a blocked
4524// site.
4525TEST_F(HttpNetworkTransactionTest,
4526 AuthAllowsDefaultCredentialsTunnelConnectionClosesBeforeBody) {
4527 HttpRequestInfo request;
4528 request.method = "GET";
4529 request.url = GURL("https://www.example.org/");
4530 request.traffic_annotation =
4531 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4532
4533 // Configure against proxy server "myproxy:70".
4534 session_deps_.proxy_resolution_service =
4535 ProxyResolutionService::CreateFixedFromPacResult(
4536 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
4537
Steven Valdez0ef94d02018-11-19 23:28:134538 // When TLS 1.3 is enabled, spurious connections are made as part of the SSL
4539 // version interference probes.
4540 // TODO(crbug.com/906668): Correctly handle version interference probes to
4541 // test TLS 1.3.
4542 SSLConfig config;
4543 config.version_max = SSL_PROTOCOL_VERSION_TLS1_2;
4544 session_deps_.ssl_config_service =
4545 std::make_unique<TestSSLConfigService>(config);
4546
Asanka Herathbc3f8f62018-11-16 23:08:304547 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
4548 auth_handler_factory->set_do_init_from_challenge(true);
4549
4550 // Create two mock AuthHandlers. This is because the transaction gets retried
4551 // after the first ERR_CONNECTION_CLOSED since it's ambiguous whether there
4552 // was a real network error.
4553 //
4554 // The handlers support both default and explicit credentials. The retry
4555 // mentioned above should be able to reuse the default identity. Thus there
4556 // should never be a need to prompt for explicit credentials.
4557 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
4558 mock_handler->set_allows_default_credentials(true);
4559 mock_handler->set_allows_explicit_credentials(true);
4560 mock_handler->set_connection_based(true);
4561 auth_handler_factory->AddMockHandler(mock_handler.release(),
4562 HttpAuth::AUTH_PROXY);
4563 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 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
4570
4571 NetLog net_log;
4572 session_deps_.net_log = &net_log;
4573 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4574
4575 // Data for both sockets.
4576 //
4577 // Writes are for the tunnel establishment attempts and the
4578 // authentication handshake.
4579 MockWrite data_writes1[] = {
4580 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4581 "Host: www.example.org:443\r\n"
4582 "Proxy-Connection: keep-alive\r\n\r\n"),
4583
4584 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4585 "Host: www.example.org:443\r\n"
4586 "Proxy-Connection: keep-alive\r\n"
4587 "Proxy-Authorization: auth_token\r\n\r\n"),
4588
4589 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4590 "Host: www.example.org:443\r\n"
4591 "Proxy-Connection: keep-alive\r\n"
4592 "Proxy-Authorization: auth_token\r\n\r\n"),
4593 };
4594
4595 // The server side of the authentication handshake. Note that the response to
4596 // the final CONNECT request is ERR_CONNECTION_CLOSED.
4597 MockRead data_reads1[] = {
4598 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4599 MockRead("Content-Length: 0\r\n"),
4600 MockRead("Proxy-Connection: keep-alive\r\n"),
4601 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4602
4603 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4604 MockRead("Content-Length: 0\r\n"),
4605 MockRead("Proxy-Connection: keep-alive\r\n"),
4606 MockRead("Proxy-Authenticate: Mock foo\r\n\r\n"),
4607
4608 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4609 };
4610
4611 StaticSocketDataProvider data1(data_reads1, data_writes1);
4612 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4613
4614 // The second socket is for the reconnection attempt. Data is identical to the
4615 // first attempt.
4616 StaticSocketDataProvider data2(data_reads1, data_writes1);
4617 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4618
4619 auto trans =
4620 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
4621
4622 TestCompletionCallback callback;
4623 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4624
4625 // Two rounds per handshake. After one retry, the error is propagated up the
4626 // stack.
4627 for (int i = 0; i < 4; ++i) {
4628 EXPECT_THAT(callback.GetResult(rv), IsOk());
4629
4630 const HttpResponseInfo* response = trans->GetResponseInfo();
4631 ASSERT_TRUE(response);
4632 ASSERT_TRUE(response->headers);
4633 EXPECT_EQ(407, response->headers->response_code());
4634 ASSERT_TRUE(trans->IsReadyToRestartForAuth());
4635
4636 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4637 }
4638
4639 // One shall be the number thou shalt retry, and the number of the retrying
4640 // shall be one. Two shalt thou not retry, neither retry thou zero, excepting
4641 // that thou then proceed to one. Three is right out. Once the number one,
4642 // being the first number, be reached, then lobbest thou thy
4643 // ERR_CONNECTION_CLOSED towards they network transaction, who shall snuff it.
4644 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.GetResult(rv));
4645
4646 trans.reset();
4647 session->CloseAllConnections();
4648}
4649
mmenke2a1781d2015-10-07 19:25:334650// Test a proxy auth scheme that allows default credentials and a proxy server
4651// that hangs up when credentials are initially sent, and sends a challenge
4652// again they are retried.
bncd16676a2016-07-20 16:23:014653TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334654 AuthAllowsDefaultCredentialsTunnelServerChallengesTwice) {
4655 HttpRequestInfo request;
4656 request.method = "GET";
4657 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104658 request.traffic_annotation =
4659 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334660
4661 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594662 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494663 ProxyResolutionService::CreateFixedFromPacResult(
4664 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334665
Jeremy Roman0579ed62017-08-29 15:56:194666 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334667 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194668 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334669 mock_handler->set_allows_default_credentials(true);
4670 auth_handler_factory->AddMockHandler(mock_handler.release(),
4671 HttpAuth::AUTH_PROXY);
4672 // Add another handler for the second challenge. It supports default
4673 // credentials, but they shouldn't be used, since they were already tried.
Jeremy Roman0579ed62017-08-29 15:56:194674 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);
dchengc7eeda422015-12-26 03:56:484678 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334679
4680 // Add NetLog just so can verify load timing information gets a NetLog ID.
4681 NetLog net_log;
4682 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094683 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334684
4685 // Should try to establish tunnel.
4686 MockWrite data_writes1[] = {
4687 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174688 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334689 "Proxy-Connection: keep-alive\r\n\r\n"),
4690 };
4691
4692 // The proxy responds to the connect with a 407, using a non-persistent
4693 // connection.
4694 MockRead data_reads1[] = {
4695 // No credentials.
4696 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4697 MockRead("Proxy-Authenticate: Mock\r\n"),
4698 MockRead("Proxy-Connection: close\r\n\r\n"),
4699 };
4700
4701 // Since the first connection was closed, need to establish another once given
4702 // credentials.
4703 MockWrite data_writes2[] = {
4704 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174705 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334706 "Proxy-Connection: keep-alive\r\n"
4707 "Proxy-Authorization: auth_token\r\n\r\n"),
4708 };
4709
4710 MockRead data_reads2[] = {
4711 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4712 MockRead("Proxy-Authenticate: Mock\r\n"),
4713 MockRead("Proxy-Connection: close\r\n\r\n"),
4714 };
4715
Ryan Sleevib8d7ea02018-05-07 20:01:014716 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke2a1781d2015-10-07 19:25:334717 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:014718 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke2a1781d2015-10-07 19:25:334719 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4720 SSLSocketDataProvider ssl(ASYNC, OK);
4721 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4722
bnc87dcefc2017-05-25 12:47:584723 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194724 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334725
4726 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204727 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014728 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334729
4730 const HttpResponseInfo* response = trans->GetResponseInfo();
4731 ASSERT_TRUE(response);
4732 ASSERT_TRUE(response->headers);
4733 EXPECT_EQ(407, response->headers->response_code());
4734 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4735 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4736 EXPECT_FALSE(response->auth_challenge);
4737
4738 LoadTimingInfo load_timing_info;
4739 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4740
4741 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014742 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334743 response = trans->GetResponseInfo();
4744 ASSERT_TRUE(response);
4745 ASSERT_TRUE(response->headers);
4746 EXPECT_EQ(407, response->headers->response_code());
4747 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4748 EXPECT_TRUE(response->auth_challenge);
4749
4750 trans.reset();
4751 session->CloseAllConnections();
4752}
4753
asankae2257db2016-10-11 22:03:164754// A more nuanced test than GenerateAuthToken test which asserts that
4755// ERR_INVALID_AUTH_CREDENTIALS does not cause the auth scheme to be
4756// unnecessarily invalidated, and that if the server co-operates, the
4757// authentication handshake can continue with the same scheme but with a
4758// different identity.
4759TEST_F(HttpNetworkTransactionTest, NonPermanentGenerateAuthTokenError) {
4760 HttpRequestInfo request;
4761 request.method = "GET";
4762 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104763 request.traffic_annotation =
4764 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
asankae2257db2016-10-11 22:03:164765
Jeremy Roman0579ed62017-08-29 15:56:194766 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
asankae2257db2016-10-11 22:03:164767 auth_handler_factory->set_do_init_from_challenge(true);
4768
4769 // First handler. Uses default credentials, but barfs at generate auth token.
Jeremy Roman0579ed62017-08-29 15:56:194770 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164771 mock_handler->set_allows_default_credentials(true);
4772 mock_handler->set_allows_explicit_credentials(true);
4773 mock_handler->set_connection_based(true);
4774 mock_handler->SetGenerateExpectation(true, ERR_INVALID_AUTH_CREDENTIALS);
4775 auth_handler_factory->AddMockHandler(mock_handler.release(),
4776 HttpAuth::AUTH_SERVER);
4777
4778 // Add another handler for the second challenge. It supports default
4779 // credentials, but they shouldn't be used, since they were already tried.
Jeremy Roman0579ed62017-08-29 15:56:194780 mock_handler = std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164781 mock_handler->set_allows_default_credentials(true);
4782 mock_handler->set_allows_explicit_credentials(true);
4783 mock_handler->set_connection_based(true);
4784 auth_handler_factory->AddMockHandler(mock_handler.release(),
4785 HttpAuth::AUTH_SERVER);
4786 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
4787
4788 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4789
4790 MockWrite data_writes1[] = {
4791 MockWrite("GET / HTTP/1.1\r\n"
4792 "Host: www.example.org\r\n"
4793 "Connection: keep-alive\r\n\r\n"),
4794 };
4795
4796 MockRead data_reads1[] = {
4797 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4798 "WWW-Authenticate: Mock\r\n"
4799 "Connection: keep-alive\r\n\r\n"),
4800 };
4801
4802 // Identical to data_writes1[]. The AuthHandler encounters a
4803 // ERR_INVALID_AUTH_CREDENTIALS during the GenerateAuthToken stage, so the
4804 // transaction procceds without an authorization header.
4805 MockWrite data_writes2[] = {
4806 MockWrite("GET / HTTP/1.1\r\n"
4807 "Host: www.example.org\r\n"
4808 "Connection: keep-alive\r\n\r\n"),
4809 };
4810
4811 MockRead data_reads2[] = {
4812 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4813 "WWW-Authenticate: Mock\r\n"
4814 "Connection: keep-alive\r\n\r\n"),
4815 };
4816
4817 MockWrite data_writes3[] = {
4818 MockWrite("GET / HTTP/1.1\r\n"
4819 "Host: www.example.org\r\n"
4820 "Connection: keep-alive\r\n"
4821 "Authorization: auth_token\r\n\r\n"),
4822 };
4823
4824 MockRead data_reads3[] = {
4825 MockRead("HTTP/1.1 200 OK\r\n"
4826 "Content-Length: 5\r\n"
4827 "Content-Type: text/plain\r\n"
4828 "Connection: keep-alive\r\n\r\n"
4829 "Hello"),
4830 };
4831
Ryan Sleevib8d7ea02018-05-07 20:01:014832 StaticSocketDataProvider data1(data_reads1, data_writes1);
asankae2257db2016-10-11 22:03:164833 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4834
Ryan Sleevib8d7ea02018-05-07 20:01:014835 StaticSocketDataProvider data2(data_reads2, data_writes2);
asankae2257db2016-10-11 22:03:164836 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4837
Ryan Sleevib8d7ea02018-05-07 20:01:014838 StaticSocketDataProvider data3(data_reads3, data_writes3);
asankae2257db2016-10-11 22:03:164839 session_deps_.socket_factory->AddSocketDataProvider(&data3);
4840
bnc87dcefc2017-05-25 12:47:584841 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194842 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
asankae2257db2016-10-11 22:03:164843
4844 TestCompletionCallback callback;
4845 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4846 EXPECT_THAT(callback.GetResult(rv), IsOk());
4847
4848 const HttpResponseInfo* response = trans->GetResponseInfo();
4849 ASSERT_TRUE(response);
4850 ASSERT_TRUE(response->headers);
4851 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4852
4853 // The following three tests assert that an authentication challenge was
4854 // received and that the stack is ready to respond to the challenge using
4855 // ambient credentials.
4856 EXPECT_EQ(401, response->headers->response_code());
4857 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4858 EXPECT_FALSE(response->auth_challenge);
4859
4860 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4861 EXPECT_THAT(callback.GetResult(rv), IsOk());
4862 response = trans->GetResponseInfo();
4863 ASSERT_TRUE(response);
4864 ASSERT_TRUE(response->headers);
4865
4866 // The following three tests assert that an authentication challenge was
4867 // received and that the stack needs explicit credentials before it is ready
4868 // to respond to the challenge.
4869 EXPECT_EQ(401, response->headers->response_code());
4870 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4871 EXPECT_TRUE(response->auth_challenge);
4872
4873 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4874 EXPECT_THAT(callback.GetResult(rv), IsOk());
4875 response = trans->GetResponseInfo();
4876 ASSERT_TRUE(response);
4877 ASSERT_TRUE(response->headers);
4878 EXPECT_EQ(200, response->headers->response_code());
4879
4880 trans.reset();
4881 session->CloseAllConnections();
4882}
4883
Matt Menked1eb6d42018-01-17 04:54:064884// Proxy resolver that returns a proxy with the same host and port for different
4885// schemes, based on the path of the URL being requests.
4886class SameProxyWithDifferentSchemesProxyResolver : public ProxyResolver {
4887 public:
4888 SameProxyWithDifferentSchemesProxyResolver() {}
4889 ~SameProxyWithDifferentSchemesProxyResolver() override {}
4890
4891 static std::string ProxyHostPortPairAsString() { return "proxy.test:10000"; }
4892
4893 static HostPortPair ProxyHostPortPair() {
4894 return HostPortPair::FromString(ProxyHostPortPairAsString());
4895 }
4896
4897 // ProxyResolver implementation.
4898 int GetProxyForURL(const GURL& url,
4899 ProxyInfo* results,
Bence Békycc5b88a2018-05-25 20:24:174900 CompletionOnceCallback callback,
Matt Menked1eb6d42018-01-17 04:54:064901 std::unique_ptr<Request>* request,
4902 const NetLogWithSource& /*net_log*/) override {
4903 *results = ProxyInfo();
Ramin Halavati921731ea2018-03-16 08:24:574904 results->set_traffic_annotation(
4905 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
Matt Menked1eb6d42018-01-17 04:54:064906 if (url.path() == "/socks4") {
4907 results->UsePacString("SOCKS " + ProxyHostPortPairAsString());
4908 return OK;
4909 }
4910 if (url.path() == "/socks5") {
4911 results->UsePacString("SOCKS5 " + ProxyHostPortPairAsString());
4912 return OK;
4913 }
4914 if (url.path() == "/http") {
4915 results->UsePacString("PROXY " + ProxyHostPortPairAsString());
4916 return OK;
4917 }
4918 if (url.path() == "/https") {
4919 results->UsePacString("HTTPS " + ProxyHostPortPairAsString());
4920 return OK;
4921 }
Matt Menkee8648fa2019-01-17 16:47:074922 if (url.path() == "/https_trusted") {
4923 results->UseProxyServer(ProxyServer(ProxyServer::SCHEME_HTTPS,
4924 ProxyHostPortPair(),
4925 true /* is_trusted_proxy */));
4926 return OK;
4927 }
Matt Menked1eb6d42018-01-17 04:54:064928 NOTREACHED();
4929 return ERR_NOT_IMPLEMENTED;
4930 }
4931
4932 private:
4933 DISALLOW_COPY_AND_ASSIGN(SameProxyWithDifferentSchemesProxyResolver);
4934};
4935
4936class SameProxyWithDifferentSchemesProxyResolverFactory
4937 : public ProxyResolverFactory {
4938 public:
4939 SameProxyWithDifferentSchemesProxyResolverFactory()
4940 : ProxyResolverFactory(false) {}
4941
Lily Houghton99597862018-03-07 16:40:424942 int CreateProxyResolver(const scoped_refptr<PacFileData>& pac_script,
4943 std::unique_ptr<ProxyResolver>* resolver,
Bence Békycc5b88a2018-05-25 20:24:174944 CompletionOnceCallback callback,
Lily Houghton99597862018-03-07 16:40:424945 std::unique_ptr<Request>* request) override {
Matt Menked1eb6d42018-01-17 04:54:064946 *resolver = std::make_unique<SameProxyWithDifferentSchemesProxyResolver>();
4947 return OK;
4948 }
4949
4950 private:
4951 DISALLOW_COPY_AND_ASSIGN(SameProxyWithDifferentSchemesProxyResolverFactory);
4952};
4953
4954// Check that when different proxy schemes are all applied to a proxy at the
Matt Menkee8648fa2019-01-17 16:47:074955// same address, the connections are not grouped together. i.e., a request to
Matt Menked1eb6d42018-01-17 04:54:064956// foo.com using proxy.com as an HTTPS proxy won't use the same socket as a
4957// request to foo.com using proxy.com as an HTTP proxy.
4958TEST_F(HttpNetworkTransactionTest, SameDestinationForDifferentProxyTypes) {
Ramin Halavatica8d5252018-03-12 05:33:494959 session_deps_.proxy_resolution_service =
4960 std::make_unique<ProxyResolutionService>(
4961 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
4962 ProxyConfig::CreateAutoDetect(), TRAFFIC_ANNOTATION_FOR_TESTS)),
4963 std::make_unique<SameProxyWithDifferentSchemesProxyResolverFactory>(),
4964 nullptr);
Matt Menked1eb6d42018-01-17 04:54:064965
4966 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4967
4968 MockWrite socks_writes[] = {
4969 MockWrite(SYNCHRONOUS, kSOCKS4OkRequestLocalHostPort80,
4970 kSOCKS4OkRequestLocalHostPort80Length),
4971 MockWrite(SYNCHRONOUS,
4972 "GET /socks4 HTTP/1.1\r\n"
4973 "Host: test\r\n"
4974 "Connection: keep-alive\r\n\r\n"),
4975 };
4976 MockRead socks_reads[] = {
4977 MockRead(SYNCHRONOUS, kSOCKS4OkReply, kSOCKS4OkReplyLength),
4978 MockRead("HTTP/1.0 200 OK\r\n"
4979 "Connection: keep-alive\r\n"
4980 "Content-Length: 15\r\n\r\n"
4981 "SOCKS4 Response"),
4982 };
Ryan Sleevib8d7ea02018-05-07 20:01:014983 StaticSocketDataProvider socks_data(socks_reads, socks_writes);
Matt Menked1eb6d42018-01-17 04:54:064984 session_deps_.socket_factory->AddSocketDataProvider(&socks_data);
4985
4986 const char kSOCKS5Request[] = {
4987 0x05, // Version
4988 0x01, // Command (CONNECT)
4989 0x00, // Reserved
4990 0x03, // Address type (DOMAINNAME)
4991 0x04, // Length of domain (4)
4992 't', 'e', 's', 't', // Domain string
4993 0x00, 0x50, // 16-bit port (80)
4994 };
4995 MockWrite socks5_writes[] = {
4996 MockWrite(ASYNC, kSOCKS5GreetRequest, kSOCKS5GreetRequestLength),
Avi Drissman4365a4782018-12-28 19:26:244997 MockWrite(ASYNC, kSOCKS5Request, base::size(kSOCKS5Request)),
Matt Menked1eb6d42018-01-17 04:54:064998 MockWrite(SYNCHRONOUS,
4999 "GET /socks5 HTTP/1.1\r\n"
5000 "Host: test\r\n"
5001 "Connection: keep-alive\r\n\r\n"),
5002 };
5003 MockRead socks5_reads[] = {
5004 MockRead(ASYNC, kSOCKS5GreetResponse, kSOCKS5GreetResponseLength),
5005 MockRead(ASYNC, kSOCKS5OkResponse, kSOCKS5OkResponseLength),
5006 MockRead("HTTP/1.0 200 OK\r\n"
5007 "Connection: keep-alive\r\n"
5008 "Content-Length: 15\r\n\r\n"
5009 "SOCKS5 Response"),
5010 };
Ryan Sleevib8d7ea02018-05-07 20:01:015011 StaticSocketDataProvider socks5_data(socks5_reads, socks5_writes);
Matt Menked1eb6d42018-01-17 04:54:065012 session_deps_.socket_factory->AddSocketDataProvider(&socks5_data);
5013
5014 MockWrite http_writes[] = {
5015 MockWrite(SYNCHRONOUS,
5016 "GET http://test/http HTTP/1.1\r\n"
5017 "Host: test\r\n"
5018 "Proxy-Connection: keep-alive\r\n\r\n"),
5019 };
5020 MockRead http_reads[] = {
5021 MockRead("HTTP/1.1 200 OK\r\n"
5022 "Proxy-Connection: keep-alive\r\n"
5023 "Content-Length: 13\r\n\r\n"
5024 "HTTP Response"),
5025 };
Ryan Sleevib8d7ea02018-05-07 20:01:015026 StaticSocketDataProvider http_data(http_reads, http_writes);
Matt Menked1eb6d42018-01-17 04:54:065027 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
5028
5029 MockWrite https_writes[] = {
5030 MockWrite(SYNCHRONOUS,
5031 "GET http://test/https HTTP/1.1\r\n"
5032 "Host: test\r\n"
5033 "Proxy-Connection: keep-alive\r\n\r\n"),
5034 };
5035 MockRead https_reads[] = {
5036 MockRead("HTTP/1.1 200 OK\r\n"
5037 "Proxy-Connection: keep-alive\r\n"
5038 "Content-Length: 14\r\n\r\n"
5039 "HTTPS Response"),
5040 };
Ryan Sleevib8d7ea02018-05-07 20:01:015041 StaticSocketDataProvider https_data(https_reads, https_writes);
Matt Menked1eb6d42018-01-17 04:54:065042 session_deps_.socket_factory->AddSocketDataProvider(&https_data);
5043 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
5044 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5045
Matt Menkee8648fa2019-01-17 16:47:075046 MockWrite https_trusted_writes[] = {
5047 MockWrite(SYNCHRONOUS,
5048 "GET http://test/https_trusted HTTP/1.1\r\n"
5049 "Host: test\r\n"
5050 "Proxy-Connection: keep-alive\r\n\r\n"),
5051 };
5052 MockRead https_trusted_reads[] = {
5053 MockRead("HTTP/1.1 200 OK\r\n"
5054 "Proxy-Connection: keep-alive\r\n"
5055 "Content-Length: 22\r\n\r\n"
5056 "HTTPS Trusted Response"),
5057 };
5058 StaticSocketDataProvider trusted_https_data(https_trusted_reads,
5059 https_trusted_writes);
5060 session_deps_.socket_factory->AddSocketDataProvider(&trusted_https_data);
5061 SSLSocketDataProvider ssl2(SYNCHRONOUS, OK);
5062 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
5063
Matt Menked1eb6d42018-01-17 04:54:065064 struct TestCase {
5065 GURL url;
5066 std::string expected_response;
Matt Menkee8648fa2019-01-17 16:47:075067 // How many idle sockets there should be in the SOCKS 4/5 proxy socket pools
Matt Menked1eb6d42018-01-17 04:54:065068 // after the test.
Matt Menkee8648fa2019-01-17 16:47:075069 int expected_idle_socks4_sockets;
5070 int expected_idle_socks5_sockets;
5071 // How many idle sockets there should be in the HTTP/HTTPS proxy socket
5072 // pools after the test.
Matt Menked1eb6d42018-01-17 04:54:065073 int expected_idle_http_sockets;
Matt Menkee8648fa2019-01-17 16:47:075074 int expected_idle_https_sockets;
5075 // How many idle sockets there should be in the HTTPS proxy socket pool with
5076 // the ProxyServer's |is_trusted_proxy| bit set after the test.
5077 int expected_idle_trusted_https_sockets;
Matt Menked1eb6d42018-01-17 04:54:065078 } const kTestCases[] = {
Matt Menkee8648fa2019-01-17 16:47:075079 {GURL("http://test/socks4"), "SOCKS4 Response", 1, 0, 0, 0, 0},
5080 {GURL("http://test/socks5"), "SOCKS5 Response", 1, 1, 0, 0, 0},
5081 {GURL("http://test/http"), "HTTP Response", 1, 1, 1, 0, 0},
5082 {GURL("http://test/https"), "HTTPS Response", 1, 1, 1, 1, 0},
5083 {GURL("http://test/https_trusted"), "HTTPS Trusted Response", 1, 1, 1, 1,
5084 1},
Matt Menked1eb6d42018-01-17 04:54:065085 };
5086
5087 for (const auto& test_case : kTestCases) {
5088 HttpRequestInfo request;
5089 request.method = "GET";
5090 request.url = test_case.url;
Ramin Halavatib5e433e2018-02-07 07:41:105091 request.traffic_annotation =
5092 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Matt Menked1eb6d42018-01-17 04:54:065093 std::unique_ptr<HttpNetworkTransaction> trans =
5094 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
5095 session.get());
5096 TestCompletionCallback callback;
5097 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
5098 EXPECT_THAT(callback.GetResult(rv), IsOk());
5099
5100 const HttpResponseInfo* response = trans->GetResponseInfo();
5101 ASSERT_TRUE(response);
5102 ASSERT_TRUE(response->headers);
5103 EXPECT_EQ(200, response->headers->response_code());
5104 std::string response_data;
5105 EXPECT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
5106 EXPECT_EQ(test_case.expected_response, response_data);
5107
5108 // Return the socket to the socket pool, so can make sure it's not used for
5109 // the next requests.
5110 trans.reset();
5111 base::RunLoop().RunUntilIdle();
5112
5113 // Check the number of idle sockets in the pool, to make sure that used
5114 // sockets are indeed being returned to the socket pool. If each request
5115 // doesn't return an idle socket to the pool, the test would incorrectly
5116 // pass.
Matt Menkee8648fa2019-01-17 16:47:075117 EXPECT_EQ(test_case.expected_idle_socks4_sockets,
5118 session
Matt Menked23ab952019-03-06 00:24:405119 ->GetSocketPool(
Matt Menkee8648fa2019-01-17 16:47:075120 HttpNetworkSession::NORMAL_SOCKET_POOL,
5121 ProxyServer(ProxyServer::SCHEME_SOCKS4,
5122 SameProxyWithDifferentSchemesProxyResolver::
5123 ProxyHostPortPair()))
5124 ->IdleSocketCount());
5125 EXPECT_EQ(test_case.expected_idle_socks5_sockets,
5126 session
Matt Menked23ab952019-03-06 00:24:405127 ->GetSocketPool(
Matt Menkee8648fa2019-01-17 16:47:075128 HttpNetworkSession::NORMAL_SOCKET_POOL,
5129 ProxyServer(ProxyServer::SCHEME_SOCKS5,
5130 SameProxyWithDifferentSchemesProxyResolver::
5131 ProxyHostPortPair()))
5132 ->IdleSocketCount());
5133 EXPECT_EQ(test_case.expected_idle_http_sockets,
5134 session
Matt Menked23ab952019-03-06 00:24:405135 ->GetSocketPool(
Matt Menkee8648fa2019-01-17 16:47:075136 HttpNetworkSession::NORMAL_SOCKET_POOL,
5137 ProxyServer(ProxyServer::SCHEME_HTTP,
5138 SameProxyWithDifferentSchemesProxyResolver::
5139 ProxyHostPortPair()))
5140 ->IdleSocketCount());
5141 EXPECT_EQ(test_case.expected_idle_https_sockets,
5142 session
Matt Menked23ab952019-03-06 00:24:405143 ->GetSocketPool(
Matt Menkee8648fa2019-01-17 16:47:075144 HttpNetworkSession::NORMAL_SOCKET_POOL,
5145 ProxyServer(ProxyServer::SCHEME_HTTPS,
5146 SameProxyWithDifferentSchemesProxyResolver::
5147 ProxyHostPortPair()))
5148 ->IdleSocketCount());
5149 EXPECT_EQ(test_case.expected_idle_trusted_https_sockets,
5150 session
Matt Menked23ab952019-03-06 00:24:405151 ->GetSocketPool(
Matt Menkee8648fa2019-01-17 16:47:075152 HttpNetworkSession::NORMAL_SOCKET_POOL,
5153 ProxyServer(ProxyServer::SCHEME_HTTPS,
5154 SameProxyWithDifferentSchemesProxyResolver::
5155 ProxyHostPortPair(),
5156 true /* is_trusted_proxy */))
5157 ->IdleSocketCount());
Matt Menked1eb6d42018-01-17 04:54:065158 }
5159}
5160
[email protected]029c83b62013-01-24 05:28:205161// Test the load timing for HTTPS requests with an HTTP proxy.
bncd16676a2016-07-20 16:23:015162TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:205163 HttpRequestInfo request1;
5164 request1.method = "GET";
bncce36dca22015-04-21 22:11:235165 request1.url = GURL("https://www.example.org/1");
Ramin Halavatib5e433e2018-02-07 07:41:105166 request1.traffic_annotation =
5167 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:205168
5169 HttpRequestInfo request2;
5170 request2.method = "GET";
bncce36dca22015-04-21 22:11:235171 request2.url = GURL("https://www.example.org/2");
Ramin Halavatib5e433e2018-02-07 07:41:105172 request2.traffic_annotation =
5173 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:205174
5175 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495176 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5177 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515178 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075179 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095180 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:205181
5182 // Since we have proxy, should try to establish tunnel.
5183 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:175184 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5185 "Host: www.example.org:443\r\n"
5186 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205187
rsleevidb16bb02015-11-12 23:47:175188 MockWrite("GET /1 HTTP/1.1\r\n"
5189 "Host: www.example.org\r\n"
5190 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205191
rsleevidb16bb02015-11-12 23:47:175192 MockWrite("GET /2 HTTP/1.1\r\n"
5193 "Host: www.example.org\r\n"
5194 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205195 };
5196
5197 // The proxy responds to the connect with a 407, using a persistent
5198 // connection.
5199 MockRead data_reads1[] = {
5200 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
5201
5202 MockRead("HTTP/1.1 200 OK\r\n"),
5203 MockRead("Content-Length: 1\r\n\r\n"),
5204 MockRead(SYNCHRONOUS, "1"),
5205
5206 MockRead("HTTP/1.1 200 OK\r\n"),
5207 MockRead("Content-Length: 2\r\n\r\n"),
5208 MockRead(SYNCHRONOUS, "22"),
5209 };
5210
Ryan Sleevib8d7ea02018-05-07 20:01:015211 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:075212 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:205213 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075214 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:205215
5216 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:585217 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:195218 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:205219
5220 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015221 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:205222
5223 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015224 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:205225
5226 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:525227 ASSERT_TRUE(response1);
tbansal2ecbbc72016-10-06 17:15:475228 EXPECT_TRUE(response1->proxy_server.is_http());
wezca1070932016-05-26 20:30:525229 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:205230 EXPECT_EQ(1, response1->headers->GetContentLength());
5231
5232 LoadTimingInfo load_timing_info1;
5233 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
5234 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
5235
5236 trans1.reset();
5237
5238 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:585239 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:195240 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:205241
5242 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015243 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:205244
5245 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015246 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:205247
5248 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:525249 ASSERT_TRUE(response2);
tbansal2ecbbc72016-10-06 17:15:475250 EXPECT_TRUE(response2->proxy_server.is_http());
wezca1070932016-05-26 20:30:525251 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:205252 EXPECT_EQ(2, response2->headers->GetContentLength());
5253
5254 LoadTimingInfo load_timing_info2;
5255 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5256 TestLoadTimingReused(load_timing_info2);
5257
5258 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
5259
5260 trans2.reset();
5261 session->CloseAllConnections();
5262}
5263
5264// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
bncd16676a2016-07-20 16:23:015265TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:205266 HttpRequestInfo request1;
5267 request1.method = "GET";
bncce36dca22015-04-21 22:11:235268 request1.url = GURL("https://www.example.org/1");
Ramin Halavatib5e433e2018-02-07 07:41:105269 request1.traffic_annotation =
5270 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:205271
5272 HttpRequestInfo request2;
5273 request2.method = "GET";
bncce36dca22015-04-21 22:11:235274 request2.url = GURL("https://www.example.org/2");
Ramin Halavatib5e433e2018-02-07 07:41:105275 request2.traffic_annotation =
5276 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:205277
5278 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595279 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:495280 ProxyResolutionService::CreateFixedFromPacResult(
5281 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515282 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075283 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095284 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:205285
5286 // Since we have proxy, should try to establish tunnel.
5287 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:175288 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5289 "Host: www.example.org:443\r\n"
5290 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205291
rsleevidb16bb02015-11-12 23:47:175292 MockWrite("GET /1 HTTP/1.1\r\n"
5293 "Host: www.example.org\r\n"
5294 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205295
rsleevidb16bb02015-11-12 23:47:175296 MockWrite("GET /2 HTTP/1.1\r\n"
5297 "Host: www.example.org\r\n"
5298 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205299 };
5300
5301 // The proxy responds to the connect with a 407, using a persistent
5302 // connection.
5303 MockRead data_reads1[] = {
5304 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
5305
5306 MockRead("HTTP/1.1 200 OK\r\n"),
5307 MockRead("Content-Length: 1\r\n\r\n"),
5308 MockRead(SYNCHRONOUS, "1"),
5309
5310 MockRead("HTTP/1.1 200 OK\r\n"),
5311 MockRead("Content-Length: 2\r\n\r\n"),
5312 MockRead(SYNCHRONOUS, "22"),
5313 };
5314
Ryan Sleevib8d7ea02018-05-07 20:01:015315 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:075316 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:205317 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075318 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:205319
5320 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:585321 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:195322 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:205323
5324 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015325 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:205326
5327 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015328 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:205329
5330 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:525331 ASSERT_TRUE(response1);
5332 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:205333 EXPECT_EQ(1, response1->headers->GetContentLength());
5334
5335 LoadTimingInfo load_timing_info1;
5336 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
5337 TestLoadTimingNotReusedWithPac(load_timing_info1,
5338 CONNECT_TIMING_HAS_SSL_TIMES);
5339
5340 trans1.reset();
5341
5342 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:585343 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:195344 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:205345
5346 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015347 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:205348
5349 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015350 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:205351
5352 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:525353 ASSERT_TRUE(response2);
5354 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:205355 EXPECT_EQ(2, response2->headers->GetContentLength());
5356
5357 LoadTimingInfo load_timing_info2;
5358 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5359 TestLoadTimingReusedWithPac(load_timing_info2);
5360
5361 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
5362
5363 trans2.reset();
5364 session->CloseAllConnections();
5365}
5366
[email protected]2df19bb2010-08-25 20:13:465367// Test a simple get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015368TEST_F(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:275369 HttpRequestInfo request;
5370 request.method = "GET";
bncce36dca22015-04-21 22:11:235371 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105372 request.traffic_annotation =
5373 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275374
[email protected]2df19bb2010-08-25 20:13:465375 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495376 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5377 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515378 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075379 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095380 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:465381
[email protected]2df19bb2010-08-25 20:13:465382 // Since we have proxy, should use full url
5383 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235384 MockWrite(
5385 "GET http://www.example.org/ HTTP/1.1\r\n"
5386 "Host: www.example.org\r\n"
5387 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465388 };
5389
5390 MockRead data_reads1[] = {
5391 MockRead("HTTP/1.1 200 OK\r\n"),
5392 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5393 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065394 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:465395 };
5396
Ryan Sleevib8d7ea02018-05-07 20:01:015397 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:075398 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:065399 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075400 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:465401
[email protected]49639fa2011-12-20 23:22:415402 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:465403
bnc691fda62016-08-12 00:43:165404 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505405
bnc691fda62016-08-12 00:43:165406 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015407 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465408
5409 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015410 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465411
[email protected]58e32bb2013-01-21 18:23:255412 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165413 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255414 TestLoadTimingNotReused(load_timing_info,
5415 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5416
bnc691fda62016-08-12 00:43:165417 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525418 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:465419
tbansal2ecbbc72016-10-06 17:15:475420 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:465421 EXPECT_TRUE(response->headers->IsKeepAlive());
5422 EXPECT_EQ(200, response->headers->response_code());
5423 EXPECT_EQ(100, response->headers->GetContentLength());
5424 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5425
5426 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525427 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:465428}
5429
[email protected]7642b5ae2010-09-01 20:55:175430// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015431TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:275432 HttpRequestInfo request;
5433 request.method = "GET";
bncce36dca22015-04-21 22:11:235434 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105435 request.traffic_annotation =
5436 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275437
[email protected]7642b5ae2010-09-01 20:55:175438 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495439 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5440 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515441 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075442 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095443 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:175444
bncce36dca22015-04-21 22:11:235445 // fetch http://www.example.org/ via SPDY
Ryan Hamilton0239aac2018-05-19 00:03:135446 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:455447 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415448 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]7642b5ae2010-09-01 20:55:175449
Ryan Hamilton0239aac2018-05-19 00:03:135450 spdy::SpdySerializedFrame resp(
5451 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
5452 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:175453 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415454 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]7642b5ae2010-09-01 20:55:175455 };
5456
Ryan Sleevib8d7ea02018-05-07 20:01:015457 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075458 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:175459
[email protected]8ddf8322012-02-23 18:08:065460 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365461 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075462 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:175463
[email protected]49639fa2011-12-20 23:22:415464 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:175465
bnc691fda62016-08-12 00:43:165466 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505467
bnc691fda62016-08-12 00:43:165468 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015469 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7642b5ae2010-09-01 20:55:175470
5471 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015472 EXPECT_THAT(rv, IsOk());
[email protected]7642b5ae2010-09-01 20:55:175473
[email protected]58e32bb2013-01-21 18:23:255474 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165475 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255476 TestLoadTimingNotReused(load_timing_info,
5477 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5478
bnc691fda62016-08-12 00:43:165479 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525480 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:475481 EXPECT_TRUE(response->proxy_server.is_https());
wezca1070932016-05-26 20:30:525482 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025483 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]7642b5ae2010-09-01 20:55:175484
5485 std::string response_data;
bnc691fda62016-08-12 00:43:165486 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235487 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:175488}
5489
[email protected]1c173852014-06-19 12:51:505490// Verifies that a session which races and wins against the owning transaction
5491// (completing prior to host resolution), doesn't fail the transaction.
5492// Regression test for crbug.com/334413.
bncd16676a2016-07-20 16:23:015493TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
[email protected]1c173852014-06-19 12:51:505494 HttpRequestInfo request;
5495 request.method = "GET";
bncce36dca22015-04-21 22:11:235496 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105497 request.traffic_annotation =
5498 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c173852014-06-19 12:51:505499
5500 // Configure SPDY proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495501 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5502 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515503 BoundTestNetLog log;
[email protected]1c173852014-06-19 12:51:505504 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095505 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1c173852014-06-19 12:51:505506
bncce36dca22015-04-21 22:11:235507 // Fetch http://www.example.org/ through the SPDY proxy.
Ryan Hamilton0239aac2018-05-19 00:03:135508 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:455509 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415510 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]1c173852014-06-19 12:51:505511
Raul Tambre94493c652019-03-11 17:18:355512 spdy::SpdySerializedFrame resp(
5513 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135514 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]1c173852014-06-19 12:51:505515 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415516 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]1c173852014-06-19 12:51:505517 };
5518
Ryan Sleevib8d7ea02018-05-07 20:01:015519 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]1c173852014-06-19 12:51:505520 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
5521
5522 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365523 ssl.next_proto = kProtoHTTP2;
[email protected]1c173852014-06-19 12:51:505524 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5525
5526 TestCompletionCallback callback1;
5527
bnc691fda62016-08-12 00:43:165528 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1c173852014-06-19 12:51:505529
5530 // Stall the hostname resolution begun by the transaction.
[email protected]1c173852014-06-19 12:51:505531 session_deps_.host_resolver->set_ondemand_mode(true);
5532
bnc691fda62016-08-12 00:43:165533 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015534 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c173852014-06-19 12:51:505535
5536 // Race a session to the proxy, which completes first.
5537 session_deps_.host_resolver->set_ondemand_mode(false);
Paul Jensena457017a2018-01-19 23:52:045538 SpdySessionKey key(HostPortPair("proxy", 70), ProxyServer::Direct(),
Matt Menke2436b2f2018-12-11 18:07:115539 PRIVACY_MODE_DISABLED,
5540 SpdySessionKey::IsProxySession::kTrue, SocketTag());
[email protected]1c173852014-06-19 12:51:505541 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:525542 CreateSpdySession(session.get(), key, log.bound());
[email protected]1c173852014-06-19 12:51:505543
5544 // Unstall the resolution begun by the transaction.
5545 session_deps_.host_resolver->set_ondemand_mode(true);
5546 session_deps_.host_resolver->ResolveAllPending();
5547
5548 EXPECT_FALSE(callback1.have_result());
5549 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015550 EXPECT_THAT(rv, IsOk());
[email protected]1c173852014-06-19 12:51:505551
bnc691fda62016-08-12 00:43:165552 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525553 ASSERT_TRUE(response);
5554 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025555 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]1c173852014-06-19 12:51:505556
5557 std::string response_data;
bnc691fda62016-08-12 00:43:165558 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]1c173852014-06-19 12:51:505559 EXPECT_EQ(kUploadData, response_data);
5560}
5561
[email protected]dc7bd1c52010-11-12 00:01:135562// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015563TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:275564 HttpRequestInfo request;
5565 request.method = "GET";
bncce36dca22015-04-21 22:11:235566 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105567 request.traffic_annotation =
5568 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275569
[email protected]79cb5c12011-09-12 13:12:045570 // Configure against https proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495571 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5572 "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515573 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075574 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095575 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:135576
[email protected]dc7bd1c52010-11-12 00:01:135577 // The first request will be a bare GET, the second request will be a
5578 // GET with a Proxy-Authorization header.
bncb26024382016-06-29 02:39:455579 spdy_util_.set_default_url(request.url);
Ryan Hamilton0239aac2018-05-19 00:03:135580 spdy::SpdySerializedFrame req_get(
Bence Béky27ad0a12018-02-08 00:35:485581 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:385582 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]dc7bd1c52010-11-12 00:01:135583 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:465584 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:135585 };
Ryan Hamilton0239aac2018-05-19 00:03:135586 spdy::SpdySerializedFrame req_get_authorization(spdy_util_.ConstructSpdyGet(
Avi Drissman4365a4782018-12-28 19:26:245587 kExtraAuthorizationHeaders, base::size(kExtraAuthorizationHeaders) / 2, 3,
Bence Béky27ad0a12018-02-08 00:35:485588 LOWEST));
[email protected]dc7bd1c52010-11-12 00:01:135589 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415590 CreateMockWrite(req_get, 0), CreateMockWrite(req_get_authorization, 3),
[email protected]dc7bd1c52010-11-12 00:01:135591 };
5592
5593 // The first response is a 407 proxy authentication challenge, and the second
5594 // response will be a 200 response since the second request includes a valid
5595 // Authorization header.
5596 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:465597 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:135598 };
Ryan Hamilton0239aac2018-05-19 00:03:135599 spdy::SpdySerializedFrame resp_authentication(
5600 spdy_util_.ConstructSpdyReplyError(
5601 "407", kExtraAuthenticationHeaders,
Avi Drissman4365a4782018-12-28 19:26:245602 base::size(kExtraAuthenticationHeaders) / 2, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135603 spdy::SpdySerializedFrame body_authentication(
bncdf80d44fd2016-07-15 20:27:415604 spdy_util_.ConstructSpdyDataFrame(1, true));
Ryan Hamilton0239aac2018-05-19 00:03:135605 spdy::SpdySerializedFrame resp_data(
Raul Tambre94493c652019-03-11 17:18:355606 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
Ryan Hamilton0239aac2018-05-19 00:03:135607 spdy::SpdySerializedFrame body_data(
5608 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:135609 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415610 CreateMockRead(resp_authentication, 1),
bnceb9aa7112017-01-05 01:03:465611 CreateMockRead(body_authentication, 2, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415612 CreateMockRead(resp_data, 4),
5613 CreateMockRead(body_data, 5),
rch8e6c6c42015-05-01 14:05:135614 MockRead(ASYNC, 0, 6),
[email protected]dc7bd1c52010-11-12 00:01:135615 };
5616
Ryan Sleevib8d7ea02018-05-07 20:01:015617 SequencedSocketData data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075618 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:135619
[email protected]8ddf8322012-02-23 18:08:065620 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365621 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075622 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:135623
[email protected]49639fa2011-12-20 23:22:415624 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:135625
bnc691fda62016-08-12 00:43:165626 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]dc7bd1c52010-11-12 00:01:135627
bnc691fda62016-08-12 00:43:165628 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015629 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:135630
5631 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015632 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:135633
bnc691fda62016-08-12 00:43:165634 const HttpResponseInfo* const response = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:135635
wezca1070932016-05-26 20:30:525636 ASSERT_TRUE(response);
5637 ASSERT_TRUE(response->headers);
[email protected]dc7bd1c52010-11-12 00:01:135638 EXPECT_EQ(407, response->headers->response_code());
5639 EXPECT_TRUE(response->was_fetched_via_spdy);
asanka098c0092016-06-16 20:18:435640 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:135641
[email protected]49639fa2011-12-20 23:22:415642 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:135643
bnc691fda62016-08-12 00:43:165644 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015645 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:135646
5647 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015648 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:135649
bnc691fda62016-08-12 00:43:165650 const HttpResponseInfo* const response_restart = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:135651
wezca1070932016-05-26 20:30:525652 ASSERT_TRUE(response_restart);
5653 ASSERT_TRUE(response_restart->headers);
[email protected]dc7bd1c52010-11-12 00:01:135654 EXPECT_EQ(200, response_restart->headers->response_code());
5655 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525656 EXPECT_FALSE(response_restart->auth_challenge);
[email protected]dc7bd1c52010-11-12 00:01:135657}
5658
[email protected]d9da5fe2010-10-13 22:37:165659// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
bncd16676a2016-07-20 16:23:015660TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:275661 HttpRequestInfo request;
5662 request.method = "GET";
bncce36dca22015-04-21 22:11:235663 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105664 request.traffic_annotation =
5665 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275666
[email protected]d9da5fe2010-10-13 22:37:165667 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495668 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5669 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515670 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075671 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095672 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165673
bnc691fda62016-08-12 00:43:165674 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165675
bncce36dca22015-04-21 22:11:235676 // CONNECT to www.example.org:443 via SPDY
Ryan Hamilton0239aac2018-05-19 00:03:135677 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:045678 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
5679 HostPortPair("www.example.org", 443)));
bncce36dca22015-04-21 22:11:235680 // fetch https://www.example.org/ via HTTP
[email protected]d9da5fe2010-10-13 22:37:165681
bncce36dca22015-04-21 22:11:235682 const char get[] =
5683 "GET / HTTP/1.1\r\n"
5684 "Host: www.example.org\r\n"
5685 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:135686 spdy::SpdySerializedFrame wrapped_get(
Bence Békyd74f4382018-02-20 18:26:195687 spdy_util_.ConstructSpdyDataFrame(1, get, false));
Ryan Hamilton0239aac2018-05-19 00:03:135688 spdy::SpdySerializedFrame conn_resp(
Raul Tambre94493c652019-03-11 17:18:355689 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:165690 const char resp[] = "HTTP/1.1 200 OK\r\n"
5691 "Content-Length: 10\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:135692 spdy::SpdySerializedFrame wrapped_get_resp(
Bence Békyd74f4382018-02-20 18:26:195693 spdy_util_.ConstructSpdyDataFrame(1, resp, false));
Ryan Hamilton0239aac2018-05-19 00:03:135694 spdy::SpdySerializedFrame wrapped_body(
Bence Békyd74f4382018-02-20 18:26:195695 spdy_util_.ConstructSpdyDataFrame(1, "1234567890", false));
Ryan Hamilton0239aac2018-05-19 00:03:135696 spdy::SpdySerializedFrame window_update(
bncdf80d44fd2016-07-15 20:27:415697 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
[email protected]8d2f7012012-02-16 00:08:045698
5699 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415700 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
5701 CreateMockWrite(window_update, 6),
[email protected]8d2f7012012-02-16 00:08:045702 };
5703
[email protected]d9da5fe2010-10-13 22:37:165704 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415705 CreateMockRead(conn_resp, 1, ASYNC),
5706 CreateMockRead(wrapped_get_resp, 3, ASYNC),
5707 CreateMockRead(wrapped_body, 4, ASYNC),
5708 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:135709 MockRead(ASYNC, 0, 7),
[email protected]d9da5fe2010-10-13 22:37:165710 };
5711
Ryan Sleevib8d7ea02018-05-07 20:01:015712 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075713 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165714
[email protected]8ddf8322012-02-23 18:08:065715 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365716 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075717 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065718 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075719 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165720
[email protected]49639fa2011-12-20 23:22:415721 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165722
bnc691fda62016-08-12 00:43:165723 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015724 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165725
5726 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015727 ASSERT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:165728
[email protected]58e32bb2013-01-21 18:23:255729 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165730 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255731 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5732
bnc691fda62016-08-12 00:43:165733 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525734 ASSERT_TRUE(response);
5735 ASSERT_TRUE(response->headers);
[email protected]d9da5fe2010-10-13 22:37:165736 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5737
5738 std::string response_data;
bnc691fda62016-08-12 00:43:165739 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]d9da5fe2010-10-13 22:37:165740 EXPECT_EQ("1234567890", response_data);
5741}
5742
5743// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
bncd16676a2016-07-20 16:23:015744TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
5745 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:385746
[email protected]cb9bf6ca2011-01-28 13:15:275747 HttpRequestInfo request;
5748 request.method = "GET";
bncce36dca22015-04-21 22:11:235749 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105750 request.traffic_annotation =
5751 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275752
[email protected]d9da5fe2010-10-13 22:37:165753 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495754 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5755 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515756 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075757 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095758 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165759
bnc691fda62016-08-12 00:43:165760 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165761
bncce36dca22015-04-21 22:11:235762 // CONNECT to www.example.org:443 via SPDY
Ryan Hamilton0239aac2018-05-19 00:03:135763 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:045764 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
5765 HostPortPair("www.example.org", 443)));
bncce36dca22015-04-21 22:11:235766 // fetch https://www.example.org/ via SPDY
5767 const char kMyUrl[] = "https://www.example.org/";
Ryan Hamilton0239aac2018-05-19 00:03:135768 spdy::SpdySerializedFrame get(
bnc38dcd392016-02-09 23:19:495769 spdy_util_wrapped.ConstructSpdyGet(kMyUrl, 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:135770 spdy::SpdySerializedFrame wrapped_get(
5771 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
5772 spdy::SpdySerializedFrame conn_resp(
Raul Tambre94493c652019-03-11 17:18:355773 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135774 spdy::SpdySerializedFrame get_resp(
Raul Tambre94493c652019-03-11 17:18:355775 spdy_util_wrapped.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135776 spdy::SpdySerializedFrame wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:025777 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135778 spdy::SpdySerializedFrame body(
5779 spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
5780 spdy::SpdySerializedFrame wrapped_body(
[email protected]23e482282013-06-14 16:08:025781 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135782 spdy::SpdySerializedFrame window_update_get_resp(
bncdf80d44fd2016-07-15 20:27:415783 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
Ryan Hamilton0239aac2018-05-19 00:03:135784 spdy::SpdySerializedFrame window_update_body(
bncdf80d44fd2016-07-15 20:27:415785 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
[email protected]8d2f7012012-02-16 00:08:045786
5787 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415788 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
5789 CreateMockWrite(window_update_get_resp, 6),
5790 CreateMockWrite(window_update_body, 7),
[email protected]8d2f7012012-02-16 00:08:045791 };
5792
[email protected]d9da5fe2010-10-13 22:37:165793 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415794 CreateMockRead(conn_resp, 1, ASYNC),
rch32320842015-05-16 15:57:095795 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:415796 CreateMockRead(wrapped_get_resp, 4, ASYNC),
5797 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:135798 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:165799 };
5800
Ryan Sleevib8d7ea02018-05-07 20:01:015801 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075802 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165803
[email protected]8ddf8322012-02-23 18:08:065804 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365805 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075806 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065807 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365808 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075809 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165810
[email protected]49639fa2011-12-20 23:22:415811 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165812
bnc691fda62016-08-12 00:43:165813 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015814 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165815
rch32320842015-05-16 15:57:095816 // Allow the SpdyProxyClientSocket's write callback to complete.
fdoray92e35a72016-06-10 15:54:555817 base::RunLoop().RunUntilIdle();
rch32320842015-05-16 15:57:095818 // Now allow the read of the response to complete.
mmenkee24011922015-12-17 22:12:595819 spdy_data.Resume();
[email protected]d9da5fe2010-10-13 22:37:165820 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015821 EXPECT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:165822
[email protected]58e32bb2013-01-21 18:23:255823 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165824 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255825 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5826
bnc691fda62016-08-12 00:43:165827 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525828 ASSERT_TRUE(response);
5829 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025830 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d9da5fe2010-10-13 22:37:165831
5832 std::string response_data;
bnc691fda62016-08-12 00:43:165833 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235834 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:165835}
5836
5837// Test a SPDY CONNECT failure through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015838TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:275839 HttpRequestInfo request;
5840 request.method = "GET";
bncce36dca22015-04-21 22:11:235841 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105842 request.traffic_annotation =
5843 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275844
[email protected]d9da5fe2010-10-13 22:37:165845 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495846 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5847 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515848 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075849 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095850 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165851
bnc691fda62016-08-12 00:43:165852 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165853
bncce36dca22015-04-21 22:11:235854 // CONNECT to www.example.org:443 via SPDY
Ryan Hamilton0239aac2018-05-19 00:03:135855 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:045856 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
5857 HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:135858 spdy::SpdySerializedFrame get(
5859 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:165860
5861 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415862 CreateMockWrite(connect, 0), CreateMockWrite(get, 2),
[email protected]d9da5fe2010-10-13 22:37:165863 };
5864
Ryan Hamilton0239aac2018-05-19 00:03:135865 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(1));
5866 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:165867 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415868 CreateMockRead(resp, 1, ASYNC), MockRead(ASYNC, 0, 3),
[email protected]d9da5fe2010-10-13 22:37:165869 };
5870
Ryan Sleevib8d7ea02018-05-07 20:01:015871 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075872 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165873
[email protected]8ddf8322012-02-23 18:08:065874 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365875 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075876 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065877 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365878 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075879 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165880
[email protected]49639fa2011-12-20 23:22:415881 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165882
bnc691fda62016-08-12 00:43:165883 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015884 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165885
5886 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015887 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]d9da5fe2010-10-13 22:37:165888
ttuttle960fcbf2016-04-19 13:26:325889 // TODO(juliatuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:165890}
5891
Matt Menkecb2cd0982018-12-19 17:54:045892// Test the case where a proxied H2 session doesn't exist when an auth challenge
5893// is observed, but does exist by the time auth credentials are provided.
5894// Proxy-Connection: Close is used so that there's a second DNS lookup, which is
5895// what causes the existing H2 session to be noticed and reused.
5896TEST_F(HttpNetworkTransactionTest, ProxiedH2SessionAppearsDuringAuth) {
5897 ProxyConfig proxy_config;
5898 proxy_config.set_auto_detect(true);
5899 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
5900
5901 CapturingProxyResolver capturing_proxy_resolver;
5902 capturing_proxy_resolver.set_proxy_server(
5903 ProxyServer(ProxyServer::SCHEME_HTTP, HostPortPair("myproxy", 70)));
5904 session_deps_.proxy_resolution_service =
5905 std::make_unique<ProxyResolutionService>(
5906 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
5907 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
5908 std::make_unique<CapturingProxyResolverFactory>(
5909 &capturing_proxy_resolver),
5910 nullptr);
5911
5912 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
5913
5914 const char kMyUrl[] = "https://www.example.org/";
5915 spdy::SpdySerializedFrame get(spdy_util_.ConstructSpdyGet(kMyUrl, 1, LOWEST));
5916 spdy::SpdySerializedFrame get_resp(
Raul Tambre94493c652019-03-11 17:18:355917 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Matt Menkecb2cd0982018-12-19 17:54:045918 spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
5919
5920 spdy_util_.UpdateWithStreamDestruction(1);
5921 spdy::SpdySerializedFrame get2(
5922 spdy_util_.ConstructSpdyGet(kMyUrl, 3, LOWEST));
5923 spdy::SpdySerializedFrame get_resp2(
Raul Tambre94493c652019-03-11 17:18:355924 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
Matt Menkecb2cd0982018-12-19 17:54:045925 spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
5926
5927 MockWrite auth_challenge_writes[] = {
5928 MockWrite(ASYNC, 0,
5929 "CONNECT www.example.org:443 HTTP/1.1\r\n"
5930 "Host: www.example.org:443\r\n"
5931 "Proxy-Connection: keep-alive\r\n\r\n"),
5932 };
5933
5934 MockRead auth_challenge_reads[] = {
5935 MockRead(ASYNC, 1,
5936 "HTTP/1.1 407 Authentication Required\r\n"
5937 "Content-Length: 0\r\n"
5938 "Proxy-Connection: close\r\n"
5939 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
5940 };
5941
5942 MockWrite spdy_writes[] = {
5943 MockWrite(ASYNC, 0,
5944 "CONNECT www.example.org:443 HTTP/1.1\r\n"
5945 "Host: www.example.org:443\r\n"
5946 "Proxy-Connection: keep-alive\r\n"
5947 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5948 CreateMockWrite(get, 2),
5949 CreateMockWrite(get2, 5),
5950 };
5951
5952 MockRead spdy_reads[] = {
5953 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\n\r\n"),
5954 CreateMockRead(get_resp, 3, ASYNC),
5955 CreateMockRead(body, 4, ASYNC),
5956 CreateMockRead(get_resp2, 6, ASYNC),
5957 CreateMockRead(body2, 7, ASYNC),
5958
5959 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 8),
5960 };
5961
5962 SequencedSocketData auth_challenge1(auth_challenge_reads,
5963 auth_challenge_writes);
5964 session_deps_.socket_factory->AddSocketDataProvider(&auth_challenge1);
5965
5966 SequencedSocketData auth_challenge2(auth_challenge_reads,
5967 auth_challenge_writes);
5968 session_deps_.socket_factory->AddSocketDataProvider(&auth_challenge2);
5969
5970 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
5971 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
5972
5973 SSLSocketDataProvider ssl(ASYNC, OK);
5974 ssl.next_proto = kProtoHTTP2;
5975 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5976
5977 TestCompletionCallback callback;
5978 std::string response_data;
5979
5980 // Run first request until an auth challenge is observed.
5981 HttpRequestInfo request1;
5982 request1.method = "GET";
5983 request1.url = GURL(kMyUrl);
5984 request1.traffic_annotation =
5985 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5986 HttpNetworkTransaction trans1(LOWEST, session.get());
5987 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
5988 EXPECT_THAT(callback.GetResult(rv), IsOk());
5989 const HttpResponseInfo* response = trans1.GetResponseInfo();
5990 ASSERT_TRUE(response);
5991 ASSERT_TRUE(response->headers);
5992 EXPECT_EQ(407, response->headers->response_code());
5993 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5994 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
5995
5996 // Run second request until an auth challenge is observed.
5997 HttpRequestInfo request2;
5998 request2.method = "GET";
5999 request2.url = GURL(kMyUrl);
6000 request2.traffic_annotation =
6001 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6002 HttpNetworkTransaction trans2(LOWEST, session.get());
6003 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
6004 EXPECT_THAT(callback.GetResult(rv), IsOk());
6005 response = trans2.GetResponseInfo();
6006 ASSERT_TRUE(response);
6007 ASSERT_TRUE(response->headers);
6008 EXPECT_EQ(407, response->headers->response_code());
6009 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6010 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
6011
6012 // Now provide credentials for the first request, and wait for it to complete.
6013 rv = trans1.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
6014 rv = callback.GetResult(rv);
6015 EXPECT_THAT(rv, IsOk());
6016 response = trans1.GetResponseInfo();
6017 ASSERT_TRUE(response);
6018 ASSERT_TRUE(response->headers);
6019 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
6020 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
6021 EXPECT_EQ(kUploadData, response_data);
6022
6023 // Now provide credentials for the second request. It should notice the
6024 // existing session, and reuse it.
6025 rv = trans2.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
6026 EXPECT_THAT(callback.GetResult(rv), IsOk());
6027 response = trans2.GetResponseInfo();
6028 ASSERT_TRUE(response);
6029 ASSERT_TRUE(response->headers);
6030 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
6031 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
6032 EXPECT_EQ(kUploadData, response_data);
6033}
6034
[email protected]f6c63db52013-02-02 00:35:226035// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
6036// HTTPS Proxy to different servers.
bncd16676a2016-07-20 16:23:016037TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:226038 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
6039 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496040 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6041 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:516042 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076043 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:096044 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:506045 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:226046
6047 HttpRequestInfo request1;
6048 request1.method = "GET";
bncce36dca22015-04-21 22:11:236049 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:226050 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:106051 request1.traffic_annotation =
6052 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226053
6054 HttpRequestInfo request2;
6055 request2.method = "GET";
bncce36dca22015-04-21 22:11:236056 request2.url = GURL("https://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:226057 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:106058 request2.traffic_annotation =
6059 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226060
bncce36dca22015-04-21 22:11:236061 // CONNECT to www.example.org:443 via SPDY.
Ryan Hamilton0239aac2018-05-19 00:03:136062 spdy::SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:046063 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
6064 HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:136065 spdy::SpdySerializedFrame conn_resp1(
Raul Tambre94493c652019-03-11 17:18:356066 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
[email protected]f6c63db52013-02-02 00:35:226067
bncce36dca22015-04-21 22:11:236068 // Fetch https://www.example.org/ via HTTP.
6069 const char get1[] =
6070 "GET / HTTP/1.1\r\n"
6071 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:226072 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136073 spdy::SpdySerializedFrame wrapped_get1(
Bence Békyd74f4382018-02-20 18:26:196074 spdy_util_.ConstructSpdyDataFrame(1, get1, false));
[email protected]f6c63db52013-02-02 00:35:226075 const char resp1[] = "HTTP/1.1 200 OK\r\n"
6076 "Content-Length: 1\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136077 spdy::SpdySerializedFrame wrapped_get_resp1(
Bence Békyd74f4382018-02-20 18:26:196078 spdy_util_.ConstructSpdyDataFrame(1, resp1, false));
Ryan Hamilton0239aac2018-05-19 00:03:136079 spdy::SpdySerializedFrame wrapped_body1(
Bence Békyd74f4382018-02-20 18:26:196080 spdy_util_.ConstructSpdyDataFrame(1, "1", false));
Ryan Hamilton0239aac2018-05-19 00:03:136081 spdy::SpdySerializedFrame window_update(
bncdf80d44fd2016-07-15 20:27:416082 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:226083
bncce36dca22015-04-21 22:11:236084 // CONNECT to mail.example.org:443 via SPDY.
Ryan Hamilton0239aac2018-05-19 00:03:136085 spdy::SpdyHeaderBlock connect2_block;
6086 connect2_block[spdy::kHttp2MethodHeader] = "CONNECT";
6087 connect2_block[spdy::kHttp2AuthorityHeader] = "mail.example.org:443";
6088 spdy::SpdySerializedFrame connect2(spdy_util_.ConstructSpdyHeaders(
Matt Menke6e879bd2019-03-18 17:26:046089 3, std::move(connect2_block), HttpProxyConnectJob::kH2QuicTunnelPriority,
6090 false));
[email protected]601e03f12014-04-06 16:26:396091
Ryan Hamilton0239aac2018-05-19 00:03:136092 spdy::SpdySerializedFrame conn_resp2(
Raul Tambre94493c652019-03-11 17:18:356093 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
[email protected]f6c63db52013-02-02 00:35:226094
bncce36dca22015-04-21 22:11:236095 // Fetch https://mail.example.org/ via HTTP.
6096 const char get2[] =
6097 "GET / HTTP/1.1\r\n"
6098 "Host: mail.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:226099 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136100 spdy::SpdySerializedFrame wrapped_get2(
Bence Békyd74f4382018-02-20 18:26:196101 spdy_util_.ConstructSpdyDataFrame(3, get2, false));
[email protected]f6c63db52013-02-02 00:35:226102 const char resp2[] = "HTTP/1.1 200 OK\r\n"
6103 "Content-Length: 2\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136104 spdy::SpdySerializedFrame wrapped_get_resp2(
Bence Békyd74f4382018-02-20 18:26:196105 spdy_util_.ConstructSpdyDataFrame(3, resp2, false));
Ryan Hamilton0239aac2018-05-19 00:03:136106 spdy::SpdySerializedFrame wrapped_body2(
Bence Békyd74f4382018-02-20 18:26:196107 spdy_util_.ConstructSpdyDataFrame(3, "22", false));
[email protected]f6c63db52013-02-02 00:35:226108
6109 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:416110 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
6111 CreateMockWrite(connect2, 5), CreateMockWrite(wrapped_get2, 7),
[email protected]f6c63db52013-02-02 00:35:226112 };
6113
6114 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:416115 CreateMockRead(conn_resp1, 1, ASYNC),
6116 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
6117 CreateMockRead(wrapped_body1, 4, ASYNC),
6118 CreateMockRead(conn_resp2, 6, ASYNC),
6119 CreateMockRead(wrapped_get_resp2, 8, ASYNC),
6120 CreateMockRead(wrapped_body2, 9, ASYNC),
6121 MockRead(ASYNC, 0, 10),
[email protected]f6c63db52013-02-02 00:35:226122 };
6123
Ryan Sleevib8d7ea02018-05-07 20:01:016124 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
mmenke11eb5152015-06-09 14:50:506125 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:226126
6127 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:366128 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:506129 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:226130 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:506131 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:226132 SSLSocketDataProvider ssl3(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:506133 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:226134
6135 TestCompletionCallback callback;
6136
bnc691fda62016-08-12 00:43:166137 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206138 int rv = trans.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016139 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:226140
6141 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:166142 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]f6c63db52013-02-02 00:35:226143 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
6144
bnc691fda62016-08-12 00:43:166145 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526146 ASSERT_TRUE(response);
6147 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:226148 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6149
6150 std::string response_data;
Victor Costan9c7302b2018-08-27 16:39:446151 scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(256);
bnc691fda62016-08-12 00:43:166152 rv = trans.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:506153 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:226154
bnc691fda62016-08-12 00:43:166155 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206156 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016157 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:226158
6159 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:166160 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:226161 // Even though the SPDY connection is reused, a new tunnelled connection has
6162 // to be created, so the socket's load timing looks like a fresh connection.
6163 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
6164
6165 // The requests should have different IDs, since they each are using their own
6166 // separate stream.
6167 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
6168
bnc691fda62016-08-12 00:43:166169 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:506170 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:226171}
6172
6173// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
6174// HTTPS Proxy to the same server.
bncd16676a2016-07-20 16:23:016175TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:226176 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
6177 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496178 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6179 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:516180 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076181 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:096182 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:506183 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:226184
6185 HttpRequestInfo request1;
6186 request1.method = "GET";
bncce36dca22015-04-21 22:11:236187 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:226188 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:106189 request1.traffic_annotation =
6190 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226191
6192 HttpRequestInfo request2;
6193 request2.method = "GET";
bncce36dca22015-04-21 22:11:236194 request2.url = GURL("https://www.example.org/2");
[email protected]f6c63db52013-02-02 00:35:226195 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:106196 request2.traffic_annotation =
6197 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226198
bncce36dca22015-04-21 22:11:236199 // CONNECT to www.example.org:443 via SPDY.
Ryan Hamilton0239aac2018-05-19 00:03:136200 spdy::SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:046201 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
6202 HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:136203 spdy::SpdySerializedFrame conn_resp1(
Raul Tambre94493c652019-03-11 17:18:356204 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
[email protected]f6c63db52013-02-02 00:35:226205
bncce36dca22015-04-21 22:11:236206 // Fetch https://www.example.org/ via HTTP.
6207 const char get1[] =
6208 "GET / HTTP/1.1\r\n"
6209 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:226210 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136211 spdy::SpdySerializedFrame wrapped_get1(
Bence Békyd74f4382018-02-20 18:26:196212 spdy_util_.ConstructSpdyDataFrame(1, get1, false));
[email protected]f6c63db52013-02-02 00:35:226213 const char resp1[] = "HTTP/1.1 200 OK\r\n"
6214 "Content-Length: 1\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136215 spdy::SpdySerializedFrame wrapped_get_resp1(
Bence Békyd74f4382018-02-20 18:26:196216 spdy_util_.ConstructSpdyDataFrame(1, resp1, false));
Ryan Hamilton0239aac2018-05-19 00:03:136217 spdy::SpdySerializedFrame wrapped_body1(
Bence Békyd74f4382018-02-20 18:26:196218 spdy_util_.ConstructSpdyDataFrame(1, "1", false));
Ryan Hamilton0239aac2018-05-19 00:03:136219 spdy::SpdySerializedFrame window_update(
bncdf80d44fd2016-07-15 20:27:416220 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:226221
bncce36dca22015-04-21 22:11:236222 // Fetch https://www.example.org/2 via HTTP.
6223 const char get2[] =
6224 "GET /2 HTTP/1.1\r\n"
6225 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:226226 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136227 spdy::SpdySerializedFrame wrapped_get2(
Bence Békyd74f4382018-02-20 18:26:196228 spdy_util_.ConstructSpdyDataFrame(1, get2, false));
[email protected]f6c63db52013-02-02 00:35:226229 const char resp2[] = "HTTP/1.1 200 OK\r\n"
6230 "Content-Length: 2\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136231 spdy::SpdySerializedFrame wrapped_get_resp2(
Bence Békyd74f4382018-02-20 18:26:196232 spdy_util_.ConstructSpdyDataFrame(1, resp2, false));
Ryan Hamilton0239aac2018-05-19 00:03:136233 spdy::SpdySerializedFrame wrapped_body2(
Bence Békyd74f4382018-02-20 18:26:196234 spdy_util_.ConstructSpdyDataFrame(1, "22", false));
[email protected]f6c63db52013-02-02 00:35:226235
6236 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:416237 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
6238 CreateMockWrite(wrapped_get2, 5),
[email protected]f6c63db52013-02-02 00:35:226239 };
6240
6241 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:416242 CreateMockRead(conn_resp1, 1, ASYNC),
6243 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
bnceb9aa7112017-01-05 01:03:466244 CreateMockRead(wrapped_body1, 4, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:416245 CreateMockRead(wrapped_get_resp2, 6, ASYNC),
bnceb9aa7112017-01-05 01:03:466246 CreateMockRead(wrapped_body2, 7, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:416247 MockRead(ASYNC, 0, 8),
[email protected]f6c63db52013-02-02 00:35:226248 };
6249
Ryan Sleevib8d7ea02018-05-07 20:01:016250 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
mmenke11eb5152015-06-09 14:50:506251 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:226252
6253 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:366254 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:506255 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:226256 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:506257 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:226258
6259 TestCompletionCallback callback;
6260
bnc87dcefc2017-05-25 12:47:586261 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:196262 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206263 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016264 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:226265
6266 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016267 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:226268
6269 LoadTimingInfo load_timing_info;
6270 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6271 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
6272
6273 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526274 ASSERT_TRUE(response);
6275 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:226276 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6277
6278 std::string response_data;
Victor Costan9c7302b2018-08-27 16:39:446279 scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(256);
[email protected]90499482013-06-01 00:39:506280 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:226281 trans.reset();
6282
bnc87dcefc2017-05-25 12:47:586283 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:196284 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206285 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016286 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:226287
[email protected]f6c63db52013-02-02 00:35:226288 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016289 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:226290
6291 LoadTimingInfo load_timing_info2;
6292 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
6293 TestLoadTimingReused(load_timing_info2);
6294
6295 // The requests should have the same ID.
6296 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
6297
[email protected]90499482013-06-01 00:39:506298 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:226299}
6300
6301// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
6302// Proxy to different servers.
bncd16676a2016-07-20 16:23:016303TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) {
[email protected]f6c63db52013-02-02 00:35:226304 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496305 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6306 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:516307 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076308 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:096309 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:506310 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:226311
6312 HttpRequestInfo request1;
6313 request1.method = "GET";
bncce36dca22015-04-21 22:11:236314 request1.url = GURL("http://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:226315 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:106316 request1.traffic_annotation =
6317 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226318
6319 HttpRequestInfo request2;
6320 request2.method = "GET";
bncce36dca22015-04-21 22:11:236321 request2.url = GURL("http://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:226322 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:106323 request2.traffic_annotation =
6324 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226325
bncce36dca22015-04-21 22:11:236326 // http://www.example.org/
Ryan Hamilton0239aac2018-05-19 00:03:136327 spdy::SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:236328 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
Ryan Hamilton0239aac2018-05-19 00:03:136329 spdy::SpdySerializedFrame get1(
bnc42331402016-07-25 13:36:156330 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
Ryan Hamilton0239aac2018-05-19 00:03:136331 spdy::SpdySerializedFrame get_resp1(
Raul Tambre94493c652019-03-11 17:18:356332 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:136333 spdy::SpdySerializedFrame body1(
6334 spdy_util_.ConstructSpdyDataFrame(1, "1", true));
rdsmithebb50aa2015-11-12 03:44:386335 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]f6c63db52013-02-02 00:35:226336
bncce36dca22015-04-21 22:11:236337 // http://mail.example.org/
Ryan Hamilton0239aac2018-05-19 00:03:136338 spdy::SpdyHeaderBlock headers2(
bncce36dca22015-04-21 22:11:236339 spdy_util_.ConstructGetHeaderBlockForProxy("http://mail.example.org/"));
Ryan Hamilton0239aac2018-05-19 00:03:136340 spdy::SpdySerializedFrame get2(
bnc42331402016-07-25 13:36:156341 spdy_util_.ConstructSpdyHeaders(3, std::move(headers2), LOWEST, true));
Ryan Hamilton0239aac2018-05-19 00:03:136342 spdy::SpdySerializedFrame get_resp2(
Raul Tambre94493c652019-03-11 17:18:356343 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
Ryan Hamilton0239aac2018-05-19 00:03:136344 spdy::SpdySerializedFrame body2(
6345 spdy_util_.ConstructSpdyDataFrame(3, "22", true));
[email protected]f6c63db52013-02-02 00:35:226346
6347 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:416348 CreateMockWrite(get1, 0), CreateMockWrite(get2, 3),
[email protected]f6c63db52013-02-02 00:35:226349 };
6350
6351 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:416352 CreateMockRead(get_resp1, 1, ASYNC),
6353 CreateMockRead(body1, 2, ASYNC),
6354 CreateMockRead(get_resp2, 4, ASYNC),
6355 CreateMockRead(body2, 5, ASYNC),
6356 MockRead(ASYNC, 0, 6),
[email protected]f6c63db52013-02-02 00:35:226357 };
6358
Ryan Sleevib8d7ea02018-05-07 20:01:016359 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
mmenke11eb5152015-06-09 14:50:506360 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:226361
6362 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:366363 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:506364 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:226365
6366 TestCompletionCallback callback;
6367
bnc87dcefc2017-05-25 12:47:586368 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:196369 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206370 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016371 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:226372
6373 LoadTimingInfo load_timing_info;
6374 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6375 TestLoadTimingNotReused(load_timing_info,
6376 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6377
6378 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526379 ASSERT_TRUE(response);
6380 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:026381 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]f6c63db52013-02-02 00:35:226382
6383 std::string response_data;
Victor Costan9c7302b2018-08-27 16:39:446384 scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(256);
mmenke11eb5152015-06-09 14:50:506385 rv = trans->Read(buf.get(), 256, callback.callback());
6386 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:226387 // Delete the first request, so the second one can reuse the socket.
6388 trans.reset();
6389
bnc691fda62016-08-12 00:43:166390 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206391 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016392 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:226393
6394 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:166395 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:226396 TestLoadTimingReused(load_timing_info2);
6397
6398 // The requests should have the same ID.
6399 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
6400
bnc691fda62016-08-12 00:43:166401 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:506402 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:226403}
6404
Matt Menke2436b2f2018-12-11 18:07:116405// Test that an HTTP/2 CONNECT through an HTTPS Proxy to a HTTP/2 server and a
6406// direct (non-proxied) request to the proxy server are not pooled, as that
6407// would break socket pool isolation.
6408TEST_F(HttpNetworkTransactionTest, SpdyProxyIsolation1) {
6409 ProxyConfig proxy_config;
6410 proxy_config.set_auto_detect(true);
6411 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
6412
6413 CapturingProxyResolver capturing_proxy_resolver;
6414 session_deps_.proxy_resolution_service =
6415 std::make_unique<ProxyResolutionService>(
6416 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
6417 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
6418 std::make_unique<CapturingProxyResolverFactory>(
6419 &capturing_proxy_resolver),
6420 nullptr);
6421
6422 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6423
6424 SpdyTestUtil spdy_util1;
6425 // CONNECT to www.example.org:443 via HTTP/2.
6426 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:046427 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
6428 HostPortPair("www.example.org", 443)));
Matt Menke2436b2f2018-12-11 18:07:116429 // fetch https://www.example.org/ via HTTP/2.
6430 const char kMyUrl[] = "https://www.example.org/";
6431 spdy::SpdySerializedFrame get(spdy_util1.ConstructSpdyGet(kMyUrl, 1, LOWEST));
6432 spdy::SpdySerializedFrame wrapped_get(
6433 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
6434 spdy::SpdySerializedFrame conn_resp(
Raul Tambre94493c652019-03-11 17:18:356435 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Matt Menke2436b2f2018-12-11 18:07:116436 spdy::SpdySerializedFrame get_resp(
Raul Tambre94493c652019-03-11 17:18:356437 spdy_util1.ConstructSpdyGetReply(nullptr, 0, 1));
Matt Menke2436b2f2018-12-11 18:07:116438 spdy::SpdySerializedFrame wrapped_get_resp(
6439 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
6440 spdy::SpdySerializedFrame body(spdy_util1.ConstructSpdyDataFrame(1, true));
6441 spdy::SpdySerializedFrame wrapped_body(
6442 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
6443 spdy::SpdySerializedFrame window_update_get_resp(
6444 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
6445 spdy::SpdySerializedFrame window_update_body(
6446 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
6447
6448 MockWrite spdy_writes1[] = {
6449 CreateMockWrite(connect, 0),
6450 CreateMockWrite(wrapped_get, 2),
6451 CreateMockWrite(window_update_get_resp, 6),
6452 CreateMockWrite(window_update_body, 7),
6453 };
6454
6455 MockRead spdy_reads1[] = {
6456 CreateMockRead(conn_resp, 1, ASYNC),
6457 MockRead(ASYNC, ERR_IO_PENDING, 3),
6458 CreateMockRead(wrapped_get_resp, 4, ASYNC),
6459 CreateMockRead(wrapped_body, 5, ASYNC),
6460 MockRead(ASYNC, 0, 8),
6461 };
6462
6463 SequencedSocketData spdy_data1(spdy_reads1, spdy_writes1);
6464 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data1);
6465
6466 // Fetch https://proxy:70/ via HTTP/2. Needs a new SpdyTestUtil, since it uses
6467 // a new pipe.
6468 SpdyTestUtil spdy_util2;
6469 spdy::SpdySerializedFrame req(
6470 spdy_util2.ConstructSpdyGet("https://proxy:70/", 1, LOWEST));
6471 MockWrite spdy_writes2[] = {CreateMockWrite(req, 0)};
6472
6473 spdy::SpdySerializedFrame resp(
6474 spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
6475 spdy::SpdySerializedFrame data(spdy_util2.ConstructSpdyDataFrame(1, true));
6476 MockRead spdy_reads2[] = {
6477 CreateMockRead(resp, 1),
6478 CreateMockRead(data, 2),
6479 MockRead(ASYNC, 0, 3),
6480 };
6481 SequencedSocketData spdy_data2(spdy_reads2, spdy_writes2);
6482 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data2);
6483
6484 SSLSocketDataProvider ssl(ASYNC, OK);
6485 ssl.next_proto = kProtoHTTP2;
6486 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6487 SSLSocketDataProvider ssl2(ASYNC, OK);
6488 ssl2.next_proto = kProtoHTTP2;
6489 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6490 SSLSocketDataProvider ssl3(ASYNC, OK);
6491 ssl3.next_proto = kProtoHTTP2;
6492 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
6493
6494 TestCompletionCallback callback;
6495 std::string response_data;
6496
6497 // Make a request using proxy:70 as a HTTP/2 proxy.
6498 capturing_proxy_resolver.set_proxy_server(
6499 ProxyServer(ProxyServer::SCHEME_HTTPS, HostPortPair("proxy", 70)));
6500 HttpRequestInfo request1;
6501 request1.method = "GET";
6502 request1.url = GURL("https://www.example.org/");
6503 request1.traffic_annotation =
6504 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6505
6506 HttpNetworkTransaction trans1(LOWEST, session.get());
6507 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
6508 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6509
6510 // Allow the SpdyProxyClientSocket's write callback to complete.
6511 base::RunLoop().RunUntilIdle();
6512 // Now allow the read of the response to complete.
6513 spdy_data1.Resume();
6514 rv = callback.WaitForResult();
6515 EXPECT_THAT(rv, IsOk());
6516
6517 const HttpResponseInfo* response = trans1.GetResponseInfo();
6518 ASSERT_TRUE(response);
6519 ASSERT_TRUE(response->headers);
6520 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
6521
6522 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
6523 EXPECT_EQ(kUploadData, response_data);
6524 RunUntilIdle();
6525
6526 // Make a direct HTTP/2 request to proxy:70.
6527 capturing_proxy_resolver.set_proxy_server(ProxyServer::Direct());
6528 HttpRequestInfo request2;
6529 request2.method = "GET";
6530 request2.url = GURL("https://proxy:70/");
6531 request2.traffic_annotation =
6532 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6533 HttpNetworkTransaction trans2(LOWEST, session.get());
6534 EXPECT_THAT(callback.GetResult(trans2.Start(&request2, callback.callback(),
6535 NetLogWithSource())),
6536 IsOk());
6537 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
6538}
6539
6540// Same as above, but reverse request order, since the code to check for an
6541// existing session is different for tunnels and direct connections.
6542TEST_F(HttpNetworkTransactionTest, SpdyProxyIsolation2) {
6543 // Configure against https proxy server "myproxy:80".
6544 ProxyConfig proxy_config;
6545 proxy_config.set_auto_detect(true);
6546 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
6547
6548 CapturingProxyResolver capturing_proxy_resolver;
6549 session_deps_.proxy_resolution_service =
6550 std::make_unique<ProxyResolutionService>(
6551 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
6552 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
6553 std::make_unique<CapturingProxyResolverFactory>(
6554 &capturing_proxy_resolver),
6555 nullptr);
6556
6557 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6558 // Fetch https://proxy:70/ via HTTP/2.
6559 SpdyTestUtil spdy_util1;
6560 spdy::SpdySerializedFrame req(
6561 spdy_util1.ConstructSpdyGet("https://proxy:70/", 1, LOWEST));
6562 MockWrite spdy_writes1[] = {CreateMockWrite(req, 0)};
6563
6564 spdy::SpdySerializedFrame resp(
6565 spdy_util1.ConstructSpdyGetReply(nullptr, 0, 1));
6566 spdy::SpdySerializedFrame data(spdy_util1.ConstructSpdyDataFrame(1, true));
6567 MockRead spdy_reads1[] = {
6568 CreateMockRead(resp, 1),
6569 CreateMockRead(data, 2),
6570 MockRead(ASYNC, 0, 3),
6571 };
6572 SequencedSocketData spdy_data1(spdy_reads1, spdy_writes1);
6573 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data1);
6574
6575 SpdyTestUtil spdy_util2;
6576 // CONNECT to www.example.org:443 via HTTP/2.
6577 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:046578 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
6579 HostPortPair("www.example.org", 443)));
Matt Menke2436b2f2018-12-11 18:07:116580 // fetch https://www.example.org/ via HTTP/2.
6581 const char kMyUrl[] = "https://www.example.org/";
6582 spdy::SpdySerializedFrame get(spdy_util2.ConstructSpdyGet(kMyUrl, 1, LOWEST));
6583 spdy::SpdySerializedFrame wrapped_get(
6584 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
6585 spdy::SpdySerializedFrame conn_resp(
6586 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
6587 spdy::SpdySerializedFrame get_resp(
6588 spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
6589 spdy::SpdySerializedFrame wrapped_get_resp(
6590 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
6591 spdy::SpdySerializedFrame body(spdy_util2.ConstructSpdyDataFrame(1, true));
6592 spdy::SpdySerializedFrame wrapped_body(
6593 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
6594 spdy::SpdySerializedFrame window_update_get_resp(
6595 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
6596 spdy::SpdySerializedFrame window_update_body(
6597 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
6598
6599 MockWrite spdy_writes2[] = {
6600 CreateMockWrite(connect, 0),
6601 CreateMockWrite(wrapped_get, 2),
6602 CreateMockWrite(window_update_get_resp, 6),
6603 CreateMockWrite(window_update_body, 7),
6604 };
6605
6606 MockRead spdy_reads2[] = {
6607 CreateMockRead(conn_resp, 1, ASYNC),
6608 MockRead(ASYNC, ERR_IO_PENDING, 3),
6609 CreateMockRead(wrapped_get_resp, 4, ASYNC),
6610 CreateMockRead(wrapped_body, 5, ASYNC),
6611 MockRead(ASYNC, 0, 8),
6612 };
6613
6614 SequencedSocketData spdy_data2(spdy_reads2, spdy_writes2);
6615 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data2);
6616
6617 SSLSocketDataProvider ssl(ASYNC, OK);
6618 ssl.next_proto = kProtoHTTP2;
6619 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6620 SSLSocketDataProvider ssl2(ASYNC, OK);
6621 ssl2.next_proto = kProtoHTTP2;
6622 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6623 SSLSocketDataProvider ssl3(ASYNC, OK);
6624 ssl3.next_proto = kProtoHTTP2;
6625 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
6626
6627 TestCompletionCallback callback;
6628 std::string response_data;
6629
6630 // Make a direct HTTP/2 request to proxy:70.
6631 capturing_proxy_resolver.set_proxy_server(ProxyServer::Direct());
6632 HttpRequestInfo request1;
6633 request1.method = "GET";
6634 request1.url = GURL("https://proxy:70/");
6635 request1.traffic_annotation =
6636 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6637 HttpNetworkTransaction trans1(LOWEST, session.get());
6638 EXPECT_THAT(callback.GetResult(trans1.Start(&request1, callback.callback(),
6639 NetLogWithSource())),
6640 IsOk());
6641 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
6642 RunUntilIdle();
6643
6644 // Make a request using proxy:70 as a HTTP/2 proxy.
6645 capturing_proxy_resolver.set_proxy_server(
6646 ProxyServer(ProxyServer::SCHEME_HTTPS, HostPortPair("proxy", 70)));
6647 HttpRequestInfo request2;
6648 request2.method = "GET";
6649 request2.url = GURL("https://www.example.org/");
6650 request2.traffic_annotation =
6651 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6652
6653 HttpNetworkTransaction trans2(LOWEST, session.get());
6654 int rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
6655 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6656
6657 // Allow the SpdyProxyClientSocket's write callback to complete.
6658 base::RunLoop().RunUntilIdle();
6659 // Now allow the read of the response to complete.
6660 spdy_data2.Resume();
6661 rv = callback.WaitForResult();
6662 EXPECT_THAT(rv, IsOk());
6663
6664 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
6665 ASSERT_TRUE(response2);
6666 ASSERT_TRUE(response2->headers);
6667 EXPECT_EQ("HTTP/1.1 200", response2->headers->GetStatusLine());
6668
6669 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
6670 EXPECT_EQ(kUploadData, response_data);
6671}
6672
[email protected]2df19bb2010-08-25 20:13:466673// Test the challenge-response-retry sequence through an HTTPS Proxy
bncd16676a2016-07-20 16:23:016674TEST_F(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:466675 HttpRequestInfo request;
6676 request.method = "GET";
bncce36dca22015-04-21 22:11:236677 request.url = GURL("http://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:466678 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:296679 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:106680 request.traffic_annotation =
6681 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:466682
[email protected]79cb5c12011-09-12 13:12:046683 // Configure against https proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496684 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6685 "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:516686 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076687 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:096688 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276689
[email protected]2df19bb2010-08-25 20:13:466690 // Since we have proxy, should use full url
6691 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:166692 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
6693 "Host: www.example.org\r\n"
6694 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:466695
bnc691fda62016-08-12 00:43:166696 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:236697 // be issuing -- the final header line contains the credentials.
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"
6701 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:466702 };
6703
6704 // The proxy responds to the GET with a 407, using a persistent
6705 // connection.
6706 MockRead data_reads1[] = {
6707 // No credentials.
6708 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
6709 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6710 MockRead("Proxy-Connection: keep-alive\r\n"),
6711 MockRead("Content-Length: 0\r\n\r\n"),
6712
6713 MockRead("HTTP/1.1 200 OK\r\n"),
6714 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6715 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066716 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:466717 };
6718
Ryan Sleevib8d7ea02018-05-07 20:01:016719 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:076720 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:066721 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076722 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:466723
[email protected]49639fa2011-12-20 23:22:416724 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:466725
bnc691fda62016-08-12 00:43:166726 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506727
bnc691fda62016-08-12 00:43:166728 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:016729 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:466730
6731 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016732 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:466733
[email protected]58e32bb2013-01-21 18:23:256734 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:166735 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:256736 TestLoadTimingNotReused(load_timing_info,
6737 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6738
bnc691fda62016-08-12 00:43:166739 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526740 ASSERT_TRUE(response);
6741 ASSERT_TRUE(response->headers);
[email protected]2df19bb2010-08-25 20:13:466742 EXPECT_EQ(407, response->headers->response_code());
6743 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
asanka098c0092016-06-16 20:18:436744 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
Wojciech Dzierżanowski0950c372019-04-02 19:29:506745 EXPECT_FALSE(response->did_use_http_auth);
[email protected]2df19bb2010-08-25 20:13:466746
[email protected]49639fa2011-12-20 23:22:416747 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:466748
bnc691fda62016-08-12 00:43:166749 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:016750 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:466751
6752 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016753 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:466754
[email protected]58e32bb2013-01-21 18:23:256755 load_timing_info = LoadTimingInfo();
bnc691fda62016-08-12 00:43:166756 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:256757 // Retrying with HTTP AUTH is considered to be reusing a socket.
6758 TestLoadTimingReused(load_timing_info);
6759
bnc691fda62016-08-12 00:43:166760 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526761 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:466762
6763 EXPECT_TRUE(response->headers->IsKeepAlive());
6764 EXPECT_EQ(200, response->headers->response_code());
6765 EXPECT_EQ(100, response->headers->GetContentLength());
6766 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
Wojciech Dzierżanowski0950c372019-04-02 19:29:506767 EXPECT_TRUE(response->did_use_http_auth);
[email protected]2df19bb2010-08-25 20:13:466768
6769 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:526770 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:466771}
6772
[email protected]23e482282013-06-14 16:08:026773void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:086774 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:426775 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:086776 request.method = "GET";
bncce36dca22015-04-21 22:11:236777 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:106778 request.traffic_annotation =
6779 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]c744cf22009-02-27 07:28:086780
[email protected]cb9bf6ca2011-01-28 13:15:276781 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496782 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6783 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:096784 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276785
[email protected]c744cf22009-02-27 07:28:086786 // Since we have proxy, should try to establish tunnel.
6787 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:176788 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
6789 "Host: www.example.org:443\r\n"
6790 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:086791 };
6792
6793 MockRead data_reads[] = {
mmenked39192ee2015-12-09 00:57:236794 status, MockRead("Content-Length: 10\r\n\r\n"),
6795 // No response body because the test stops reading here.
6796 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]c744cf22009-02-27 07:28:086797 };
6798
Ryan Sleevib8d7ea02018-05-07 20:01:016799 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:076800 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:086801
[email protected]49639fa2011-12-20 23:22:416802 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:086803
bnc691fda62016-08-12 00:43:166804 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506805
tfarina42834112016-09-22 13:38:206806 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016807 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]c744cf22009-02-27 07:28:086808
6809 rv = callback.WaitForResult();
6810 EXPECT_EQ(expected_status, rv);
6811}
6812
[email protected]23e482282013-06-14 16:08:026813void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:236814 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:086815 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:426816 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:086817}
6818
bncd16676a2016-07-20 16:23:016819TEST_F(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:086820 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
6821}
6822
bncd16676a2016-07-20 16:23:016823TEST_F(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:086824 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
6825}
6826
bncd16676a2016-07-20 16:23:016827TEST_F(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:086828 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
6829}
6830
bncd16676a2016-07-20 16:23:016831TEST_F(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:086832 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
6833}
6834
bncd16676a2016-07-20 16:23:016835TEST_F(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:086836 ConnectStatusHelper(
6837 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
6838}
6839
bncd16676a2016-07-20 16:23:016840TEST_F(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:086841 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
6842}
6843
bncd16676a2016-07-20 16:23:016844TEST_F(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:086845 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
6846}
6847
bncd16676a2016-07-20 16:23:016848TEST_F(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:086849 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
6850}
6851
bncd16676a2016-07-20 16:23:016852TEST_F(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:086853 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
6854}
6855
bncd16676a2016-07-20 16:23:016856TEST_F(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:086857 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
6858}
6859
bncd16676a2016-07-20 16:23:016860TEST_F(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:086861 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
6862}
6863
bncd16676a2016-07-20 16:23:016864TEST_F(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:086865 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
6866}
6867
bncd16676a2016-07-20 16:23:016868TEST_F(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:086869 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
6870}
6871
bncd16676a2016-07-20 16:23:016872TEST_F(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:086873 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
6874}
6875
bncd16676a2016-07-20 16:23:016876TEST_F(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:086877 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
6878}
6879
bncd16676a2016-07-20 16:23:016880TEST_F(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:086881 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
6882}
6883
bncd16676a2016-07-20 16:23:016884TEST_F(HttpNetworkTransactionTest, ConnectStatus308) {
[email protected]0a17aab32014-04-24 03:32:376885 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
6886}
6887
bncd16676a2016-07-20 16:23:016888TEST_F(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:086889 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
6890}
6891
bncd16676a2016-07-20 16:23:016892TEST_F(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:086893 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
6894}
6895
bncd16676a2016-07-20 16:23:016896TEST_F(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:086897 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
6898}
6899
bncd16676a2016-07-20 16:23:016900TEST_F(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:086901 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
6902}
6903
bncd16676a2016-07-20 16:23:016904TEST_F(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:086905 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
6906}
6907
bncd16676a2016-07-20 16:23:016908TEST_F(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:086909 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
6910}
6911
bncd16676a2016-07-20 16:23:016912TEST_F(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:086913 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
6914}
6915
bncd16676a2016-07-20 16:23:016916TEST_F(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:086917 ConnectStatusHelperWithExpectedStatus(
6918 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:546919 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:086920}
6921
bncd16676a2016-07-20 16:23:016922TEST_F(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:086923 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
6924}
6925
bncd16676a2016-07-20 16:23:016926TEST_F(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:086927 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
6928}
6929
bncd16676a2016-07-20 16:23:016930TEST_F(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:086931 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
6932}
6933
bncd16676a2016-07-20 16:23:016934TEST_F(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:086935 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
6936}
6937
bncd16676a2016-07-20 16:23:016938TEST_F(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:086939 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
6940}
6941
bncd16676a2016-07-20 16:23:016942TEST_F(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:086943 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
6944}
6945
bncd16676a2016-07-20 16:23:016946TEST_F(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:086947 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
6948}
6949
bncd16676a2016-07-20 16:23:016950TEST_F(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:086951 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
6952}
6953
bncd16676a2016-07-20 16:23:016954TEST_F(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:086955 ConnectStatusHelper(
6956 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
6957}
6958
bncd16676a2016-07-20 16:23:016959TEST_F(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:086960 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
6961}
6962
bncd16676a2016-07-20 16:23:016963TEST_F(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:086964 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
6965}
6966
bncd16676a2016-07-20 16:23:016967TEST_F(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:086968 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
6969}
6970
bncd16676a2016-07-20 16:23:016971TEST_F(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:086972 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
6973}
6974
bncd16676a2016-07-20 16:23:016975TEST_F(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:086976 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
6977}
6978
bncd16676a2016-07-20 16:23:016979TEST_F(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:086980 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
6981}
6982
bncd16676a2016-07-20 16:23:016983TEST_F(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:086984 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
6985}
6986
[email protected]038e9a32008-10-08 22:40:166987// Test the flow when both the proxy server AND origin server require
6988// authentication. Again, this uses basic auth for both since that is
6989// the simplest to mock.
bncd16676a2016-07-20 16:23:016990TEST_F(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:276991 HttpRequestInfo request;
6992 request.method = "GET";
bncce36dca22015-04-21 22:11:236993 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:106994 request.traffic_annotation =
6995 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:276996
[email protected]038e9a32008-10-08 22:40:166997 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496998 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6999 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:097000 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:077001
bnc691fda62016-08-12 00:43:167002 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]038e9a32008-10-08 22:40:167003
[email protected]f9ee6b52008-11-08 06:46:237004 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237005 MockWrite(
7006 "GET http://www.example.org/ HTTP/1.1\r\n"
7007 "Host: www.example.org\r\n"
7008 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237009 };
7010
[email protected]038e9a32008-10-08 22:40:167011 MockRead data_reads1[] = {
7012 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
7013 // Give a couple authenticate options (only the middle one is actually
7014 // supported).
[email protected]22927ad2009-09-21 19:56:197015 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:167016 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7017 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
7018 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7019 // Large content-length -- won't matter, as connection will be reset.
7020 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067021 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:167022 };
7023
bnc691fda62016-08-12 00:43:167024 // After calling trans.RestartWithAuth() the first time, this is the
[email protected]038e9a32008-10-08 22:40:167025 // request we should be issuing -- the final header line contains the
7026 // proxy's credentials.
7027 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237028 MockWrite(
7029 "GET http://www.example.org/ HTTP/1.1\r\n"
7030 "Host: www.example.org\r\n"
7031 "Proxy-Connection: keep-alive\r\n"
7032 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:167033 };
7034
7035 // Now the proxy server lets the request pass through to origin server.
7036 // The origin server responds with a 401.
7037 MockRead data_reads2[] = {
7038 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7039 // Note: We are using the same realm-name as the proxy server. This is
7040 // completely valid, as realms are unique across hosts.
7041 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7042 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7043 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067044 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:167045 };
7046
bnc691fda62016-08-12 00:43:167047 // After calling trans.RestartWithAuth() the second time, we should send
[email protected]038e9a32008-10-08 22:40:167048 // the credentials for both the proxy and origin server.
7049 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237050 MockWrite(
7051 "GET http://www.example.org/ HTTP/1.1\r\n"
7052 "Host: www.example.org\r\n"
7053 "Proxy-Connection: keep-alive\r\n"
7054 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
7055 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:167056 };
7057
7058 // Lastly we get the desired content.
7059 MockRead data_reads3[] = {
7060 MockRead("HTTP/1.0 200 OK\r\n"),
7061 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7062 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067063 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:167064 };
7065
Ryan Sleevib8d7ea02018-05-07 20:01:017066 StaticSocketDataProvider data1(data_reads1, data_writes1);
7067 StaticSocketDataProvider data2(data_reads2, data_writes2);
7068 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]bb88e1d32013-05-03 23:11:077069 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7070 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7071 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:167072
[email protected]49639fa2011-12-20 23:22:417073 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:167074
tfarina42834112016-09-22 13:38:207075 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017076 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:167077
7078 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017079 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:167080
bnc691fda62016-08-12 00:43:167081 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527082 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047083 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:167084
[email protected]49639fa2011-12-20 23:22:417085 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:167086
bnc691fda62016-08-12 00:43:167087 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:017088 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:167089
7090 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017091 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:167092
bnc691fda62016-08-12 00:43:167093 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527094 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047095 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:167096
[email protected]49639fa2011-12-20 23:22:417097 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:167098
bnc691fda62016-08-12 00:43:167099 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
7100 callback3.callback());
robpercival214763f2016-07-01 23:27:017101 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:167102
7103 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017104 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:167105
bnc691fda62016-08-12 00:43:167106 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527107 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:167108 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:167109}
[email protected]4ddaf2502008-10-23 18:26:197110
[email protected]ea9dc9a2009-09-05 00:43:327111// For the NTLM implementation using SSPI, we skip the NTLM tests since we
7112// can't hook into its internals to cause it to generate predictable NTLM
7113// authorization headers.
7114#if defined(NTLM_PORTABLE)
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377115// The NTLM authentication unit tests are based on known test data from the
7116// [MS-NLMP] Specification [1]. These tests are primarily of the authentication
7117// flow rather than the implementation of the NTLM protocol. See net/ntlm
7118// for the implementation and testing of the protocol.
7119//
7120// [1] https://msdn.microsoft.com/en-us/library/cc236621.aspx
[email protected]385a4672009-03-11 22:21:297121
7122// Enter the correct password and authenticate successfully.
Zentaro Kavanagh1890a3d2018-01-29 19:52:557123TEST_F(HttpNetworkTransactionTest, NTLMAuthV2) {
[email protected]1c773ea12009-04-28 19:58:427124 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:247125 request.method = "GET";
Zentaro Kavanagh1890a3d2018-01-29 19:52:557126 request.url = GURL("https://server/kids/login.aspx");
Ramin Halavatib5e433e2018-02-07 07:41:107127 request.traffic_annotation =
7128 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2217aa22013-10-11 03:03:547129
7130 // Ensure load is not disrupted by flags which suppress behaviour specific
7131 // to other auth schemes.
7132 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:247133
Zentaro Kavanagh6ccee512017-09-28 18:34:097134 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
7135 MockGetMSTime, MockGenerateRandom, MockGetHostName);
danakj1fd259a02016-04-16 03:17:097136 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277137
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377138 // Generate the NTLM messages based on known test data.
7139 std::string negotiate_msg;
7140 std::string challenge_msg;
7141 std::string authenticate_msg;
7142 base::Base64Encode(
7143 base::StringPiece(
7144 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
Avi Drissman4365a4782018-12-28 19:26:247145 base::size(ntlm::test::kExpectedNegotiateMsg)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377146 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:557147 base::Base64Encode(
7148 base::StringPiece(
7149 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
Avi Drissman4365a4782018-12-28 19:26:247150 base::size(ntlm::test::kChallengeMsgFromSpecV2)),
Zentaro Kavanagh1890a3d2018-01-29 19:52:557151 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377152 base::Base64Encode(
7153 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:097154 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557155 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
Avi Drissman4365a4782018-12-28 19:26:247156 base::size(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557157 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377158 &authenticate_msg);
7159
[email protected]3f918782009-02-28 01:29:247160 MockWrite data_writes1[] = {
Zentaro Kavanagh1890a3d2018-01-29 19:52:557161 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
7162 "Host: server\r\n"
7163 "Connection: keep-alive\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:247164 };
7165
7166 MockRead data_reads1[] = {
7167 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:047168 // Negotiate and NTLM are often requested together. However, we only want
7169 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
7170 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:247171 MockRead("WWW-Authenticate: NTLM\r\n"),
7172 MockRead("Connection: close\r\n"),
7173 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:367174 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:247175 // Missing content -- won't matter, as connection will be reset.
[email protected]3f918782009-02-28 01:29:247176 };
7177
7178 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:167179 // After restarting with a null identity, this is the
7180 // request we should be issuing -- the final header line contains a Type
7181 // 1 message.
7182 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557183 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167184 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377185 "Authorization: NTLM "),
7186 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:247187
bnc691fda62016-08-12 00:43:167188 // After calling trans.RestartWithAuth(), we should send a Type 3 message
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377189 // (using correct credentials). The second request continues on the
7190 // same connection.
bnc691fda62016-08-12 00:43:167191 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557192 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167193 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377194 "Authorization: NTLM "),
7195 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:247196 };
7197
7198 MockRead data_reads2[] = {
Bence Béky1e4ef192017-09-18 19:58:027199 // The origin server responds with a Type 2 message.
7200 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377201 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
7202 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky1e4ef192017-09-18 19:58:027203 MockRead("Content-Type: text/html\r\n\r\n"),
7204 MockRead("You are not authorized to view this page\r\n"),
[email protected]3f918782009-02-28 01:29:247205
Bence Béky1e4ef192017-09-18 19:58:027206 // Lastly we get the desired content.
7207 MockRead("HTTP/1.1 200 OK\r\n"),
7208 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
7209 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
[email protected]3f918782009-02-28 01:29:247210 };
7211
Ryan Sleevib8d7ea02018-05-07 20:01:017212 StaticSocketDataProvider data1(data_reads1, data_writes1);
7213 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:077214 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7215 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:247216
Bence Béky83eb3512017-09-05 12:56:097217 SSLSocketDataProvider ssl1(ASYNC, OK);
7218 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
7219 SSLSocketDataProvider ssl2(ASYNC, OK);
7220 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
7221
[email protected]49639fa2011-12-20 23:22:417222 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:247223
bnc691fda62016-08-12 00:43:167224 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:507225
tfarina42834112016-09-22 13:38:207226 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017227 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:247228
7229 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017230 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:247231
bnc691fda62016-08-12 00:43:167232 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227233
bnc691fda62016-08-12 00:43:167234 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527235 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047236 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:247237
[email protected]49639fa2011-12-20 23:22:417238 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:257239
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377240 rv = trans.RestartWithAuth(
7241 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
7242 callback2.callback());
robpercival214763f2016-07-01 23:27:017243 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:257244
7245 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017246 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:257247
bnc691fda62016-08-12 00:43:167248 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:257249
bnc691fda62016-08-12 00:43:167250 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527251 ASSERT_TRUE(response);
7252 EXPECT_FALSE(response->auth_challenge);
[email protected]10af5fe72011-01-31 16:17:257253
[email protected]49639fa2011-12-20 23:22:417254 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:247255
bnc691fda62016-08-12 00:43:167256 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:017257 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:247258
[email protected]0757e7702009-03-27 04:00:227259 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017260 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:247261
bnc691fda62016-08-12 00:43:167262 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527263 ASSERT_TRUE(response);
7264 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:027265 EXPECT_EQ(14, response->headers->GetContentLength());
7266
7267 std::string response_data;
7268 rv = ReadTransaction(&trans, &response_data);
7269 EXPECT_THAT(rv, IsOk());
7270 EXPECT_EQ("Please Login\r\n", response_data);
7271
7272 EXPECT_TRUE(data1.AllReadDataConsumed());
7273 EXPECT_TRUE(data1.AllWriteDataConsumed());
7274 EXPECT_TRUE(data2.AllReadDataConsumed());
7275 EXPECT_TRUE(data2.AllWriteDataConsumed());
[email protected]3f918782009-02-28 01:29:247276}
7277
[email protected]385a4672009-03-11 22:21:297278// Enter a wrong password, and then the correct one.
Zentaro Kavanagh1890a3d2018-01-29 19:52:557279TEST_F(HttpNetworkTransactionTest, NTLMAuthV2WrongThenRightPassword) {
[email protected]1c773ea12009-04-28 19:58:427280 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:297281 request.method = "GET";
Zentaro Kavanagh1890a3d2018-01-29 19:52:557282 request.url = GURL("https://server/kids/login.aspx");
Ramin Halavatib5e433e2018-02-07 07:41:107283 request.traffic_annotation =
7284 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]385a4672009-03-11 22:21:297285
Zentaro Kavanagh6ccee512017-09-28 18:34:097286 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
7287 MockGetMSTime, MockGenerateRandom, MockGetHostName);
danakj1fd259a02016-04-16 03:17:097288 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277289
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377290 // Generate the NTLM messages based on known test data.
7291 std::string negotiate_msg;
7292 std::string challenge_msg;
7293 std::string authenticate_msg;
7294 base::Base64Encode(
7295 base::StringPiece(
7296 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
Avi Drissman4365a4782018-12-28 19:26:247297 base::size(ntlm::test::kExpectedNegotiateMsg)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377298 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:557299 base::Base64Encode(
7300 base::StringPiece(
7301 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
Avi Drissman4365a4782018-12-28 19:26:247302 base::size(ntlm::test::kChallengeMsgFromSpecV2)),
Zentaro Kavanagh1890a3d2018-01-29 19:52:557303 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377304 base::Base64Encode(
7305 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:097306 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557307 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
Avi Drissman4365a4782018-12-28 19:26:247308 base::size(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557309 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377310 &authenticate_msg);
7311
7312 // The authenticate message when |kWrongPassword| is sent.
7313 std::string wrong_password_authenticate_msg(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557314 "TlRMTVNTUAADAAAAGAAYAFgAAACKAIoAcAAAAAwADAD6AAAACAAIAAYBAAAQABAADgEAAAAA"
7315 "AABYAAAAA4IIAAAAAAAAAAAAAPknEYqtJQtusopDRSfYzAAAAAAAAAAAAAAAAAAAAAAAAAAA"
7316 "AAAAAOtVz38osnFdRRggUQHUJ3EBAQAAAAAAAIALyP0A1NIBqqqqqqqqqqoAAAAAAgAMAEQA"
7317 "bwBtAGEAaQBuAAEADABTAGUAcgB2AGUAcgAGAAQAAgAAAAoAEAAAAAAAAAAAAAAAAAAAAAAA"
7318 "CQAWAEgAVABUAFAALwBzAGUAcgB2AGUAcgAAAAAAAAAAAEQAbwBtAGEAaQBuAFUAcwBlAHIA"
7319 "QwBPAE0AUABVAFQARQBSAA==");
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377320
Zentaro Kavanagh1890a3d2018-01-29 19:52:557321 // Sanity check that it's the same length as the correct authenticate message
7322 // and that it's different.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377323 ASSERT_EQ(authenticate_msg.length(),
7324 wrong_password_authenticate_msg.length());
Zentaro Kavanagh1890a3d2018-01-29 19:52:557325 ASSERT_NE(authenticate_msg, wrong_password_authenticate_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377326
[email protected]385a4672009-03-11 22:21:297327 MockWrite data_writes1[] = {
Zentaro Kavanagh1890a3d2018-01-29 19:52:557328 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
7329 "Host: server\r\n"
7330 "Connection: keep-alive\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297331 };
7332
7333 MockRead data_reads1[] = {
7334 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:047335 // Negotiate and NTLM are often requested together. However, we only want
7336 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
7337 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:297338 MockRead("WWW-Authenticate: NTLM\r\n"),
7339 MockRead("Connection: close\r\n"),
7340 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:367341 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297342 // Missing content -- won't matter, as connection will be reset.
[email protected]385a4672009-03-11 22:21:297343 };
7344
7345 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:167346 // After restarting with a null identity, this is the
7347 // request we should be issuing -- the final header line contains a Type
7348 // 1 message.
7349 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557350 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167351 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377352 "Authorization: NTLM "),
7353 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297354
bnc691fda62016-08-12 00:43:167355 // After calling trans.RestartWithAuth(), we should send a Type 3 message
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377356 // (using incorrect credentials). The second request continues on the
7357 // same connection.
bnc691fda62016-08-12 00:43:167358 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557359 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167360 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377361 "Authorization: NTLM "),
7362 MockWrite(wrong_password_authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297363 };
7364
7365 MockRead data_reads2[] = {
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377366 // The origin server responds with a Type 2 message.
7367 MockRead("HTTP/1.1 401 Access Denied\r\n"),
7368 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
7369 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
7370 MockRead("Content-Type: text/html\r\n\r\n"),
7371 MockRead("You are not authorized to view this page\r\n"),
[email protected]385a4672009-03-11 22:21:297372
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377373 // Wrong password.
7374 MockRead("HTTP/1.1 401 Access Denied\r\n"),
7375 MockRead("WWW-Authenticate: NTLM\r\n"), MockRead("Connection: close\r\n"),
7376 MockRead("Content-Length: 42\r\n"),
7377 MockRead("Content-Type: text/html\r\n\r\n"),
7378 // Missing content -- won't matter, as connection will be reset.
[email protected]385a4672009-03-11 22:21:297379 };
7380
7381 MockWrite data_writes3[] = {
bnc691fda62016-08-12 00:43:167382 // After restarting with a null identity, this is the
7383 // request we should be issuing -- the final header line contains a Type
7384 // 1 message.
7385 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557386 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167387 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377388 "Authorization: NTLM "),
7389 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297390
bnc691fda62016-08-12 00:43:167391 // After calling trans.RestartWithAuth(), we should send a Type 3 message
7392 // (the credentials for the origin server). The second request continues
7393 // on the same connection.
7394 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557395 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167396 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377397 "Authorization: NTLM "),
7398 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297399 };
7400
7401 MockRead data_reads3[] = {
Bence Béky1e4ef192017-09-18 19:58:027402 // The origin server responds with a Type 2 message.
7403 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377404 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
7405 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky1e4ef192017-09-18 19:58:027406 MockRead("Content-Type: text/html\r\n\r\n"),
7407 MockRead("You are not authorized to view this page\r\n"),
[email protected]385a4672009-03-11 22:21:297408
Bence Béky1e4ef192017-09-18 19:58:027409 // Lastly we get the desired content.
7410 MockRead("HTTP/1.1 200 OK\r\n"),
7411 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
7412 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
[email protected]385a4672009-03-11 22:21:297413 };
7414
Ryan Sleevib8d7ea02018-05-07 20:01:017415 StaticSocketDataProvider data1(data_reads1, data_writes1);
7416 StaticSocketDataProvider data2(data_reads2, data_writes2);
7417 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]bb88e1d32013-05-03 23:11:077418 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7419 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7420 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:297421
Bence Béky83eb3512017-09-05 12:56:097422 SSLSocketDataProvider ssl1(ASYNC, OK);
7423 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
7424 SSLSocketDataProvider ssl2(ASYNC, OK);
7425 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
7426 SSLSocketDataProvider ssl3(ASYNC, OK);
7427 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
7428
[email protected]49639fa2011-12-20 23:22:417429 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:297430
bnc691fda62016-08-12 00:43:167431 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:507432
tfarina42834112016-09-22 13:38:207433 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017434 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:297435
7436 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017437 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:297438
bnc691fda62016-08-12 00:43:167439 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:297440
bnc691fda62016-08-12 00:43:167441 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527442 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047443 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:297444
[email protected]49639fa2011-12-20 23:22:417445 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:297446
[email protected]0757e7702009-03-27 04:00:227447 // Enter the wrong password.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377448 rv = trans.RestartWithAuth(
7449 AuthCredentials(ntlm::test::kDomainUserCombined, kWrongPassword),
7450 callback2.callback());
robpercival214763f2016-07-01 23:27:017451 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:297452
[email protected]10af5fe72011-01-31 16:17:257453 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017454 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:297455
bnc691fda62016-08-12 00:43:167456 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:417457 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:167458 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:017459 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:257460 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017461 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167462 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227463
bnc691fda62016-08-12 00:43:167464 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527465 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047466 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:227467
[email protected]49639fa2011-12-20 23:22:417468 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:227469
7470 // Now enter the right password.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377471 rv = trans.RestartWithAuth(
7472 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
7473 callback4.callback());
robpercival214763f2016-07-01 23:27:017474 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:257475
7476 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:017477 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:257478
bnc691fda62016-08-12 00:43:167479 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:257480
[email protected]49639fa2011-12-20 23:22:417481 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:257482
7483 // One more roundtrip
bnc691fda62016-08-12 00:43:167484 rv = trans.RestartWithAuth(AuthCredentials(), callback5.callback());
robpercival214763f2016-07-01 23:27:017485 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:227486
7487 rv = callback5.WaitForResult();
robpercival214763f2016-07-01 23:27:017488 EXPECT_THAT(rv, IsOk());
[email protected]0757e7702009-03-27 04:00:227489
bnc691fda62016-08-12 00:43:167490 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527491 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:027492 EXPECT_EQ(14, response->headers->GetContentLength());
7493
7494 std::string response_data;
7495 rv = ReadTransaction(&trans, &response_data);
7496 EXPECT_THAT(rv, IsOk());
7497 EXPECT_EQ("Please Login\r\n", response_data);
7498
7499 EXPECT_TRUE(data1.AllReadDataConsumed());
7500 EXPECT_TRUE(data1.AllWriteDataConsumed());
7501 EXPECT_TRUE(data2.AllReadDataConsumed());
7502 EXPECT_TRUE(data2.AllWriteDataConsumed());
7503 EXPECT_TRUE(data3.AllReadDataConsumed());
7504 EXPECT_TRUE(data3.AllWriteDataConsumed());
[email protected]385a4672009-03-11 22:21:297505}
Bence Béky83eb3512017-09-05 12:56:097506
Bence Béky3238f2e12017-09-22 22:44:497507// Server requests NTLM authentication, which is not supported over HTTP/2.
7508// Subsequent request with authorization header should be sent over HTTP/1.1.
Bence Béky83eb3512017-09-05 12:56:097509TEST_F(HttpNetworkTransactionTest, NTLMOverHttp2) {
Zentaro Kavanagh6ccee512017-09-28 18:34:097510 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
7511 MockGetMSTime, MockGenerateRandom, MockGetHostName);
Bence Béky83eb3512017-09-05 12:56:097512
Zentaro Kavanagh1890a3d2018-01-29 19:52:557513 const char* kUrl = "https://server/kids/login.aspx";
Bence Béky83eb3512017-09-05 12:56:097514
7515 HttpRequestInfo request;
7516 request.method = "GET";
7517 request.url = GURL(kUrl);
Ramin Halavatib5e433e2018-02-07 07:41:107518 request.traffic_annotation =
7519 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Béky83eb3512017-09-05 12:56:097520
7521 // First request without credentials.
Ryan Hamilton0239aac2018-05-19 00:03:137522 spdy::SpdyHeaderBlock request_headers0(
7523 spdy_util_.ConstructGetHeaderBlock(kUrl));
7524 spdy::SpdySerializedFrame request0(spdy_util_.ConstructSpdyHeaders(
Bence Béky83eb3512017-09-05 12:56:097525 1, std::move(request_headers0), LOWEST, true));
7526
Ryan Hamilton0239aac2018-05-19 00:03:137527 spdy::SpdyHeaderBlock response_headers0;
7528 response_headers0[spdy::kHttp2StatusHeader] = "401";
Bence Béky83eb3512017-09-05 12:56:097529 response_headers0["www-authenticate"] = "NTLM";
Ryan Hamilton0239aac2018-05-19 00:03:137530 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyResponseHeaders(
Bence Béky83eb3512017-09-05 12:56:097531 1, std::move(response_headers0), true));
7532
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377533 // Stream 1 is closed.
7534 spdy_util_.UpdateWithStreamDestruction(1);
7535
7536 // Generate the NTLM messages based on known test data.
7537 std::string negotiate_msg;
7538 std::string challenge_msg;
7539 std::string authenticate_msg;
7540 base::Base64Encode(
7541 base::StringPiece(
7542 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
Avi Drissman4365a4782018-12-28 19:26:247543 base::size(ntlm::test::kExpectedNegotiateMsg)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377544 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:557545 base::Base64Encode(
7546 base::StringPiece(
7547 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
Avi Drissman4365a4782018-12-28 19:26:247548 base::size(ntlm::test::kChallengeMsgFromSpecV2)),
Zentaro Kavanagh1890a3d2018-01-29 19:52:557549 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377550 base::Base64Encode(
7551 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:097552 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557553 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
Avi Drissman4365a4782018-12-28 19:26:247554 base::size(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557555 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377556 &authenticate_msg);
7557
7558 // Retry with authorization header.
Ryan Hamilton0239aac2018-05-19 00:03:137559 spdy::SpdyHeaderBlock request_headers1(
7560 spdy_util_.ConstructGetHeaderBlock(kUrl));
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377561 request_headers1["authorization"] = std::string("NTLM ") + negotiate_msg;
Ryan Hamilton0239aac2018-05-19 00:03:137562 spdy::SpdySerializedFrame request1(spdy_util_.ConstructSpdyHeaders(
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377563 3, std::move(request_headers1), LOWEST, true));
7564
Ryan Hamilton0239aac2018-05-19 00:03:137565 spdy::SpdySerializedFrame rst(
7566 spdy_util_.ConstructSpdyRstStream(3, spdy::ERROR_CODE_HTTP_1_1_REQUIRED));
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377567
Bence Béky3238f2e12017-09-22 22:44:497568 MockWrite writes0[] = {CreateMockWrite(request0, 0)};
7569 MockRead reads0[] = {CreateMockRead(resp, 1), MockRead(ASYNC, 0, 2)};
Bence Béky83eb3512017-09-05 12:56:097570
7571 // Retry yet again using HTTP/1.1.
7572 MockWrite writes1[] = {
7573 // After restarting with a null identity, this is the
7574 // request we should be issuing -- the final header line contains a Type
7575 // 1 message.
7576 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557577 "Host: server\r\n"
Bence Béky83eb3512017-09-05 12:56:097578 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377579 "Authorization: NTLM "),
7580 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
Bence Béky83eb3512017-09-05 12:56:097581
7582 // After calling trans.RestartWithAuth(), we should send a Type 3 message
7583 // (the credentials for the origin server). The second request continues
7584 // on the same connection.
7585 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557586 "Host: server\r\n"
Bence Béky83eb3512017-09-05 12:56:097587 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377588 "Authorization: NTLM "),
7589 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
Bence Béky83eb3512017-09-05 12:56:097590 };
7591
7592 MockRead reads1[] = {
7593 // The origin server responds with a Type 2 message.
7594 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377595 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
7596 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky83eb3512017-09-05 12:56:097597 MockRead("Content-Type: text/html\r\n\r\n"),
7598 MockRead("You are not authorized to view this page\r\n"),
7599
7600 // Lastly we get the desired content.
7601 MockRead("HTTP/1.1 200 OK\r\n"),
7602 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
Bence Béky1e4ef192017-09-18 19:58:027603 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
Bence Béky83eb3512017-09-05 12:56:097604 };
Ryan Sleevib8d7ea02018-05-07 20:01:017605 SequencedSocketData data0(reads0, writes0);
7606 StaticSocketDataProvider data1(reads1, writes1);
Bence Béky83eb3512017-09-05 12:56:097607 session_deps_.socket_factory->AddSocketDataProvider(&data0);
7608 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7609
7610 SSLSocketDataProvider ssl0(ASYNC, OK);
7611 ssl0.next_proto = kProtoHTTP2;
7612 SSLSocketDataProvider ssl1(ASYNC, OK);
7613 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl0);
7614 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
7615
7616 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7617 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
7618
7619 TestCompletionCallback callback1;
7620 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
7621 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7622
7623 rv = callback1.WaitForResult();
7624 EXPECT_THAT(rv, IsOk());
7625
7626 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
7627
7628 const HttpResponseInfo* response = trans.GetResponseInfo();
7629 ASSERT_TRUE(response);
7630 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
7631
7632 TestCompletionCallback callback2;
7633
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377634 rv = trans.RestartWithAuth(
7635 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
7636 callback2.callback());
Bence Béky83eb3512017-09-05 12:56:097637 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7638
7639 rv = callback2.WaitForResult();
7640 EXPECT_THAT(rv, IsOk());
7641
7642 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
7643
7644 response = trans.GetResponseInfo();
7645 ASSERT_TRUE(response);
7646 EXPECT_FALSE(response->auth_challenge);
7647
7648 TestCompletionCallback callback3;
7649
7650 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
7651 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7652
7653 rv = callback3.WaitForResult();
7654 EXPECT_THAT(rv, IsOk());
7655
7656 response = trans.GetResponseInfo();
7657 ASSERT_TRUE(response);
7658 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:027659 EXPECT_EQ(14, response->headers->GetContentLength());
7660
7661 std::string response_data;
7662 rv = ReadTransaction(&trans, &response_data);
7663 EXPECT_THAT(rv, IsOk());
7664 EXPECT_EQ("Please Login\r\n", response_data);
7665
7666 EXPECT_TRUE(data0.AllReadDataConsumed());
7667 EXPECT_TRUE(data0.AllWriteDataConsumed());
7668 EXPECT_TRUE(data1.AllReadDataConsumed());
7669 EXPECT_TRUE(data1.AllWriteDataConsumed());
Bence Béky83eb3512017-09-05 12:56:097670}
David Benjamin5cb91132018-04-06 05:54:497671
7672// Test that, if we have an NTLM proxy and the origin resets the connection, we
7673// do no retry forever checking for TLS version interference. This is a
7674// regression test for https://crbug.com/823387.
7675TEST_F(HttpNetworkTransactionTest, NTLMProxyTLSHandshakeReset) {
7676 // The NTLM test data expects the proxy to be named 'server'. The origin is
7677 // https://origin/.
7678 session_deps_.proxy_resolution_service =
7679 ProxyResolutionService::CreateFixedFromPacResult(
7680 "PROXY server", TRAFFIC_ANNOTATION_FOR_TESTS);
7681
7682 SSLConfig config;
David Benjamin5cb91132018-04-06 05:54:497683 session_deps_.ssl_config_service =
Ryan Sleevib8449e02018-07-15 04:31:077684 std::make_unique<TestSSLConfigService>(config);
David Benjamin5cb91132018-04-06 05:54:497685
7686 HttpRequestInfo request;
7687 request.method = "GET";
7688 request.url = GURL("https://origin/");
7689 request.traffic_annotation =
7690 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7691
7692 // Ensure load is not disrupted by flags which suppress behaviour specific
7693 // to other auth schemes.
7694 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
7695
7696 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
7697 MockGetMSTime, MockGenerateRandom, MockGetHostName);
7698 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7699
7700 // Generate the NTLM messages based on known test data.
7701 std::string negotiate_msg;
7702 std::string challenge_msg;
7703 std::string authenticate_msg;
7704 base::Base64Encode(
7705 base::StringPiece(
7706 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
Avi Drissman4365a4782018-12-28 19:26:247707 base::size(ntlm::test::kExpectedNegotiateMsg)),
David Benjamin5cb91132018-04-06 05:54:497708 &negotiate_msg);
7709 base::Base64Encode(
7710 base::StringPiece(
7711 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
Avi Drissman4365a4782018-12-28 19:26:247712 base::size(ntlm::test::kChallengeMsgFromSpecV2)),
David Benjamin5cb91132018-04-06 05:54:497713 &challenge_msg);
7714 base::Base64Encode(
7715 base::StringPiece(
7716 reinterpret_cast<const char*>(
7717 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
Avi Drissman4365a4782018-12-28 19:26:247718 base::size(
David Benjamin5cb91132018-04-06 05:54:497719 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
7720 &authenticate_msg);
7721
7722 MockWrite data_writes[] = {
7723 // The initial CONNECT request.
7724 MockWrite("CONNECT origin:443 HTTP/1.1\r\n"
7725 "Host: origin:443\r\n"
7726 "Proxy-Connection: keep-alive\r\n\r\n"),
7727
7728 // After restarting with an identity.
7729 MockWrite("CONNECT origin:443 HTTP/1.1\r\n"
7730 "Host: origin:443\r\n"
7731 "Proxy-Connection: keep-alive\r\n"
7732 "Proxy-Authorization: NTLM "),
7733 MockWrite(negotiate_msg.c_str()),
7734 // End headers.
7735 MockWrite("\r\n\r\n"),
7736
7737 // The second restart.
7738 MockWrite("CONNECT origin:443 HTTP/1.1\r\n"
7739 "Host: origin:443\r\n"
7740 "Proxy-Connection: keep-alive\r\n"
7741 "Proxy-Authorization: NTLM "),
7742 MockWrite(authenticate_msg.c_str()),
7743 // End headers.
7744 MockWrite("\r\n\r\n"),
7745 };
7746
7747 MockRead data_reads[] = {
7748 // The initial NTLM response.
7749 MockRead("HTTP/1.1 407 Access Denied\r\n"
7750 "Content-Length: 0\r\n"
7751 "Proxy-Authenticate: NTLM\r\n\r\n"),
7752
7753 // The NTLM challenge message.
7754 MockRead("HTTP/1.1 407 Access Denied\r\n"
7755 "Content-Length: 0\r\n"
7756 "Proxy-Authenticate: NTLM "),
7757 MockRead(challenge_msg.c_str()),
7758 // End headers.
7759 MockRead("\r\n\r\n"),
7760
7761 // Finally the tunnel is established.
7762 MockRead("HTTP/1.1 200 Connected\r\n\r\n"),
7763 };
7764
Ryan Sleevib8d7ea02018-05-07 20:01:017765 StaticSocketDataProvider data(data_reads, data_writes);
David Benjamin5cb91132018-04-06 05:54:497766 SSLSocketDataProvider data_ssl(ASYNC, ERR_CONNECTION_RESET);
Ryan Sleevib8d7ea02018-05-07 20:01:017767 StaticSocketDataProvider data2(data_reads, data_writes);
David Benjamin5cb91132018-04-06 05:54:497768 SSLSocketDataProvider data_ssl2(ASYNC, ERR_CONNECTION_RESET);
Steven Valdez0ef94d02018-11-19 23:28:137769 data_ssl2.expected_ssl_version_max = SSL_PROTOCOL_VERSION_TLS1_2;
David Benjamin5cb91132018-04-06 05:54:497770 session_deps_.socket_factory->AddSocketDataProvider(&data);
7771 session_deps_.socket_factory->AddSSLSocketDataProvider(&data_ssl);
7772 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7773 session_deps_.socket_factory->AddSSLSocketDataProvider(&data_ssl2);
7774
7775 // Start the transaction. The proxy responds with an NTLM authentication
7776 // request.
7777 TestCompletionCallback callback;
7778 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
7779 int rv = callback.GetResult(
7780 trans.Start(&request, callback.callback(), NetLogWithSource()));
7781
7782 EXPECT_THAT(rv, IsOk());
7783 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
7784 const HttpResponseInfo* response = trans.GetResponseInfo();
7785 ASSERT_TRUE(response);
7786 EXPECT_TRUE(CheckNTLMProxyAuth(response->auth_challenge.get()));
7787
7788 // Configure credentials. The proxy responds with the challenge message.
7789 rv = callback.GetResult(trans.RestartWithAuth(
7790 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
7791 callback.callback()));
7792 EXPECT_THAT(rv, IsOk());
7793 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
7794 response = trans.GetResponseInfo();
7795 ASSERT_TRUE(response);
7796 EXPECT_FALSE(response->auth_challenge);
7797
7798 // Restart once more. The tunnel will be established and the the SSL handshake
7799 // will reset. The TLS 1.3 version interference probe will then kick in and
7800 // restart the process. The proxy responds with another NTLM authentiation
7801 // request, but we don't need to provide credentials as the cached ones work/
7802 rv = callback.GetResult(
7803 trans.RestartWithAuth(AuthCredentials(), callback.callback()));
7804 EXPECT_THAT(rv, IsOk());
7805 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
7806 response = trans.GetResponseInfo();
7807 ASSERT_TRUE(response);
7808 EXPECT_FALSE(response->auth_challenge);
7809
7810 // The proxy responds with the NTLM challenge message.
7811 rv = callback.GetResult(
7812 trans.RestartWithAuth(AuthCredentials(), callback.callback()));
7813 EXPECT_THAT(rv, IsOk());
7814 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
7815 response = trans.GetResponseInfo();
7816 ASSERT_TRUE(response);
7817 EXPECT_FALSE(response->auth_challenge);
7818
7819 // Send the NTLM authenticate message. The tunnel is established and the
7820 // handshake resets again. We should not retry again.
7821 rv = callback.GetResult(
7822 trans.RestartWithAuth(AuthCredentials(), callback.callback()));
7823 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
7824}
7825
[email protected]ea9dc9a2009-09-05 00:43:327826#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:297827
[email protected]4ddaf2502008-10-23 18:26:197828// Test reading a server response which has only headers, and no body.
7829// After some maximum number of bytes is consumed, the transaction should
7830// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
bncd16676a2016-07-20 16:23:017831TEST_F(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:427832 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:197833 request.method = "GET";
bncce36dca22015-04-21 22:11:237834 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:107835 request.traffic_annotation =
7836 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]4ddaf2502008-10-23 18:26:197837
danakj1fd259a02016-04-16 03:17:097838 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167839 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277840
[email protected]b75b7b2f2009-10-06 00:54:537841 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:437842 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:537843 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:197844
7845 MockRead data_reads[] = {
7846 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:067847 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:197848 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:067849 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:197850 };
Ryan Sleevib8d7ea02018-05-07 20:01:017851 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:077852 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:197853
[email protected]49639fa2011-12-20 23:22:417854 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:197855
tfarina42834112016-09-22 13:38:207856 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017857 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]4ddaf2502008-10-23 18:26:197858
7859 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017860 EXPECT_THAT(rv, IsError(ERR_RESPONSE_HEADERS_TOO_BIG));
[email protected]4ddaf2502008-10-23 18:26:197861}
[email protected]f4e426b2008-11-05 00:24:497862
7863// Make sure that we don't try to reuse a TCPClientSocket when failing to
7864// establish tunnel.
7865// http://code.google.com/p/chromium/issues/detail?id=3772
bncd16676a2016-07-20 16:23:017866TEST_F(HttpNetworkTransactionTest, DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:277867 HttpRequestInfo request;
7868 request.method = "GET";
bncce36dca22015-04-21 22:11:237869 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:107870 request.traffic_annotation =
7871 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:277872
[email protected]f4e426b2008-11-05 00:24:497873 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:497874 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
7875 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]db8f44c2008-12-13 04:52:017876
danakj1fd259a02016-04-16 03:17:097877 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:497878
bnc87dcefc2017-05-25 12:47:587879 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:197880 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]f4e426b2008-11-05 00:24:497881
[email protected]f4e426b2008-11-05 00:24:497882 // Since we have proxy, should try to establish tunnel.
7883 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:177884 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7885 "Host: www.example.org:443\r\n"
7886 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:497887 };
7888
[email protected]77848d12008-11-14 00:00:227889 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:497890 // connection. Usually a proxy would return 501 (not implemented),
7891 // or 200 (tunnel established).
7892 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:237893 MockRead("HTTP/1.1 404 Not Found\r\n"),
7894 MockRead("Content-Length: 10\r\n\r\n"),
7895 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]f4e426b2008-11-05 00:24:497896 };
7897
Ryan Sleevib8d7ea02018-05-07 20:01:017898 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:077899 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:497900
[email protected]49639fa2011-12-20 23:22:417901 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:497902
tfarina42834112016-09-22 13:38:207903 int rv = trans->Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017904 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f4e426b2008-11-05 00:24:497905
7906 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017907 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]f4e426b2008-11-05 00:24:497908
[email protected]b4404c02009-04-10 16:38:527909 // Empty the current queue. This is necessary because idle sockets are
7910 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557911 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:527912
[email protected]f4e426b2008-11-05 00:24:497913 // We now check to make sure the TCPClientSocket was not added back to
7914 // the pool.
[email protected]90499482013-06-01 00:39:507915 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:497916 trans.reset();
fdoray92e35a72016-06-10 15:54:557917 base::RunLoop().RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:497918 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:507919 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:497920}
[email protected]372d34a2008-11-05 21:30:517921
[email protected]1b157c02009-04-21 01:55:407922// Make sure that we recycle a socket after reading all of the response body.
bncd16676a2016-07-20 16:23:017923TEST_F(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:427924 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:407925 request.method = "GET";
bncce36dca22015-04-21 22:11:237926 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:107927 request.traffic_annotation =
7928 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1b157c02009-04-21 01:55:407929
danakj1fd259a02016-04-16 03:17:097930 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277931
bnc691fda62016-08-12 00:43:167932 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277933
[email protected]1b157c02009-04-21 01:55:407934 MockRead data_reads[] = {
7935 // A part of the response body is received with the response headers.
7936 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
7937 // The rest of the response body is received in two parts.
7938 MockRead("lo"),
7939 MockRead(" world"),
7940 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:067941 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:407942 };
7943
Ryan Sleevib8d7ea02018-05-07 20:01:017944 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:077945 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:407946
[email protected]49639fa2011-12-20 23:22:417947 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:407948
tfarina42834112016-09-22 13:38:207949 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017950 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1b157c02009-04-21 01:55:407951
7952 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017953 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:407954
bnc691fda62016-08-12 00:43:167955 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527956 ASSERT_TRUE(response);
[email protected]1b157c02009-04-21 01:55:407957
wezca1070932016-05-26 20:30:527958 EXPECT_TRUE(response->headers);
[email protected]1b157c02009-04-21 01:55:407959 std::string status_line = response->headers->GetStatusLine();
7960 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
7961
[email protected]90499482013-06-01 00:39:507962 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:407963
7964 std::string response_data;
bnc691fda62016-08-12 00:43:167965 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017966 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:407967 EXPECT_EQ("hello world", response_data);
7968
7969 // Empty the current queue. This is necessary because idle sockets are
7970 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557971 base::RunLoop().RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:407972
7973 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507974 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:407975}
7976
[email protected]76a505b2010-08-25 06:23:007977// Make sure that we recycle a SSL socket after reading all of the response
7978// body.
bncd16676a2016-07-20 16:23:017979TEST_F(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:007980 HttpRequestInfo request;
7981 request.method = "GET";
bncce36dca22015-04-21 22:11:237982 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:107983 request.traffic_annotation =
7984 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:007985
7986 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237987 MockWrite(
7988 "GET / HTTP/1.1\r\n"
7989 "Host: www.example.org\r\n"
7990 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:007991 };
7992
7993 MockRead data_reads[] = {
7994 MockRead("HTTP/1.1 200 OK\r\n"),
7995 MockRead("Content-Length: 11\r\n\r\n"),
7996 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:067997 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:007998 };
7999
[email protected]8ddf8322012-02-23 18:08:068000 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078001 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:008002
Ryan Sleevib8d7ea02018-05-07 20:01:018003 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:078004 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:008005
[email protected]49639fa2011-12-20 23:22:418006 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:008007
danakj1fd259a02016-04-16 03:17:098008 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168009 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:008010
tfarina42834112016-09-22 13:38:208011 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:008012
robpercival214763f2016-07-01 23:27:018013 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8014 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:008015
bnc691fda62016-08-12 00:43:168016 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528017 ASSERT_TRUE(response);
8018 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:008019 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8020
[email protected]90499482013-06-01 00:39:508021 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008022
8023 std::string response_data;
bnc691fda62016-08-12 00:43:168024 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:018025 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:008026 EXPECT_EQ("hello world", response_data);
8027
8028 // Empty the current queue. This is necessary because idle sockets are
8029 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:558030 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:008031
8032 // We now check to make sure the socket was added back to the pool.
Matt Menke9d5e2c92019-02-05 01:42:238033 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008034}
8035
8036// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
8037// from the pool and make sure that we recover okay.
bncd16676a2016-07-20 16:23:018038TEST_F(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:008039 HttpRequestInfo request;
8040 request.method = "GET";
bncce36dca22015-04-21 22:11:238041 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:108042 request.traffic_annotation =
8043 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:008044
8045 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238046 MockWrite(
8047 "GET / HTTP/1.1\r\n"
8048 "Host: www.example.org\r\n"
8049 "Connection: keep-alive\r\n\r\n"),
8050 MockWrite(
8051 "GET / HTTP/1.1\r\n"
8052 "Host: www.example.org\r\n"
8053 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:008054 };
8055
8056 MockRead data_reads[] = {
mmenke911ee0222015-12-04 03:58:428057 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
8058 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
[email protected]76a505b2010-08-25 06:23:008059
[email protected]8ddf8322012-02-23 18:08:068060 SSLSocketDataProvider ssl(ASYNC, OK);
8061 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078062 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8063 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:008064
Ryan Sleevib8d7ea02018-05-07 20:01:018065 StaticSocketDataProvider data(data_reads, data_writes);
8066 StaticSocketDataProvider data2(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:078067 session_deps_.socket_factory->AddSocketDataProvider(&data);
8068 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:008069
[email protected]49639fa2011-12-20 23:22:418070 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:008071
danakj1fd259a02016-04-16 03:17:098072 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:588073 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:198074 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:008075
tfarina42834112016-09-22 13:38:208076 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:008077
robpercival214763f2016-07-01 23:27:018078 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8079 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:008080
8081 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528082 ASSERT_TRUE(response);
8083 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:008084 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8085
[email protected]90499482013-06-01 00:39:508086 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008087
8088 std::string response_data;
8089 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018090 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:008091 EXPECT_EQ("hello world", response_data);
8092
8093 // Empty the current queue. This is necessary because idle sockets are
8094 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:558095 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:008096
8097 // We now check to make sure the socket was added back to the pool.
Matt Menke9d5e2c92019-02-05 01:42:238098 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008099
8100 // Now start the second transaction, which should reuse the previous socket.
8101
bnc87dcefc2017-05-25 12:47:588102 trans =
Jeremy Roman0579ed62017-08-29 15:56:198103 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:008104
tfarina42834112016-09-22 13:38:208105 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:008106
robpercival214763f2016-07-01 23:27:018107 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8108 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:008109
8110 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528111 ASSERT_TRUE(response);
8112 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:008113 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8114
[email protected]90499482013-06-01 00:39:508115 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008116
8117 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018118 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:008119 EXPECT_EQ("hello world", response_data);
8120
8121 // Empty the current queue. This is necessary because idle sockets are
8122 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:558123 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:008124
8125 // We now check to make sure the socket was added back to the pool.
Matt Menke9d5e2c92019-02-05 01:42:238126 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008127}
8128
maksim.sisov0adf8592016-07-15 06:25:568129// Grab a socket, use it, and put it back into the pool. Then, make
8130// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:018131TEST_F(HttpNetworkTransactionTest, FlushSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:568132 HttpRequestInfo request;
8133 request.method = "GET";
8134 request.url = GURL("http://www.example.org/");
8135 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:108136 request.traffic_annotation =
8137 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
maksim.sisov0adf8592016-07-15 06:25:568138
8139 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8140
bnc691fda62016-08-12 00:43:168141 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:568142
8143 MockRead data_reads[] = {
8144 // A part of the response body is received with the response headers.
8145 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
8146 // The rest of the response body is received in two parts.
8147 MockRead("lo"), MockRead(" world"),
8148 MockRead("junk"), // Should not be read!!
8149 MockRead(SYNCHRONOUS, OK),
8150 };
8151
Ryan Sleevib8d7ea02018-05-07 20:01:018152 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
maksim.sisov0adf8592016-07-15 06:25:568153 session_deps_.socket_factory->AddSocketDataProvider(&data);
8154
8155 TestCompletionCallback callback;
8156
tfarina42834112016-09-22 13:38:208157 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:568158 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8159
8160 EXPECT_THAT(callback.GetResult(rv), IsOk());
8161
bnc691fda62016-08-12 00:43:168162 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:568163 ASSERT_TRUE(response);
8164 EXPECT_TRUE(response->headers);
8165 std::string status_line = response->headers->GetStatusLine();
8166 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
8167
8168 // Make memory critical notification and ensure the transaction still has been
8169 // operating right.
8170 base::MemoryPressureListener::NotifyMemoryPressure(
8171 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8172 base::RunLoop().RunUntilIdle();
8173
8174 // Socket should not be flushed as long as it is not idle.
8175 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
8176
8177 std::string response_data;
bnc691fda62016-08-12 00:43:168178 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:568179 EXPECT_THAT(rv, IsOk());
8180 EXPECT_EQ("hello world", response_data);
8181
8182 // Empty the current queue. This is necessary because idle sockets are
8183 // added to the connection pool asynchronously with a PostTask.
8184 base::RunLoop().RunUntilIdle();
8185
8186 // We now check to make sure the socket was added back to the pool.
8187 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
8188
8189 // Idle sockets should be flushed now.
8190 base::MemoryPressureListener::NotifyMemoryPressure(
8191 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8192 base::RunLoop().RunUntilIdle();
8193
8194 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
8195}
8196
yucliu48f235d2018-01-11 00:59:558197// Disable idle socket closing on memory pressure.
8198// Grab a socket, use it, and put it back into the pool. Then, make
8199// low memory notification and ensure the socket pool is NOT flushed.
8200TEST_F(HttpNetworkTransactionTest, NoFlushSocketPoolOnLowMemoryNotifications) {
8201 HttpRequestInfo request;
8202 request.method = "GET";
8203 request.url = GURL("http://www.example.org/");
8204 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:108205 request.traffic_annotation =
8206 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
yucliu48f235d2018-01-11 00:59:558207
8208 // Disable idle socket closing on memory pressure.
8209 session_deps_.disable_idle_sockets_close_on_memory_pressure = true;
8210 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8211
8212 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
8213
8214 MockRead data_reads[] = {
8215 // A part of the response body is received with the response headers.
8216 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
8217 // The rest of the response body is received in two parts.
8218 MockRead("lo"), MockRead(" world"),
8219 MockRead("junk"), // Should not be read!!
8220 MockRead(SYNCHRONOUS, OK),
8221 };
8222
Ryan Sleevib8d7ea02018-05-07 20:01:018223 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
yucliu48f235d2018-01-11 00:59:558224 session_deps_.socket_factory->AddSocketDataProvider(&data);
8225
8226 TestCompletionCallback callback;
8227
8228 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
8229 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8230
8231 EXPECT_THAT(callback.GetResult(rv), IsOk());
8232
8233 const HttpResponseInfo* response = trans.GetResponseInfo();
8234 ASSERT_TRUE(response);
8235 EXPECT_TRUE(response->headers);
8236 std::string status_line = response->headers->GetStatusLine();
8237 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
8238
8239 // Make memory critical notification and ensure the transaction still has been
8240 // operating right.
8241 base::MemoryPressureListener::NotifyMemoryPressure(
8242 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8243 base::RunLoop().RunUntilIdle();
8244
8245 // Socket should not be flushed as long as it is not idle.
8246 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
8247
8248 std::string response_data;
8249 rv = ReadTransaction(&trans, &response_data);
8250 EXPECT_THAT(rv, IsOk());
8251 EXPECT_EQ("hello world", response_data);
8252
8253 // Empty the current queue. This is necessary because idle sockets are
8254 // added to the connection pool asynchronously with a PostTask.
8255 base::RunLoop().RunUntilIdle();
8256
8257 // We now check to make sure the socket was added back to the pool.
8258 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
8259
8260 // Idle sockets should NOT be flushed on moderate memory pressure.
8261 base::MemoryPressureListener::NotifyMemoryPressure(
8262 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE);
8263 base::RunLoop().RunUntilIdle();
8264
8265 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
8266
8267 // Idle sockets should NOT be flushed on critical memory pressure.
8268 base::MemoryPressureListener::NotifyMemoryPressure(
8269 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8270 base::RunLoop().RunUntilIdle();
8271
8272 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
8273}
8274
maksim.sisov0adf8592016-07-15 06:25:568275// Grab an SSL socket, use it, and put it back into the pool. Then, make
8276// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:018277TEST_F(HttpNetworkTransactionTest, FlushSSLSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:568278 HttpRequestInfo request;
8279 request.method = "GET";
8280 request.url = GURL("https://www.example.org/");
8281 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:108282 request.traffic_annotation =
8283 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
maksim.sisov0adf8592016-07-15 06:25:568284
8285 MockWrite data_writes[] = {
8286 MockWrite("GET / HTTP/1.1\r\n"
8287 "Host: www.example.org\r\n"
8288 "Connection: keep-alive\r\n\r\n"),
8289 };
8290
8291 MockRead data_reads[] = {
8292 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
8293 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
8294
8295 SSLSocketDataProvider ssl(ASYNC, OK);
8296 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8297
Ryan Sleevib8d7ea02018-05-07 20:01:018298 StaticSocketDataProvider data(data_reads, data_writes);
maksim.sisov0adf8592016-07-15 06:25:568299 session_deps_.socket_factory->AddSocketDataProvider(&data);
8300
8301 TestCompletionCallback callback;
8302
8303 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168304 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:568305
Matt Menke9d5e2c92019-02-05 01:42:238306 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
tfarina42834112016-09-22 13:38:208307 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:568308
8309 EXPECT_THAT(callback.GetResult(rv), IsOk());
8310
bnc691fda62016-08-12 00:43:168311 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:568312 ASSERT_TRUE(response);
8313 ASSERT_TRUE(response->headers);
8314 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8315
8316 // Make memory critical notification and ensure the transaction still has been
8317 // operating right.
8318 base::MemoryPressureListener::NotifyMemoryPressure(
8319 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8320 base::RunLoop().RunUntilIdle();
8321
Matt Menke9d5e2c92019-02-05 01:42:238322 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
maksim.sisov0adf8592016-07-15 06:25:568323
8324 std::string response_data;
bnc691fda62016-08-12 00:43:168325 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:568326 EXPECT_THAT(rv, IsOk());
8327 EXPECT_EQ("hello world", response_data);
8328
8329 // Empty the current queue. This is necessary because idle sockets are
8330 // added to the connection pool asynchronously with a PostTask.
8331 base::RunLoop().RunUntilIdle();
8332
8333 // We now check to make sure the socket was added back to the pool.
Matt Menke9d5e2c92019-02-05 01:42:238334 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
maksim.sisov0adf8592016-07-15 06:25:568335
8336 // Make memory notification once again and ensure idle socket is closed.
8337 base::MemoryPressureListener::NotifyMemoryPressure(
8338 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8339 base::RunLoop().RunUntilIdle();
8340
Matt Menke9d5e2c92019-02-05 01:42:238341 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
maksim.sisov0adf8592016-07-15 06:25:568342}
8343
[email protected]b4404c02009-04-10 16:38:528344// Make sure that we recycle a socket after a zero-length response.
8345// http://crbug.com/9880
bncd16676a2016-07-20 16:23:018346TEST_F(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:428347 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:528348 request.method = "GET";
bncce36dca22015-04-21 22:11:238349 request.url = GURL(
8350 "http://www.example.org/csi?v=3&s=web&action=&"
8351 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
8352 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
8353 "rt=prt.2642,ol.2649,xjs.2951");
Ramin Halavatib5e433e2018-02-07 07:41:108354 request.traffic_annotation =
8355 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]b4404c02009-04-10 16:38:528356
danakj1fd259a02016-04-16 03:17:098357 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:278358
[email protected]b4404c02009-04-10 16:38:528359 MockRead data_reads[] = {
8360 MockRead("HTTP/1.1 204 No Content\r\n"
8361 "Content-Length: 0\r\n"
8362 "Content-Type: text/html\r\n\r\n"),
8363 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:068364 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:528365 };
8366
Ryan Sleevib8d7ea02018-05-07 20:01:018367 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:078368 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:528369
mmenkecc2298e2015-12-07 18:20:188370 // Transaction must be created after the MockReads, so it's destroyed before
8371 // them.
bnc691fda62016-08-12 00:43:168372 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkecc2298e2015-12-07 18:20:188373
[email protected]49639fa2011-12-20 23:22:418374 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:528375
tfarina42834112016-09-22 13:38:208376 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018377 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]b4404c02009-04-10 16:38:528378
8379 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018380 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:528381
bnc691fda62016-08-12 00:43:168382 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528383 ASSERT_TRUE(response);
[email protected]b4404c02009-04-10 16:38:528384
wezca1070932016-05-26 20:30:528385 EXPECT_TRUE(response->headers);
[email protected]b4404c02009-04-10 16:38:528386 std::string status_line = response->headers->GetStatusLine();
8387 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
8388
[email protected]90499482013-06-01 00:39:508389 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:528390
8391 std::string response_data;
bnc691fda62016-08-12 00:43:168392 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:018393 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:528394 EXPECT_EQ("", response_data);
8395
8396 // Empty the current queue. This is necessary because idle sockets are
8397 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:558398 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:528399
8400 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:508401 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:528402}
8403
bncd16676a2016-07-20 16:23:018404TEST_F(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
danakj1fd259a02016-04-16 03:17:098405 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:228406 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:198407 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:228408 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:278409
[email protected]1c773ea12009-04-28 19:58:428410 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:518411 // Transaction 1: a GET request that succeeds. The socket is recycled
8412 // after use.
8413 request[0].method = "GET";
8414 request[0].url = GURL("http://www.google.com/");
8415 request[0].load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:108416 request[0].traffic_annotation =
8417 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]372d34a2008-11-05 21:30:518418 // Transaction 2: a POST request. Reuses the socket kept alive from
8419 // transaction 1. The first attempts fails when writing the POST data.
8420 // This causes the transaction to retry with a new socket. The second
8421 // attempt succeeds.
8422 request[1].method = "POST";
8423 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:278424 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:518425 request[1].load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:108426 request[1].traffic_annotation =
8427 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]372d34a2008-11-05 21:30:518428
danakj1fd259a02016-04-16 03:17:098429 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:518430
8431 // The first socket is used for transaction 1 and the first attempt of
8432 // transaction 2.
8433
8434 // The response of transaction 1.
8435 MockRead data_reads1[] = {
8436 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
8437 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068438 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:518439 };
8440 // The mock write results of transaction 1 and the first attempt of
8441 // transaction 2.
8442 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:068443 MockWrite(SYNCHRONOUS, 64), // GET
8444 MockWrite(SYNCHRONOUS, 93), // POST
8445 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:518446 };
Ryan Sleevib8d7ea02018-05-07 20:01:018447 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]372d34a2008-11-05 21:30:518448
8449 // The second socket is used for the second attempt of transaction 2.
8450
8451 // The response of transaction 2.
8452 MockRead data_reads2[] = {
8453 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
8454 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:068455 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:518456 };
8457 // The mock write results of the second attempt of transaction 2.
8458 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:068459 MockWrite(SYNCHRONOUS, 93), // POST
8460 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:518461 };
Ryan Sleevib8d7ea02018-05-07 20:01:018462 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]372d34a2008-11-05 21:30:518463
[email protected]bb88e1d32013-05-03 23:11:078464 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8465 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:518466
thestig9d3bb0c2015-01-24 00:49:518467 const char* const kExpectedResponseData[] = {
[email protected]372d34a2008-11-05 21:30:518468 "hello world", "welcome"
8469 };
8470
8471 for (int i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:168472 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]372d34a2008-11-05 21:30:518473
[email protected]49639fa2011-12-20 23:22:418474 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:518475
tfarina42834112016-09-22 13:38:208476 int rv = trans.Start(&request[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018477 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]372d34a2008-11-05 21:30:518478
8479 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018480 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:518481
bnc691fda62016-08-12 00:43:168482 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528483 ASSERT_TRUE(response);
[email protected]372d34a2008-11-05 21:30:518484
wezca1070932016-05-26 20:30:528485 EXPECT_TRUE(response->headers);
[email protected]372d34a2008-11-05 21:30:518486 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8487
8488 std::string response_data;
bnc691fda62016-08-12 00:43:168489 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:018490 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:518491 EXPECT_EQ(kExpectedResponseData[i], response_data);
8492 }
8493}
[email protected]f9ee6b52008-11-08 06:46:238494
8495// Test the request-challenge-retry sequence for basic auth when there is
8496// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:168497// it fails the identity from the URL is used to answer the challenge.
bncd16676a2016-07-20 16:23:018498TEST_F(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:428499 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238500 request.method = "GET";
bncce36dca22015-04-21 22:11:238501 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:418502 request.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:108503 request.traffic_annotation =
8504 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]a97cca42009-08-14 01:00:298505
danakj1fd259a02016-04-16 03:17:098506 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168507 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278508
[email protected]a97cca42009-08-14 01:00:298509 // The password contains an escaped character -- for this test to pass it
8510 // will need to be unescaped by HttpNetworkTransaction.
8511 EXPECT_EQ("b%40r", request.url.password());
8512
[email protected]f9ee6b52008-11-08 06:46:238513 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238514 MockWrite(
8515 "GET / HTTP/1.1\r\n"
8516 "Host: www.example.org\r\n"
8517 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238518 };
8519
8520 MockRead data_reads1[] = {
8521 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8522 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8523 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068524 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238525 };
8526
[email protected]2262e3a2012-05-22 16:08:168527 // After the challenge above, the transaction will be restarted using the
8528 // identity from the url (foo, b@r) to answer the challenge.
8529 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238530 MockWrite(
8531 "GET / HTTP/1.1\r\n"
8532 "Host: www.example.org\r\n"
8533 "Connection: keep-alive\r\n"
8534 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:168535 };
8536
8537 MockRead data_reads2[] = {
8538 MockRead("HTTP/1.0 200 OK\r\n"),
8539 MockRead("Content-Length: 100\r\n\r\n"),
8540 MockRead(SYNCHRONOUS, OK),
8541 };
8542
Ryan Sleevib8d7ea02018-05-07 20:01:018543 StaticSocketDataProvider data1(data_reads1, data_writes1);
8544 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:078545 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8546 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:238547
[email protected]49639fa2011-12-20 23:22:418548 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:208549 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018550 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238551 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018552 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168553 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:168554
8555 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:168556 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:018557 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:168558 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018559 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168560 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:228561
bnc691fda62016-08-12 00:43:168562 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528563 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:168564
8565 // There is no challenge info, since the identity in URL worked.
wezca1070932016-05-26 20:30:528566 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:168567
8568 EXPECT_EQ(100, response->headers->GetContentLength());
8569
8570 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:558571 base::RunLoop().RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:168572}
8573
8574// Test the request-challenge-retry sequence for basic auth when there is an
8575// incorrect identity in the URL. The identity from the URL should be used only
8576// once.
bncd16676a2016-07-20 16:23:018577TEST_F(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:168578 HttpRequestInfo request;
8579 request.method = "GET";
8580 // Note: the URL has a username:password in it. The password "baz" is
8581 // wrong (should be "bar").
bncce36dca22015-04-21 22:11:238582 request.url = GURL("http://foo:[email protected]/");
[email protected]2262e3a2012-05-22 16:08:168583
8584 request.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:108585 request.traffic_annotation =
8586 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2262e3a2012-05-22 16:08:168587
danakj1fd259a02016-04-16 03:17:098588 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168589 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2262e3a2012-05-22 16:08:168590
8591 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238592 MockWrite(
8593 "GET / HTTP/1.1\r\n"
8594 "Host: www.example.org\r\n"
8595 "Connection: keep-alive\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:168596 };
8597
8598 MockRead data_reads1[] = {
8599 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8600 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8601 MockRead("Content-Length: 10\r\n\r\n"),
8602 MockRead(SYNCHRONOUS, ERR_FAILED),
8603 };
8604
8605 // After the challenge above, the transaction will be restarted using the
8606 // identity from the url (foo, baz) to answer the challenge.
8607 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238608 MockWrite(
8609 "GET / HTTP/1.1\r\n"
8610 "Host: www.example.org\r\n"
8611 "Connection: keep-alive\r\n"
8612 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:168613 };
8614
8615 MockRead data_reads2[] = {
8616 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8617 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8618 MockRead("Content-Length: 10\r\n\r\n"),
8619 MockRead(SYNCHRONOUS, ERR_FAILED),
8620 };
8621
8622 // After the challenge above, the transaction will be restarted using the
8623 // identity supplied by the user (foo, bar) to answer the challenge.
8624 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:238625 MockWrite(
8626 "GET / HTTP/1.1\r\n"
8627 "Host: www.example.org\r\n"
8628 "Connection: keep-alive\r\n"
8629 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:168630 };
8631
8632 MockRead data_reads3[] = {
8633 MockRead("HTTP/1.0 200 OK\r\n"),
8634 MockRead("Content-Length: 100\r\n\r\n"),
8635 MockRead(SYNCHRONOUS, OK),
8636 };
8637
Ryan Sleevib8d7ea02018-05-07 20:01:018638 StaticSocketDataProvider data1(data_reads1, data_writes1);
8639 StaticSocketDataProvider data2(data_reads2, data_writes2);
8640 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]bb88e1d32013-05-03 23:11:078641 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8642 session_deps_.socket_factory->AddSocketDataProvider(&data2);
8643 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:168644
8645 TestCompletionCallback callback1;
8646
tfarina42834112016-09-22 13:38:208647 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018648 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:168649
8650 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018651 EXPECT_THAT(rv, IsOk());
[email protected]2262e3a2012-05-22 16:08:168652
bnc691fda62016-08-12 00:43:168653 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:168654 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:168655 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:018656 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:168657 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018658 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168659 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:168660
bnc691fda62016-08-12 00:43:168661 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528662 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:168663 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
8664
8665 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:168666 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:018667 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:168668 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:018669 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168670 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:168671
bnc691fda62016-08-12 00:43:168672 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528673 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:168674
8675 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:528676 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:168677
8678 EXPECT_EQ(100, response->headers->GetContentLength());
8679
[email protected]ea9dc9a2009-09-05 00:43:328680 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:558681 base::RunLoop().RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:328682}
8683
[email protected]2217aa22013-10-11 03:03:548684
8685// Test the request-challenge-retry sequence for basic auth when there is a
8686// correct identity in the URL, but its use is being suppressed. The identity
8687// from the URL should never be used.
bncd16676a2016-07-20 16:23:018688TEST_F(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
[email protected]2217aa22013-10-11 03:03:548689 HttpRequestInfo request;
8690 request.method = "GET";
bncce36dca22015-04-21 22:11:238691 request.url = GURL("http://foo:[email protected]/");
[email protected]2217aa22013-10-11 03:03:548692 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
Ramin Halavatib5e433e2018-02-07 07:41:108693 request.traffic_annotation =
8694 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2217aa22013-10-11 03:03:548695
danakj1fd259a02016-04-16 03:17:098696 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168697 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2217aa22013-10-11 03:03:548698
8699 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238700 MockWrite(
8701 "GET / HTTP/1.1\r\n"
8702 "Host: www.example.org\r\n"
8703 "Connection: keep-alive\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:548704 };
8705
8706 MockRead data_reads1[] = {
8707 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8708 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8709 MockRead("Content-Length: 10\r\n\r\n"),
8710 MockRead(SYNCHRONOUS, ERR_FAILED),
8711 };
8712
8713 // After the challenge above, the transaction will be restarted using the
8714 // identity supplied by the user, not the one in the URL, to answer the
8715 // challenge.
8716 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:238717 MockWrite(
8718 "GET / HTTP/1.1\r\n"
8719 "Host: www.example.org\r\n"
8720 "Connection: keep-alive\r\n"
8721 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:548722 };
8723
8724 MockRead data_reads3[] = {
8725 MockRead("HTTP/1.0 200 OK\r\n"),
8726 MockRead("Content-Length: 100\r\n\r\n"),
8727 MockRead(SYNCHRONOUS, OK),
8728 };
8729
Ryan Sleevib8d7ea02018-05-07 20:01:018730 StaticSocketDataProvider data1(data_reads1, data_writes1);
8731 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]2217aa22013-10-11 03:03:548732 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8733 session_deps_.socket_factory->AddSocketDataProvider(&data3);
8734
8735 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:208736 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018737 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:548738 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018739 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168740 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:548741
bnc691fda62016-08-12 00:43:168742 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528743 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:548744 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
8745
8746 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:168747 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:018748 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:548749 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:018750 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168751 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:548752
bnc691fda62016-08-12 00:43:168753 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528754 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:548755
8756 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:528757 EXPECT_FALSE(response->auth_challenge);
[email protected]2217aa22013-10-11 03:03:548758 EXPECT_EQ(100, response->headers->GetContentLength());
8759
8760 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:558761 base::RunLoop().RunUntilIdle();
[email protected]2217aa22013-10-11 03:03:548762}
8763
[email protected]f9ee6b52008-11-08 06:46:238764// Test that previously tried username/passwords for a realm get re-used.
bncd16676a2016-07-20 16:23:018765TEST_F(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
danakj1fd259a02016-04-16 03:17:098766 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:238767
8768 // Transaction 1: authenticate (foo, bar) on MyRealm1
8769 {
[email protected]1c773ea12009-04-28 19:58:428770 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238771 request.method = "GET";
bncce36dca22015-04-21 22:11:238772 request.url = GURL("http://www.example.org/x/y/z");
Ramin Halavatib5e433e2018-02-07 07:41:108773 request.traffic_annotation =
8774 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238775
bnc691fda62016-08-12 00:43:168776 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278777
[email protected]f9ee6b52008-11-08 06:46:238778 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238779 MockWrite(
8780 "GET /x/y/z HTTP/1.1\r\n"
8781 "Host: www.example.org\r\n"
8782 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238783 };
8784
8785 MockRead data_reads1[] = {
8786 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8787 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8788 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068789 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238790 };
8791
8792 // Resend with authorization (username=foo, password=bar)
8793 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238794 MockWrite(
8795 "GET /x/y/z HTTP/1.1\r\n"
8796 "Host: www.example.org\r\n"
8797 "Connection: keep-alive\r\n"
8798 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238799 };
8800
8801 // Sever accepts the authorization.
8802 MockRead data_reads2[] = {
8803 MockRead("HTTP/1.0 200 OK\r\n"),
8804 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068805 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238806 };
8807
Ryan Sleevib8d7ea02018-05-07 20:01:018808 StaticSocketDataProvider data1(data_reads1, data_writes1);
8809 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:078810 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8811 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:238812
[email protected]49639fa2011-12-20 23:22:418813 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238814
tfarina42834112016-09-22 13:38:208815 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018816 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238817
8818 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018819 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238820
bnc691fda62016-08-12 00:43:168821 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528822 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:048823 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:238824
[email protected]49639fa2011-12-20 23:22:418825 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:238826
bnc691fda62016-08-12 00:43:168827 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
8828 callback2.callback());
robpercival214763f2016-07-01 23:27:018829 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238830
8831 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018832 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238833
bnc691fda62016-08-12 00:43:168834 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528835 ASSERT_TRUE(response);
8836 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238837 EXPECT_EQ(100, response->headers->GetContentLength());
8838 }
8839
8840 // ------------------------------------------------------------------------
8841
8842 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
8843 {
[email protected]1c773ea12009-04-28 19:58:428844 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238845 request.method = "GET";
8846 // Note that Transaction 1 was at /x/y/z, so this is in the same
8847 // protection space as MyRealm1.
bncce36dca22015-04-21 22:11:238848 request.url = GURL("http://www.example.org/x/y/a/b");
Ramin Halavatib5e433e2018-02-07 07:41:108849 request.traffic_annotation =
8850 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238851
bnc691fda62016-08-12 00:43:168852 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278853
[email protected]f9ee6b52008-11-08 06:46:238854 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238855 MockWrite(
8856 "GET /x/y/a/b HTTP/1.1\r\n"
8857 "Host: www.example.org\r\n"
8858 "Connection: keep-alive\r\n"
8859 // Send preemptive authorization for MyRealm1
8860 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238861 };
8862
8863 // The server didn't like the preemptive authorization, and
8864 // challenges us for a different realm (MyRealm2).
8865 MockRead data_reads1[] = {
8866 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8867 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
8868 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068869 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238870 };
8871
8872 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
8873 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238874 MockWrite(
8875 "GET /x/y/a/b HTTP/1.1\r\n"
8876 "Host: www.example.org\r\n"
8877 "Connection: keep-alive\r\n"
8878 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238879 };
8880
8881 // Sever accepts the authorization.
8882 MockRead data_reads2[] = {
8883 MockRead("HTTP/1.0 200 OK\r\n"),
8884 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068885 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238886 };
8887
Ryan Sleevib8d7ea02018-05-07 20:01:018888 StaticSocketDataProvider data1(data_reads1, data_writes1);
8889 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:078890 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8891 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:238892
[email protected]49639fa2011-12-20 23:22:418893 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238894
tfarina42834112016-09-22 13:38:208895 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018896 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238897
8898 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018899 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238900
bnc691fda62016-08-12 00:43:168901 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528902 ASSERT_TRUE(response);
8903 ASSERT_TRUE(response->auth_challenge);
[email protected]79cb5c12011-09-12 13:12:048904 EXPECT_FALSE(response->auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:438905 EXPECT_EQ("http://www.example.org",
8906 response->auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:048907 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
aberentbba302d2015-12-03 10:20:198908 EXPECT_EQ(kBasicAuthScheme, response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:238909
[email protected]49639fa2011-12-20 23:22:418910 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:238911
bnc691fda62016-08-12 00:43:168912 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
8913 callback2.callback());
robpercival214763f2016-07-01 23:27:018914 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238915
8916 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018917 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238918
bnc691fda62016-08-12 00:43:168919 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528920 ASSERT_TRUE(response);
8921 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238922 EXPECT_EQ(100, response->headers->GetContentLength());
8923 }
8924
8925 // ------------------------------------------------------------------------
8926
8927 // Transaction 3: Resend a request in MyRealm's protection space --
8928 // succeed with preemptive authorization.
8929 {
[email protected]1c773ea12009-04-28 19:58:428930 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238931 request.method = "GET";
bncce36dca22015-04-21 22:11:238932 request.url = GURL("http://www.example.org/x/y/z2");
Ramin Halavatib5e433e2018-02-07 07:41:108933 request.traffic_annotation =
8934 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238935
bnc691fda62016-08-12 00:43:168936 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278937
[email protected]f9ee6b52008-11-08 06:46:238938 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238939 MockWrite(
8940 "GET /x/y/z2 HTTP/1.1\r\n"
8941 "Host: www.example.org\r\n"
8942 "Connection: keep-alive\r\n"
8943 // The authorization for MyRealm1 gets sent preemptively
8944 // (since the url is in the same protection space)
8945 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238946 };
8947
8948 // Sever accepts the preemptive authorization
8949 MockRead data_reads1[] = {
8950 MockRead("HTTP/1.0 200 OK\r\n"),
8951 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068952 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238953 };
8954
Ryan Sleevib8d7ea02018-05-07 20:01:018955 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:078956 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:238957
[email protected]49639fa2011-12-20 23:22:418958 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238959
tfarina42834112016-09-22 13:38:208960 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018961 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238962
8963 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018964 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238965
bnc691fda62016-08-12 00:43:168966 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528967 ASSERT_TRUE(response);
[email protected]f9ee6b52008-11-08 06:46:238968
wezca1070932016-05-26 20:30:528969 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238970 EXPECT_EQ(100, response->headers->GetContentLength());
8971 }
8972
8973 // ------------------------------------------------------------------------
8974
8975 // Transaction 4: request another URL in MyRealm (however the
8976 // url is not known to belong to the protection space, so no pre-auth).
8977 {
[email protected]1c773ea12009-04-28 19:58:428978 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238979 request.method = "GET";
bncce36dca22015-04-21 22:11:238980 request.url = GURL("http://www.example.org/x/1");
Ramin Halavatib5e433e2018-02-07 07:41:108981 request.traffic_annotation =
8982 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238983
bnc691fda62016-08-12 00:43:168984 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278985
[email protected]f9ee6b52008-11-08 06:46:238986 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238987 MockWrite(
8988 "GET /x/1 HTTP/1.1\r\n"
8989 "Host: www.example.org\r\n"
8990 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238991 };
8992
8993 MockRead data_reads1[] = {
8994 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8995 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8996 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068997 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238998 };
8999
9000 // Resend with authorization from MyRealm's cache.
9001 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:239002 MockWrite(
9003 "GET /x/1 HTTP/1.1\r\n"
9004 "Host: www.example.org\r\n"
9005 "Connection: keep-alive\r\n"
9006 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:239007 };
9008
9009 // Sever accepts the authorization.
9010 MockRead data_reads2[] = {
9011 MockRead("HTTP/1.0 200 OK\r\n"),
9012 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069013 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:239014 };
9015
Ryan Sleevib8d7ea02018-05-07 20:01:019016 StaticSocketDataProvider data1(data_reads1, data_writes1);
9017 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:079018 session_deps_.socket_factory->AddSocketDataProvider(&data1);
9019 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:239020
[email protected]49639fa2011-12-20 23:22:419021 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:239022
tfarina42834112016-09-22 13:38:209023 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019024 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:239025
9026 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019027 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:239028
bnc691fda62016-08-12 00:43:169029 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:419030 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:169031 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:019032 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:229033 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:019034 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:169035 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:229036
bnc691fda62016-08-12 00:43:169037 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529038 ASSERT_TRUE(response);
9039 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:239040 EXPECT_EQ(100, response->headers->GetContentLength());
9041 }
9042
9043 // ------------------------------------------------------------------------
9044
9045 // Transaction 5: request a URL in MyRealm, but the server rejects the
9046 // cached identity. Should invalidate and re-prompt.
9047 {
[email protected]1c773ea12009-04-28 19:58:429048 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:239049 request.method = "GET";
bncce36dca22015-04-21 22:11:239050 request.url = GURL("http://www.example.org/p/q/t");
Ramin Halavatib5e433e2018-02-07 07:41:109051 request.traffic_annotation =
9052 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:239053
bnc691fda62016-08-12 00:43:169054 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279055
[email protected]f9ee6b52008-11-08 06:46:239056 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239057 MockWrite(
9058 "GET /p/q/t HTTP/1.1\r\n"
9059 "Host: www.example.org\r\n"
9060 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:239061 };
9062
9063 MockRead data_reads1[] = {
9064 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
9065 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9066 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069067 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:239068 };
9069
9070 // Resend with authorization from cache for MyRealm.
9071 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:239072 MockWrite(
9073 "GET /p/q/t HTTP/1.1\r\n"
9074 "Host: www.example.org\r\n"
9075 "Connection: keep-alive\r\n"
9076 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:239077 };
9078
9079 // Sever rejects the authorization.
9080 MockRead data_reads2[] = {
9081 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
9082 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9083 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069084 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:239085 };
9086
9087 // At this point we should prompt for new credentials for MyRealm.
9088 // Restart with username=foo3, password=foo4.
9089 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:239090 MockWrite(
9091 "GET /p/q/t HTTP/1.1\r\n"
9092 "Host: www.example.org\r\n"
9093 "Connection: keep-alive\r\n"
9094 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:239095 };
9096
9097 // Sever accepts the authorization.
9098 MockRead data_reads3[] = {
9099 MockRead("HTTP/1.0 200 OK\r\n"),
9100 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069101 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:239102 };
9103
Ryan Sleevib8d7ea02018-05-07 20:01:019104 StaticSocketDataProvider data1(data_reads1, data_writes1);
9105 StaticSocketDataProvider data2(data_reads2, data_writes2);
9106 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]bb88e1d32013-05-03 23:11:079107 session_deps_.socket_factory->AddSocketDataProvider(&data1);
9108 session_deps_.socket_factory->AddSocketDataProvider(&data2);
9109 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:239110
[email protected]49639fa2011-12-20 23:22:419111 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:239112
tfarina42834112016-09-22 13:38:209113 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019114 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:239115
9116 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019117 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:239118
bnc691fda62016-08-12 00:43:169119 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:419120 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:169121 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:019122 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:229123 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:019124 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:169125 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:229126
bnc691fda62016-08-12 00:43:169127 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529128 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:049129 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:239130
[email protected]49639fa2011-12-20 23:22:419131 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:239132
bnc691fda62016-08-12 00:43:169133 rv = trans.RestartWithAuth(AuthCredentials(kFoo3, kBar3),
9134 callback3.callback());
robpercival214763f2016-07-01 23:27:019135 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:239136
[email protected]0757e7702009-03-27 04:00:229137 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:019138 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:239139
bnc691fda62016-08-12 00:43:169140 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529141 ASSERT_TRUE(response);
9142 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:239143 EXPECT_EQ(100, response->headers->GetContentLength());
9144 }
9145}
[email protected]89ceba9a2009-03-21 03:46:069146
[email protected]3c32c5f2010-05-18 15:18:129147// Tests that nonce count increments when multiple auth attempts
9148// are started with the same nonce.
bncd16676a2016-07-20 16:23:019149TEST_F(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:449150 HttpAuthHandlerDigest::Factory* digest_factory =
9151 new HttpAuthHandlerDigest::Factory();
9152 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
9153 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
9154 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:079155 session_deps_.http_auth_handler_factory.reset(digest_factory);
danakj1fd259a02016-04-16 03:17:099156 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:129157
9158 // Transaction 1: authenticate (foo, bar) on MyRealm1
9159 {
[email protected]3c32c5f2010-05-18 15:18:129160 HttpRequestInfo request;
9161 request.method = "GET";
bncce36dca22015-04-21 22:11:239162 request.url = GURL("http://www.example.org/x/y/z");
Ramin Halavatib5e433e2018-02-07 07:41:109163 request.traffic_annotation =
9164 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3c32c5f2010-05-18 15:18:129165
bnc691fda62016-08-12 00:43:169166 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279167
[email protected]3c32c5f2010-05-18 15:18:129168 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239169 MockWrite(
9170 "GET /x/y/z HTTP/1.1\r\n"
9171 "Host: www.example.org\r\n"
9172 "Connection: keep-alive\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:129173 };
9174
9175 MockRead data_reads1[] = {
9176 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
9177 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
9178 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069179 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:129180 };
9181
9182 // Resend with authorization (username=foo, password=bar)
9183 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:239184 MockWrite(
9185 "GET /x/y/z HTTP/1.1\r\n"
9186 "Host: www.example.org\r\n"
9187 "Connection: keep-alive\r\n"
9188 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
9189 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
9190 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
9191 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:129192 };
9193
9194 // Sever accepts the authorization.
9195 MockRead data_reads2[] = {
zmo9528c9f42015-08-04 22:12:089196 MockRead("HTTP/1.0 200 OK\r\n"),
9197 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:129198 };
9199
Ryan Sleevib8d7ea02018-05-07 20:01:019200 StaticSocketDataProvider data1(data_reads1, data_writes1);
9201 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:079202 session_deps_.socket_factory->AddSocketDataProvider(&data1);
9203 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:129204
[email protected]49639fa2011-12-20 23:22:419205 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:129206
tfarina42834112016-09-22 13:38:209207 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019208 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:129209
9210 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019211 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:129212
bnc691fda62016-08-12 00:43:169213 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529214 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:049215 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:129216
[email protected]49639fa2011-12-20 23:22:419217 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:129218
bnc691fda62016-08-12 00:43:169219 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
9220 callback2.callback());
robpercival214763f2016-07-01 23:27:019221 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:129222
9223 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:019224 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:129225
bnc691fda62016-08-12 00:43:169226 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529227 ASSERT_TRUE(response);
9228 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:129229 }
9230
9231 // ------------------------------------------------------------------------
9232
9233 // Transaction 2: Request another resource in digestive's protection space.
9234 // This will preemptively add an Authorization header which should have an
9235 // "nc" value of 2 (as compared to 1 in the first use.
9236 {
[email protected]3c32c5f2010-05-18 15:18:129237 HttpRequestInfo request;
9238 request.method = "GET";
9239 // Note that Transaction 1 was at /x/y/z, so this is in the same
9240 // protection space as digest.
bncce36dca22015-04-21 22:11:239241 request.url = GURL("http://www.example.org/x/y/a/b");
Ramin Halavatib5e433e2018-02-07 07:41:109242 request.traffic_annotation =
9243 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3c32c5f2010-05-18 15:18:129244
bnc691fda62016-08-12 00:43:169245 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279246
[email protected]3c32c5f2010-05-18 15:18:129247 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239248 MockWrite(
9249 "GET /x/y/a/b HTTP/1.1\r\n"
9250 "Host: www.example.org\r\n"
9251 "Connection: keep-alive\r\n"
9252 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
9253 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
9254 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
9255 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:129256 };
9257
9258 // Sever accepts the authorization.
9259 MockRead data_reads1[] = {
9260 MockRead("HTTP/1.0 200 OK\r\n"),
9261 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069262 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:129263 };
9264
Ryan Sleevib8d7ea02018-05-07 20:01:019265 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:079266 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:129267
[email protected]49639fa2011-12-20 23:22:419268 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:129269
tfarina42834112016-09-22 13:38:209270 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019271 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:129272
9273 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019274 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:129275
bnc691fda62016-08-12 00:43:169276 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529277 ASSERT_TRUE(response);
9278 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:129279 }
9280}
9281
[email protected]89ceba9a2009-03-21 03:46:069282// Test the ResetStateForRestart() private method.
bncd16676a2016-07-20 16:23:019283TEST_F(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:069284 // Create a transaction (the dependencies aren't important).
danakj1fd259a02016-04-16 03:17:099285 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169286 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]89ceba9a2009-03-21 03:46:069287
9288 // Setup some state (which we expect ResetStateForRestart() will clear).
Victor Costan9c7302b2018-08-27 16:39:449289 trans.read_buf_ = base::MakeRefCounted<IOBuffer>(15);
bnc691fda62016-08-12 00:43:169290 trans.read_buf_len_ = 15;
9291 trans.request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:069292
9293 // Setup state in response_
bnc691fda62016-08-12 00:43:169294 HttpResponseInfo* response = &trans.response_;
[email protected]0877e3d2009-10-17 22:29:579295 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:089296 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:579297 response->response_time = base::Time::Now();
9298 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:069299
9300 { // Setup state for response_.vary_data
9301 HttpRequestInfo request;
9302 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
9303 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:279304 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:439305 request.extra_headers.SetHeader("Foo", "1");
9306 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:509307 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:069308 }
9309
9310 // Cause the above state to be reset.
bnc691fda62016-08-12 00:43:169311 trans.ResetStateForRestart();
[email protected]89ceba9a2009-03-21 03:46:069312
9313 // Verify that the state that needed to be reset, has been reset.
bnc691fda62016-08-12 00:43:169314 EXPECT_FALSE(trans.read_buf_);
9315 EXPECT_EQ(0, trans.read_buf_len_);
9316 EXPECT_TRUE(trans.request_headers_.IsEmpty());
wezca1070932016-05-26 20:30:529317 EXPECT_FALSE(response->auth_challenge);
9318 EXPECT_FALSE(response->headers);
[email protected]34f40942010-10-04 00:34:049319 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:089320 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:579321 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:069322}
9323
[email protected]bacff652009-03-31 17:50:339324// Test HTTPS connections to a site with a bad certificate
bncd16676a2016-07-20 16:23:019325TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:339326 HttpRequestInfo request;
9327 request.method = "GET";
bncce36dca22015-04-21 22:11:239328 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109329 request.traffic_annotation =
9330 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]bacff652009-03-31 17:50:339331
danakj1fd259a02016-04-16 03:17:099332 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169333 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279334
[email protected]bacff652009-03-31 17:50:339335 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239336 MockWrite(
9337 "GET / HTTP/1.1\r\n"
9338 "Host: www.example.org\r\n"
9339 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:339340 };
9341
9342 MockRead data_reads[] = {
9343 MockRead("HTTP/1.0 200 OK\r\n"),
9344 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9345 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069346 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:339347 };
9348
[email protected]5ecc992a42009-11-11 01:41:599349 StaticSocketDataProvider ssl_bad_certificate;
Ryan Sleevib8d7ea02018-05-07 20:01:019350 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069351 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
9352 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:339353
[email protected]bb88e1d32013-05-03 23:11:079354 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
9355 session_deps_.socket_factory->AddSocketDataProvider(&data);
9356 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
9357 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:339358
[email protected]49639fa2011-12-20 23:22:419359 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:339360
tfarina42834112016-09-22 13:38:209361 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019362 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:339363
9364 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019365 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:339366
bnc691fda62016-08-12 00:43:169367 rv = trans.RestartIgnoringLastError(callback.callback());
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, IsOk());
[email protected]bacff652009-03-31 17:50:339372
bnc691fda62016-08-12 00:43:169373 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:339374
wezca1070932016-05-26 20:30:529375 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:339376 EXPECT_EQ(100, response->headers->GetContentLength());
9377}
9378
9379// Test HTTPS connections to a site with a bad certificate, going through a
9380// proxy
bncd16676a2016-07-20 16:23:019381TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
Ramin Halavatica8d5252018-03-12 05:33:499382 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9383 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]bacff652009-03-31 17:50:339384
9385 HttpRequestInfo request;
9386 request.method = "GET";
bncce36dca22015-04-21 22:11:239387 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109388 request.traffic_annotation =
9389 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]bacff652009-03-31 17:50:339390
9391 MockWrite proxy_writes[] = {
rsleevidb16bb02015-11-12 23:47:179392 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9393 "Host: www.example.org:443\r\n"
9394 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:339395 };
9396
9397 MockRead proxy_reads[] = {
9398 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069399 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:339400 };
9401
9402 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179403 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9404 "Host: www.example.org:443\r\n"
9405 "Proxy-Connection: keep-alive\r\n\r\n"),
9406 MockWrite("GET / HTTP/1.1\r\n"
9407 "Host: www.example.org\r\n"
9408 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:339409 };
9410
9411 MockRead data_reads[] = {
9412 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
9413 MockRead("HTTP/1.0 200 OK\r\n"),
9414 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9415 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069416 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:339417 };
9418
Ryan Sleevib8d7ea02018-05-07 20:01:019419 StaticSocketDataProvider ssl_bad_certificate(proxy_reads, proxy_writes);
9420 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069421 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
9422 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:339423
[email protected]bb88e1d32013-05-03 23:11:079424 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
9425 session_deps_.socket_factory->AddSocketDataProvider(&data);
9426 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
9427 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:339428
[email protected]49639fa2011-12-20 23:22:419429 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:339430
9431 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:079432 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:339433
danakj1fd259a02016-04-16 03:17:099434 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169435 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bacff652009-03-31 17:50:339436
tfarina42834112016-09-22 13:38:209437 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019438 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:339439
9440 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019441 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:339442
bnc691fda62016-08-12 00:43:169443 rv = trans.RestartIgnoringLastError(callback.callback());
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, IsOk());
[email protected]bacff652009-03-31 17:50:339448
bnc691fda62016-08-12 00:43:169449 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:339450
wezca1070932016-05-26 20:30:529451 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:339452 EXPECT_EQ(100, response->headers->GetContentLength());
9453 }
9454}
9455
[email protected]2df19bb2010-08-25 20:13:469456
9457// Test HTTPS connections to a site, going through an HTTPS proxy
bncd16676a2016-07-20 16:23:019458TEST_F(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:599459 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499460 ProxyResolutionService::CreateFixedFromPacResult(
9461 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519462 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079463 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:469464
9465 HttpRequestInfo request;
9466 request.method = "GET";
bncce36dca22015-04-21 22:11:239467 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109468 request.traffic_annotation =
9469 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:469470
9471 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179472 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9473 "Host: www.example.org:443\r\n"
9474 "Proxy-Connection: keep-alive\r\n\r\n"),
9475 MockWrite("GET / HTTP/1.1\r\n"
9476 "Host: www.example.org\r\n"
9477 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:469478 };
9479
9480 MockRead data_reads[] = {
9481 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
9482 MockRead("HTTP/1.1 200 OK\r\n"),
9483 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9484 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069485 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:469486 };
9487
Ryan Sleevib8d7ea02018-05-07 20:01:019488 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069489 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
9490 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:469491
[email protected]bb88e1d32013-05-03 23:11:079492 session_deps_.socket_factory->AddSocketDataProvider(&data);
9493 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
9494 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:469495
[email protected]49639fa2011-12-20 23:22:419496 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:469497
danakj1fd259a02016-04-16 03:17:099498 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169499 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:469500
tfarina42834112016-09-22 13:38:209501 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019502 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:469503
9504 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019505 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:169506 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:469507
wezca1070932016-05-26 20:30:529508 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:469509
tbansal2ecbbc72016-10-06 17:15:479510 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:469511 EXPECT_TRUE(response->headers->IsKeepAlive());
9512 EXPECT_EQ(200, response->headers->response_code());
9513 EXPECT_EQ(100, response->headers->GetContentLength());
9514 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:209515
9516 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169517 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209518 TestLoadTimingNotReusedWithPac(load_timing_info,
9519 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:469520}
9521
Eric Roman74103c72019-02-21 00:23:129522// Test that an HTTPS Proxy can redirect a CONNECT request for main frames.
bncd16676a2016-07-20 16:23:019523TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:599524 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499525 ProxyResolutionService::CreateFixedFromPacResult(
9526 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519527 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079528 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:299529
Matt Menkeecfecfc72019-02-05 19:15:289530 base::TimeTicks start_time = base::TimeTicks::Now();
9531 const base::TimeDelta kTimeIncrement = base::TimeDelta::FromSeconds(4);
9532 session_deps_.host_resolver->set_ondemand_mode(true);
9533
[email protected]511f6f52010-12-17 03:58:299534 HttpRequestInfo request;
Eric Roman74103c72019-02-21 00:23:129535 request.load_flags = LOAD_MAIN_FRAME_DEPRECATED;
[email protected]511f6f52010-12-17 03:58:299536 request.method = "GET";
bncce36dca22015-04-21 22:11:239537 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109538 request.traffic_annotation =
9539 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299540
9541 MockWrite data_writes[] = {
Matt Menkeecfecfc72019-02-05 19:15:289542 MockWrite(ASYNC, 0,
9543 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:179544 "Host: www.example.org:443\r\n"
9545 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:299546 };
9547
9548 MockRead data_reads[] = {
Matt Menkeecfecfc72019-02-05 19:15:289549 // Pause on first read.
9550 MockRead(ASYNC, ERR_IO_PENDING, 1),
9551 MockRead(ASYNC, 2, "HTTP/1.1 302 Redirect\r\n"),
9552 MockRead(ASYNC, 3, "Location: http://login.example.com/\r\n"),
9553 MockRead(ASYNC, 4, "Content-Length: 0\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:299554 };
9555
Matt Menkeecfecfc72019-02-05 19:15:289556 SequencedSocketData data(MockConnect(ASYNC, OK), data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069557 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:299558
[email protected]bb88e1d32013-05-03 23:11:079559 session_deps_.socket_factory->AddSocketDataProvider(&data);
9560 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:299561
[email protected]49639fa2011-12-20 23:22:419562 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:299563
danakj1fd259a02016-04-16 03:17:099564 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169565 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:299566
tfarina42834112016-09-22 13:38:209567 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019568 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Matt Menkeecfecfc72019-02-05 19:15:289569 EXPECT_TRUE(session_deps_.host_resolver->has_pending_requests());
9570
9571 // Host resolution takes |kTimeIncrement|.
9572 FastForwardBy(kTimeIncrement);
9573 // Resolving the current request with |ResolveNow| will cause the pending
9574 // request to instantly complete, and the async connect will start as well.
9575 session_deps_.host_resolver->ResolveOnlyRequestNow();
9576
9577 // Connecting takes |kTimeIncrement|.
9578 FastForwardBy(kTimeIncrement);
9579 data.RunUntilPaused();
9580
9581 // The server takes |kTimeIncrement| to respond.
9582 FastForwardBy(kTimeIncrement);
9583 data.Resume();
[email protected]511f6f52010-12-17 03:58:299584
9585 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019586 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:169587 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:299588
wezca1070932016-05-26 20:30:529589 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:299590
9591 EXPECT_EQ(302, response->headers->response_code());
9592 std::string url;
9593 EXPECT_TRUE(response->headers->IsRedirect(&url));
9594 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:209595
[email protected]029c83b62013-01-24 05:28:209596 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169597 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209598
9599 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:199600 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:209601
Matt Menkeecfecfc72019-02-05 19:15:289602 // In the case of redirects from proxies, just as with all responses from
9603 // proxies, DNS and SSL times reflect timing to look up the destination's
9604 // name, and negotiate an SSL connection to it (Neither of which are done in
9605 // this case), which the DNS and SSL times for the proxy are all included in
9606 // connect_start / connect_end. See
Eric Roman74103c72019-02-21 00:23:129607 // HttpNetworkTransaction::OnHttpsProxyTunnelResponseRedirect
Matt Menkeecfecfc72019-02-05 19:15:289608
9609 EXPECT_TRUE(load_timing_info.connect_timing.dns_start.is_null());
9610 EXPECT_TRUE(load_timing_info.connect_timing.dns_end.is_null());
9611 EXPECT_TRUE(load_timing_info.connect_timing.ssl_start.is_null());
9612 EXPECT_TRUE(load_timing_info.connect_timing.ssl_end.is_null());
9613
9614 EXPECT_EQ(start_time, load_timing_info.proxy_resolve_start);
9615 EXPECT_EQ(start_time, load_timing_info.proxy_resolve_end);
9616 EXPECT_EQ(start_time, load_timing_info.connect_timing.connect_start);
9617 EXPECT_EQ(start_time + 3 * kTimeIncrement,
9618 load_timing_info.connect_timing.connect_end);
[email protected]029c83b62013-01-24 05:28:209619
9620 EXPECT_TRUE(load_timing_info.send_start.is_null());
9621 EXPECT_TRUE(load_timing_info.send_end.is_null());
9622 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:299623}
9624
Eric Roman74103c72019-02-21 00:23:129625// Test that an HTTPS Proxy cannot redirect a CONNECT request for subresources.
9626TEST_F(HttpNetworkTransactionTest,
9627 RedirectOfHttpsConnectSubresourceViaHttpsProxy) {
9628 base::HistogramTester histograms;
9629 session_deps_.proxy_resolution_service =
9630 ProxyResolutionService::CreateFixedFromPacResult(
9631 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
9632 TestNetLog net_log;
9633 session_deps_.net_log = &net_log;
9634
9635 HttpRequestInfo request;
9636 request.method = "GET";
9637 request.url = GURL("https://www.example.org/");
9638 request.traffic_annotation =
9639 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9640
9641 MockWrite data_writes[] = {
9642 MockWrite(ASYNC, 0,
9643 "CONNECT www.example.org:443 HTTP/1.1\r\n"
9644 "Host: www.example.org:443\r\n"
9645 "Proxy-Connection: keep-alive\r\n\r\n"),
9646 };
9647
9648 MockRead data_reads[] = {
9649 MockRead(ASYNC, 1, "HTTP/1.1 302 Redirect\r\n"),
9650 MockRead(ASYNC, 2, "Location: http://login.example.com/\r\n"),
9651 MockRead(ASYNC, 3, "Content-Length: 0\r\n\r\n"),
9652 };
9653
9654 SequencedSocketData data(MockConnect(ASYNC, OK), data_reads, data_writes);
9655 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
9656
9657 session_deps_.socket_factory->AddSocketDataProvider(&data);
9658 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
9659
9660 TestCompletionCallback callback;
9661
9662 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9663 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
9664
9665 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
9666 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9667
9668 rv = callback.WaitForResult();
9669 EXPECT_THAT(rv, IsError(ERR_HTTPS_PROXY_TUNNEL_RESPONSE_REDIRECT));
9670
9671 histograms.ExpectUniqueSample(
9672 "Net.Proxy.RedirectDuringConnect",
9673 HttpNetworkTransaction::kSubresourceByExplicitProxy, 1);
9674}
9675
9676// Test that an HTTPS Proxy which was auto-detected cannot redirect a CONNECT
9677// request for main frames.
9678TEST_F(HttpNetworkTransactionTest,
9679 RedirectOfHttpsConnectViaAutoDetectedHttpsProxy) {
9680 base::HistogramTester histograms;
9681 session_deps_.proxy_resolution_service =
9682 ProxyResolutionService::CreateFixedFromAutoDetectedPacResult(
9683 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
9684 TestNetLog net_log;
9685 session_deps_.net_log = &net_log;
9686
9687 HttpRequestInfo request;
9688 request.load_flags = LOAD_MAIN_FRAME_DEPRECATED;
9689 request.method = "GET";
9690 request.url = GURL("https://www.example.org/");
9691 request.traffic_annotation =
9692 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9693
9694 MockWrite data_writes[] = {
9695 MockWrite(ASYNC, 0,
9696 "CONNECT www.example.org:443 HTTP/1.1\r\n"
9697 "Host: www.example.org:443\r\n"
9698 "Proxy-Connection: keep-alive\r\n\r\n"),
9699 };
9700
9701 MockRead data_reads[] = {
9702 MockRead(ASYNC, 1, "HTTP/1.1 302 Redirect\r\n"),
9703 MockRead(ASYNC, 2, "Location: http://login.example.com/\r\n"),
9704 MockRead(ASYNC, 3, "Content-Length: 0\r\n\r\n"),
9705 };
9706
9707 SequencedSocketData data(MockConnect(ASYNC, OK), data_reads, data_writes);
9708 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
9709
9710 session_deps_.socket_factory->AddSocketDataProvider(&data);
9711 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
9712
9713 TestCompletionCallback callback;
9714
9715 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9716 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
9717
9718 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
9719 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9720
9721 rv = callback.WaitForResult();
9722 EXPECT_THAT(rv, IsError(ERR_HTTPS_PROXY_TUNNEL_RESPONSE_REDIRECT));
9723
9724 histograms.ExpectUniqueSample(
9725 "Net.Proxy.RedirectDuringConnect",
9726 HttpNetworkTransaction::kMainFrameByAutoDetectedProxy, 1);
9727}
9728
9729// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request for main
9730// frames.
bncd16676a2016-07-20 16:23:019731TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
Eric Roman74103c72019-02-21 00:23:129732 base::HistogramTester histograms;
Ramin Halavatica8d5252018-03-12 05:33:499733 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9734 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Matt Menkeecfecfc72019-02-05 19:15:289735 TestNetLog net_log;
9736 session_deps_.net_log = &net_log;
9737
9738 base::TimeTicks start_time = base::TimeTicks::Now();
9739 const base::TimeDelta kTimeIncrement = base::TimeDelta::FromSeconds(4);
9740 session_deps_.host_resolver->set_ondemand_mode(true);
[email protected]511f6f52010-12-17 03:58:299741
9742 HttpRequestInfo request;
9743 request.method = "GET";
Eric Roman74103c72019-02-21 00:23:129744 request.load_flags = LOAD_MAIN_FRAME_DEPRECATED;
bncce36dca22015-04-21 22:11:239745 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109746 request.traffic_annotation =
9747 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299748
Ryan Hamilton0239aac2018-05-19 00:03:139749 spdy::SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:049750 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
9751 HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:139752 spdy::SpdySerializedFrame goaway(
9753 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:299754 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:419755 CreateMockWrite(conn, 0, SYNCHRONOUS),
Matt Menkeecfecfc72019-02-05 19:15:289756 CreateMockWrite(goaway, 3, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:299757 };
9758
9759 static const char* const kExtraHeaders[] = {
9760 "location",
9761 "http://login.example.com/",
9762 };
Ryan Hamilton0239aac2018-05-19 00:03:139763 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
Avi Drissman4365a4782018-12-28 19:26:249764 "302", kExtraHeaders, base::size(kExtraHeaders) / 2, 1));
[email protected]511f6f52010-12-17 03:58:299765 MockRead data_reads[] = {
Matt Menkeecfecfc72019-02-05 19:15:289766 // Pause on first read.
9767 MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(resp, 2),
9768 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:299769 };
9770
Matt Menkeecfecfc72019-02-05 19:15:289771 SequencedSocketData data(MockConnect(ASYNC, OK), data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069772 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:369773 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:299774
[email protected]bb88e1d32013-05-03 23:11:079775 session_deps_.socket_factory->AddSocketDataProvider(&data);
9776 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:299777
[email protected]49639fa2011-12-20 23:22:419778 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:299779
danakj1fd259a02016-04-16 03:17:099780 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169781 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:299782
tfarina42834112016-09-22 13:38:209783 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019784 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Matt Menkeecfecfc72019-02-05 19:15:289785 EXPECT_TRUE(session_deps_.host_resolver->has_pending_requests());
[email protected]511f6f52010-12-17 03:58:299786
Matt Menkeecfecfc72019-02-05 19:15:289787 // Host resolution takes |kTimeIncrement|.
9788 FastForwardBy(kTimeIncrement);
9789 // Resolving the current request with |ResolveNow| will cause the pending
9790 // request to instantly complete, and the async connect will start as well.
9791 session_deps_.host_resolver->ResolveOnlyRequestNow();
9792
9793 // Connecting takes |kTimeIncrement|.
9794 FastForwardBy(kTimeIncrement);
9795 data.RunUntilPaused();
9796
9797 FastForwardBy(kTimeIncrement);
9798 data.Resume();
[email protected]511f6f52010-12-17 03:58:299799 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019800 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:169801 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:299802
wezca1070932016-05-26 20:30:529803 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:299804
9805 EXPECT_EQ(302, response->headers->response_code());
9806 std::string url;
9807 EXPECT_TRUE(response->headers->IsRedirect(&url));
9808 EXPECT_EQ("http://login.example.com/", url);
Matt Menkeecfecfc72019-02-05 19:15:289809
9810 LoadTimingInfo load_timing_info;
9811 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
9812
9813 EXPECT_FALSE(load_timing_info.socket_reused);
9814 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
9815
9816 // No proxy resolution times, since there's no PAC script.
9817 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
9818 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
9819
9820 // In the case of redirects from proxies, just as with all responses from
9821 // proxies, DNS and SSL times reflect timing to look up the destination's
9822 // name, and negotiate an SSL connection to it (Neither of which are done in
9823 // this case), which the DNS and SSL times for the proxy are all included in
9824 // connect_start / connect_end. See
Eric Roman74103c72019-02-21 00:23:129825 // HttpNetworkTransaction::OnHttpsProxyTunnelResponseRedirect.
Matt Menkeecfecfc72019-02-05 19:15:289826
9827 EXPECT_TRUE(load_timing_info.connect_timing.dns_start.is_null());
9828 EXPECT_TRUE(load_timing_info.connect_timing.dns_end.is_null());
9829 EXPECT_TRUE(load_timing_info.connect_timing.ssl_start.is_null());
9830 EXPECT_TRUE(load_timing_info.connect_timing.ssl_end.is_null());
9831
9832 EXPECT_EQ(start_time, load_timing_info.connect_timing.connect_start);
9833 EXPECT_EQ(start_time + 3 * kTimeIncrement,
9834 load_timing_info.connect_timing.connect_end);
9835
9836 EXPECT_TRUE(load_timing_info.send_start.is_null());
9837 EXPECT_TRUE(load_timing_info.send_end.is_null());
9838 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
Eric Roman74103c72019-02-21 00:23:129839
9840 histograms.ExpectUniqueSample(
9841 "Net.Proxy.RedirectDuringConnect",
9842 HttpNetworkTransaction::kMainFrameByExplicitProxy, 1);
[email protected]511f6f52010-12-17 03:58:299843}
9844
[email protected]4eddbc732012-08-09 05:40:179845// Test that an HTTPS proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:019846TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaHttpsProxy) {
Ramin Halavatica8d5252018-03-12 05:33:499847 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9848 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299849
9850 HttpRequestInfo request;
9851 request.method = "GET";
bncce36dca22015-04-21 22:11:239852 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109853 request.traffic_annotation =
9854 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299855
9856 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179857 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9858 "Host: www.example.org:443\r\n"
9859 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:299860 };
9861
9862 MockRead data_reads[] = {
9863 MockRead("HTTP/1.1 404 Not Found\r\n"),
9864 MockRead("Content-Length: 23\r\n\r\n"),
9865 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:069866 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:299867 };
9868
Ryan Sleevib8d7ea02018-05-07 20:01:019869 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069870 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:299871
[email protected]bb88e1d32013-05-03 23:11:079872 session_deps_.socket_factory->AddSocketDataProvider(&data);
9873 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:299874
[email protected]49639fa2011-12-20 23:22:419875 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:299876
danakj1fd259a02016-04-16 03:17:099877 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169878 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:299879
tfarina42834112016-09-22 13:38:209880 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019881 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:299882
9883 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019884 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:299885
ttuttle960fcbf2016-04-19 13:26:329886 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:299887}
9888
[email protected]4eddbc732012-08-09 05:40:179889// Test that a SPDY proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:019890TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaSpdyProxy) {
Ramin Halavatica8d5252018-03-12 05:33:499891 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9892 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299893
9894 HttpRequestInfo request;
9895 request.method = "GET";
bncce36dca22015-04-21 22:11:239896 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109897 request.traffic_annotation =
9898 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299899
Ryan Hamilton0239aac2018-05-19 00:03:139900 spdy::SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:049901 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
9902 HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:139903 spdy::SpdySerializedFrame rst(
9904 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:299905 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:419906 CreateMockWrite(conn, 0), CreateMockWrite(rst, 3),
[email protected]511f6f52010-12-17 03:58:299907 };
9908
9909 static const char* const kExtraHeaders[] = {
9910 "location",
9911 "http://login.example.com/",
9912 };
Ryan Hamilton0239aac2018-05-19 00:03:139913 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
Avi Drissman4365a4782018-12-28 19:26:249914 "404", kExtraHeaders, base::size(kExtraHeaders) / 2, 1));
Ryan Hamilton0239aac2018-05-19 00:03:139915 spdy::SpdySerializedFrame body(
Bence Békyd74f4382018-02-20 18:26:199916 spdy_util_.ConstructSpdyDataFrame(1, "The host does not exist", true));
[email protected]511f6f52010-12-17 03:58:299917 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:419918 CreateMockRead(resp, 1), CreateMockRead(body, 2),
rch8e6c6c42015-05-01 14:05:139919 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:299920 };
9921
Ryan Sleevib8d7ea02018-05-07 20:01:019922 SequencedSocketData data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069923 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:369924 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:299925
[email protected]bb88e1d32013-05-03 23:11:079926 session_deps_.socket_factory->AddSocketDataProvider(&data);
9927 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:299928
[email protected]49639fa2011-12-20 23:22:419929 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:299930
danakj1fd259a02016-04-16 03:17:099931 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169932 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:299933
tfarina42834112016-09-22 13:38:209934 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019935 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:299936
9937 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019938 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:299939
ttuttle960fcbf2016-04-19 13:26:329940 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:299941}
9942
[email protected]0c5fb722012-02-28 11:50:359943// Test the request-challenge-retry sequence for basic auth, through
9944// a SPDY proxy over a single SPDY session.
bncd16676a2016-07-20 16:23:019945TEST_F(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:359946 HttpRequestInfo request;
9947 request.method = "GET";
bncce36dca22015-04-21 22:11:239948 request.url = GURL("https://www.example.org/");
[email protected]0c5fb722012-02-28 11:50:359949 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:299950 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:109951 request.traffic_annotation =
9952 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0c5fb722012-02-28 11:50:359953
9954 // Configure against https proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:599955 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499956 ProxyResolutionService::CreateFixedFromPacResult(
9957 "HTTPS myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519958 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:079959 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:099960 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:359961
9962 // Since we have proxy, should try to establish tunnel.
Ryan Hamilton0239aac2018-05-19 00:03:139963 spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:049964 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
9965 HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:139966 spdy::SpdySerializedFrame rst(
9967 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
rdsmithebb50aa2015-11-12 03:44:389968 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]0c5fb722012-02-28 11:50:359969
bnc691fda62016-08-12 00:43:169970 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0c5fb722012-02-28 11:50:359971 // be issuing -- the final header line contains the credentials.
9972 const char* const kAuthCredentials[] = {
9973 "proxy-authorization", "Basic Zm9vOmJhcg==",
9974 };
Ryan Hamilton0239aac2018-05-19 00:03:139975 spdy::SpdySerializedFrame connect2(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:049976 kAuthCredentials, base::size(kAuthCredentials) / 2, 3,
9977 HttpProxyConnectJob::kH2QuicTunnelPriority,
bncce36dca22015-04-21 22:11:239978 HostPortPair("www.example.org", 443)));
9979 // fetch https://www.example.org/ via HTTP
9980 const char get[] =
9981 "GET / HTTP/1.1\r\n"
9982 "Host: www.example.org\r\n"
9983 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:139984 spdy::SpdySerializedFrame wrapped_get(
Bence Békyd74f4382018-02-20 18:26:199985 spdy_util_.ConstructSpdyDataFrame(3, get, false));
[email protected]0c5fb722012-02-28 11:50:359986
9987 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:419988 CreateMockWrite(req, 0, ASYNC), CreateMockWrite(rst, 2, ASYNC),
9989 CreateMockWrite(connect2, 3), CreateMockWrite(wrapped_get, 5),
[email protected]0c5fb722012-02-28 11:50:359990 };
9991
9992 // The proxy responds to the connect with a 407, using a persistent
9993 // connection.
thestig9d3bb0c2015-01-24 00:49:519994 const char kAuthStatus[] = "407";
[email protected]0c5fb722012-02-28 11:50:359995 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:359996 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
9997 };
Ryan Hamilton0239aac2018-05-19 00:03:139998 spdy::SpdySerializedFrame conn_auth_resp(spdy_util_.ConstructSpdyReplyError(
Avi Drissman4365a4782018-12-28 19:26:249999 kAuthStatus, kAuthChallenge, base::size(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:3510000
Ryan Hamilton0239aac2018-05-19 00:03:1310001 spdy::SpdySerializedFrame conn_resp(
Raul Tambre94493c652019-03-11 17:18:3510002 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
[email protected]0c5fb722012-02-28 11:50:3510003 const char resp[] = "HTTP/1.1 200 OK\r\n"
10004 "Content-Length: 5\r\n\r\n";
10005
Ryan Hamilton0239aac2018-05-19 00:03:1310006 spdy::SpdySerializedFrame wrapped_get_resp(
Bence Békyd74f4382018-02-20 18:26:1910007 spdy_util_.ConstructSpdyDataFrame(3, resp, false));
Ryan Hamilton0239aac2018-05-19 00:03:1310008 spdy::SpdySerializedFrame wrapped_body(
Bence Békyd74f4382018-02-20 18:26:1910009 spdy_util_.ConstructSpdyDataFrame(3, "hello", false));
[email protected]0c5fb722012-02-28 11:50:3510010 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4110011 CreateMockRead(conn_auth_resp, 1, ASYNC),
10012 CreateMockRead(conn_resp, 4, ASYNC),
10013 CreateMockRead(wrapped_get_resp, 6, ASYNC),
10014 CreateMockRead(wrapped_body, 7, ASYNC),
rch8e6c6c42015-05-01 14:05:1310015 MockRead(ASYNC, OK, 8), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:3510016 };
10017
Ryan Sleevib8d7ea02018-05-07 20:01:0110018 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0710019 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:3510020 // Negotiate SPDY to the proxy
10021 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610022 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0710023 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:3510024 // Vanilla SSL to the server
10025 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710026 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:3510027
10028 TestCompletionCallback callback1;
10029
bnc87dcefc2017-05-25 12:47:5810030 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1910031 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0c5fb722012-02-28 11:50:3510032
10033 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0110034 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:3510035
10036 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0110037 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:4610038 TestNetLogEntry::List entries;
[email protected]0c5fb722012-02-28 11:50:3510039 log.GetEntries(&entries);
10040 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0010041 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
10042 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:3510043 ExpectLogContainsSomewhere(
10044 entries, pos,
mikecirone8b85c432016-09-08 19:11:0010045 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
10046 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:3510047
10048 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210049 ASSERT_TRUE(response);
10050 ASSERT_TRUE(response->headers);
[email protected]0c5fb722012-02-28 11:50:3510051 EXPECT_EQ(407, response->headers->response_code());
10052 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
wezca1070932016-05-26 20:30:5210053 EXPECT_TRUE(response->auth_challenge);
asanka098c0092016-06-16 20:18:4310054 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]0c5fb722012-02-28 11:50:3510055
10056 TestCompletionCallback callback2;
10057
10058 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
10059 callback2.callback());
robpercival214763f2016-07-01 23:27:0110060 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:3510061
10062 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0110063 EXPECT_THAT(rv, IsOk());
[email protected]0c5fb722012-02-28 11:50:3510064
10065 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210066 ASSERT_TRUE(response);
[email protected]0c5fb722012-02-28 11:50:3510067
10068 EXPECT_TRUE(response->headers->IsKeepAlive());
10069 EXPECT_EQ(200, response->headers->response_code());
10070 EXPECT_EQ(5, response->headers->GetContentLength());
10071 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10072
10073 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:5210074 EXPECT_FALSE(response->auth_challenge);
[email protected]0c5fb722012-02-28 11:50:3510075
[email protected]029c83b62013-01-24 05:28:2010076 LoadTimingInfo load_timing_info;
10077 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10078 TestLoadTimingNotReusedWithPac(load_timing_info,
10079 CONNECT_TIMING_HAS_SSL_TIMES);
10080
[email protected]0c5fb722012-02-28 11:50:3510081 trans.reset();
10082 session->CloseAllConnections();
10083}
10084
[email protected]7c6f7ba2012-04-03 04:09:2910085// Test that an explicitly trusted SPDY proxy can push a resource from an
10086// origin that is different from that of its associated resource.
bncd16676a2016-07-20 16:23:0110087TEST_F(HttpNetworkTransactionTest, CrossOriginSPDYProxyPush) {
tbansal28e68f82016-02-04 02:56:1510088 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:1910089 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:1510090 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
10091 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]7c6f7ba2012-04-03 04:09:2910092 HttpRequestInfo request;
10093 HttpRequestInfo push_request;
Ramin Halavatib5e433e2018-02-07 07:41:1010094 request.traffic_annotation =
10095 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7c6f7ba2012-04-03 04:09:2910096
[email protected]7c6f7ba2012-04-03 04:09:2910097 request.method = "GET";
bncce36dca22015-04-21 22:11:2310098 request.url = GURL("http://www.example.org/");
[email protected]7c6f7ba2012-04-03 04:09:2910099 push_request.method = "GET";
10100 push_request.url = GURL("http://www.another-origin.com/foo.dat");
Ramin Halavatib5e433e2018-02-07 07:41:1010101 push_request.traffic_annotation =
10102 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7c6f7ba2012-04-03 04:09:2910103
tbansal28e68f82016-02-04 02:56:1510104 // Configure against https proxy server "myproxy:443".
Lily Houghton8c2f97d2018-01-22 05:06:5910105 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910106 ProxyResolutionService::CreateFixedFromPacResult(
10107 "HTTPS myproxy:443", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110108 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710109 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:5010110
Eric Roman3d8546a2018-09-10 17:00:5210111 session_deps_.proxy_resolution_service->SetProxyDelegate(
10112 proxy_delegate.get());
[email protected]61b4efc2012-04-27 18:12:5010113
danakj1fd259a02016-04-16 03:17:0910114 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:2910115
Ryan Hamilton0239aac2018-05-19 00:03:1310116 spdy::SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:4510117 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1310118 spdy::SpdySerializedFrame stream2_priority(
tombergan5d22c182017-01-11 02:05:3510119 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
[email protected]7c6f7ba2012-04-03 04:09:2910120
10121 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4110122 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:3510123 CreateMockWrite(stream2_priority, 3, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:2910124 };
10125
Ryan Hamilton0239aac2018-05-19 00:03:1310126 spdy::SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
Raul Tambre94493c652019-03-11 17:18:3510127 nullptr, 0, 2, 1, "http://www.another-origin.com/foo.dat"));
Bence Béky7bf94362018-01-10 13:19:3610128
Ryan Hamilton0239aac2018-05-19 00:03:1310129 spdy::SpdySerializedFrame stream1_reply(
Raul Tambre94493c652019-03-11 17:18:3510130 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:2910131
Ryan Hamilton0239aac2018-05-19 00:03:1310132 spdy::SpdySerializedFrame stream1_body(
10133 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:2910134
Ryan Hamilton0239aac2018-05-19 00:03:1310135 spdy::SpdySerializedFrame stream2_body(
Bence Békyd74f4382018-02-20 18:26:1910136 spdy_util_.ConstructSpdyDataFrame(2, "pushed", true));
[email protected]7c6f7ba2012-04-03 04:09:2910137
10138 MockRead spdy_reads[] = {
Bence Béky7bf94362018-01-10 13:19:3610139 CreateMockRead(stream2_syn, 1, ASYNC),
10140 CreateMockRead(stream1_reply, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:3510141 CreateMockRead(stream1_body, 4, ASYNC),
10142 CreateMockRead(stream2_body, 5, ASYNC),
10143 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
[email protected]7c6f7ba2012-04-03 04:09:2910144 };
10145
Ryan Sleevib8d7ea02018-05-07 20:01:0110146 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0710147 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:2910148 // Negotiate SPDY to the proxy
10149 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610150 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0710151 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:2910152
bnc87dcefc2017-05-25 12:47:5810153 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1910154 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7c6f7ba2012-04-03 04:09:2910155 TestCompletionCallback callback;
10156 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0110157 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:2910158
10159 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110160 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:2910161 const HttpResponseInfo* response = trans->GetResponseInfo();
10162
bnc87dcefc2017-05-25 12:47:5810163 auto push_trans =
Jeremy Roman0579ed62017-08-29 15:56:1910164 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]90499482013-06-01 00:39:5010165 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0110166 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:2910167
10168 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110169 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:2910170 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
10171
wezca1070932016-05-26 20:30:5210172 ASSERT_TRUE(response);
[email protected]7c6f7ba2012-04-03 04:09:2910173 EXPECT_TRUE(response->headers->IsKeepAlive());
10174
10175 EXPECT_EQ(200, response->headers->response_code());
10176 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10177
10178 std::string response_data;
10179 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:0110180 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:2910181 EXPECT_EQ("hello!", response_data);
10182
[email protected]029c83b62013-01-24 05:28:2010183 LoadTimingInfo load_timing_info;
10184 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10185 TestLoadTimingNotReusedWithPac(load_timing_info,
10186 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
10187
[email protected]7c6f7ba2012-04-03 04:09:2910188 // Verify the pushed stream.
wezca1070932016-05-26 20:30:5210189 EXPECT_TRUE(push_response->headers);
[email protected]7c6f7ba2012-04-03 04:09:2910190 EXPECT_EQ(200, push_response->headers->response_code());
10191
10192 rv = ReadTransaction(push_trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:0110193 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:2910194 EXPECT_EQ("pushed", response_data);
10195
[email protected]029c83b62013-01-24 05:28:2010196 LoadTimingInfo push_load_timing_info;
10197 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
10198 TestLoadTimingReusedWithPac(push_load_timing_info);
10199 // The transactions should share a socket ID, despite being for different
10200 // origins.
10201 EXPECT_EQ(load_timing_info.socket_log_id,
10202 push_load_timing_info.socket_log_id);
10203
[email protected]7c6f7ba2012-04-03 04:09:2910204 trans.reset();
10205 push_trans.reset();
10206 session->CloseAllConnections();
10207}
10208
[email protected]8c843192012-04-05 07:15:0010209// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
bncd16676a2016-07-20 16:23:0110210TEST_F(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:1510211 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:1910212 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:1510213 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
10214 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]8c843192012-04-05 07:15:0010215 HttpRequestInfo request;
10216
10217 request.method = "GET";
bncce36dca22015-04-21 22:11:2310218 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010219 request.traffic_annotation =
10220 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c843192012-04-05 07:15:0010221
Ramin Halavatica8d5252018-03-12 05:33:4910222 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
10223 "https://myproxy:443", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110224 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710225 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:5010226
10227 // Enable cross-origin push.
Eric Roman3d8546a2018-09-10 17:00:5210228 session_deps_.proxy_resolution_service->SetProxyDelegate(
10229 proxy_delegate.get());
[email protected]61b4efc2012-04-27 18:12:5010230
danakj1fd259a02016-04-16 03:17:0910231 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:0010232
Ryan Hamilton0239aac2018-05-19 00:03:1310233 spdy::SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:4510234 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
[email protected]8c843192012-04-05 07:15:0010235
Ryan Hamilton0239aac2018-05-19 00:03:1310236 spdy::SpdySerializedFrame push_rst(
10237 spdy_util_.ConstructSpdyRstStream(2, spdy::ERROR_CODE_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:0010238
10239 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4110240 CreateMockWrite(stream1_syn, 0, ASYNC), CreateMockWrite(push_rst, 3),
[email protected]8c843192012-04-05 07:15:0010241 };
10242
Ryan Hamilton0239aac2018-05-19 00:03:1310243 spdy::SpdySerializedFrame stream1_reply(
Raul Tambre94493c652019-03-11 17:18:3510244 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
[email protected]8c843192012-04-05 07:15:0010245
Ryan Hamilton0239aac2018-05-19 00:03:1310246 spdy::SpdySerializedFrame stream1_body(
10247 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]8c843192012-04-05 07:15:0010248
Ryan Hamilton0239aac2018-05-19 00:03:1310249 spdy::SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
Raul Tambre94493c652019-03-11 17:18:3510250 nullptr, 0, 2, 1, "https://www.another-origin.com/foo.dat"));
[email protected]8c843192012-04-05 07:15:0010251
10252 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4110253 CreateMockRead(stream1_reply, 1, ASYNC),
10254 CreateMockRead(stream2_syn, 2, ASYNC),
10255 CreateMockRead(stream1_body, 4, ASYNC),
mmenkee24011922015-12-17 22:12:5910256 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
[email protected]8c843192012-04-05 07:15:0010257 };
10258
Ryan Sleevib8d7ea02018-05-07 20:01:0110259 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0710260 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:0010261 // Negotiate SPDY to the proxy
10262 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610263 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0710264 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:0010265
bnc87dcefc2017-05-25 12:47:5810266 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1910267 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]8c843192012-04-05 07:15:0010268 TestCompletionCallback callback;
10269 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0110270 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c843192012-04-05 07:15:0010271
10272 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110273 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:0010274 const HttpResponseInfo* response = trans->GetResponseInfo();
10275
wezca1070932016-05-26 20:30:5210276 ASSERT_TRUE(response);
[email protected]8c843192012-04-05 07:15:0010277 EXPECT_TRUE(response->headers->IsKeepAlive());
10278
10279 EXPECT_EQ(200, response->headers->response_code());
10280 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10281
10282 std::string response_data;
10283 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:0110284 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:0010285 EXPECT_EQ("hello!", response_data);
10286
10287 trans.reset();
10288 session->CloseAllConnections();
10289}
10290
tbansal8ef1d3e2016-02-03 04:05:4210291// Test that an explicitly trusted SPDY proxy can push same-origin HTTPS
10292// resources.
bncd16676a2016-07-20 16:23:0110293TEST_F(HttpNetworkTransactionTest, SameOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:1510294 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:1910295 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:1510296 proxy_delegate->set_trusted_spdy_proxy(
10297 net::ProxyServer::FromURI("myproxy:70", net::ProxyServer::SCHEME_HTTP));
10298
tbansal8ef1d3e2016-02-03 04:05:4210299 HttpRequestInfo request;
10300
10301 request.method = "GET";
10302 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010303 request.traffic_annotation =
10304 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal8ef1d3e2016-02-03 04:05:4210305
10306 // Configure against https proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:4910307 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
10308 "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal8ef1d3e2016-02-03 04:05:4210309 BoundTestNetLog log;
10310 session_deps_.net_log = log.bound().net_log();
10311
10312 // Enable cross-origin push.
Eric Roman3d8546a2018-09-10 17:00:5210313 session_deps_.proxy_resolution_service->SetProxyDelegate(
10314 proxy_delegate.get());
tbansal8ef1d3e2016-02-03 04:05:4210315
danakj1fd259a02016-04-16 03:17:0910316 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
tbansal8ef1d3e2016-02-03 04:05:4210317
Ryan Hamilton0239aac2018-05-19 00:03:1310318 spdy::SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:4510319 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1310320 spdy::SpdySerializedFrame stream2_priority(
tombergan5d22c182017-01-11 02:05:3510321 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
tbansal8ef1d3e2016-02-03 04:05:4210322
10323 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4110324 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:3510325 CreateMockWrite(stream2_priority, 3, ASYNC),
tbansal8ef1d3e2016-02-03 04:05:4210326 };
10327
Ryan Hamilton0239aac2018-05-19 00:03:1310328 spdy::SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:1510329 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:4210330
Ryan Hamilton0239aac2018-05-19 00:03:1310331 spdy::SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
Bence Béky096cf052017-08-08 23:55:3310332 nullptr, 0, 2, 1, "http://www.example.org/foo.dat"));
bnc38dcd392016-02-09 23:19:4910333
Ryan Hamilton0239aac2018-05-19 00:03:1310334 spdy::SpdySerializedFrame stream1_body(
10335 spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:4210336
Ryan Hamilton0239aac2018-05-19 00:03:1310337 spdy::SpdySerializedFrame stream2_reply(
bnc42331402016-07-25 13:36:1510338 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:4210339
Ryan Hamilton0239aac2018-05-19 00:03:1310340 spdy::SpdySerializedFrame stream2_body(
10341 spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:4210342
10343 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4110344 CreateMockRead(stream1_reply, 1, ASYNC),
10345 CreateMockRead(stream2_syn, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:3510346 CreateMockRead(stream1_body, 4, ASYNC),
10347 CreateMockRead(stream2_body, 5, ASYNC),
10348 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
tbansal8ef1d3e2016-02-03 04:05:4210349 };
10350
Ryan Sleevib8d7ea02018-05-07 20:01:0110351 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
tbansal8ef1d3e2016-02-03 04:05:4210352 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
10353 // Negotiate SPDY to the proxy
10354 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610355 proxy.next_proto = kProtoHTTP2;
tbansal8ef1d3e2016-02-03 04:05:4210356 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
10357
bnc87dcefc2017-05-25 12:47:5810358 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1910359 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tbansal8ef1d3e2016-02-03 04:05:4210360 TestCompletionCallback callback;
10361 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0110362 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
tbansal8ef1d3e2016-02-03 04:05:4210363
10364 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110365 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:4210366 const HttpResponseInfo* response = trans->GetResponseInfo();
10367
wezca1070932016-05-26 20:30:5210368 ASSERT_TRUE(response);
tbansal8ef1d3e2016-02-03 04:05:4210369 EXPECT_TRUE(response->headers->IsKeepAlive());
10370
10371 EXPECT_EQ(200, response->headers->response_code());
10372 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10373
10374 std::string response_data;
10375 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:0110376 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:4210377 EXPECT_EQ("hello!", response_data);
10378
10379 trans.reset();
10380 session->CloseAllConnections();
10381}
10382
[email protected]2df19bb2010-08-25 20:13:4610383// Test HTTPS connections to a site with a bad certificate, going through an
10384// HTTPS proxy
bncd16676a2016-07-20 16:23:0110385TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
Ramin Halavatica8d5252018-03-12 05:33:4910386 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
10387 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:4610388
10389 HttpRequestInfo request;
10390 request.method = "GET";
bncce36dca22015-04-21 22:11:2310391 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010392 request.traffic_annotation =
10393 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:4610394
10395 // Attempt to fetch the URL from a server with a bad cert
10396 MockWrite bad_cert_writes[] = {
rsleevidb16bb02015-11-12 23:47:1710397 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
10398 "Host: www.example.org:443\r\n"
10399 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:4610400 };
10401
10402 MockRead bad_cert_reads[] = {
10403 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610404 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:4610405 };
10406
10407 // Attempt to fetch the URL with a good cert
10408 MockWrite good_data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1710409 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
10410 "Host: www.example.org:443\r\n"
10411 "Proxy-Connection: keep-alive\r\n\r\n"),
10412 MockWrite("GET / HTTP/1.1\r\n"
10413 "Host: www.example.org\r\n"
10414 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:4610415 };
10416
10417 MockRead good_cert_reads[] = {
10418 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
10419 MockRead("HTTP/1.0 200 OK\r\n"),
10420 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10421 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610422 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:4610423 };
10424
Ryan Sleevib8d7ea02018-05-07 20:01:0110425 StaticSocketDataProvider ssl_bad_certificate(bad_cert_reads, bad_cert_writes);
10426 StaticSocketDataProvider data(good_cert_reads, good_data_writes);
[email protected]8ddf8322012-02-23 18:08:0610427 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
10428 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:4610429
10430 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:0710431 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10432 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
10433 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:4610434
10435 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:0710436 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10437 session_deps_.socket_factory->AddSocketDataProvider(&data);
10438 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:4610439
[email protected]49639fa2011-12-20 23:22:4110440 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:4610441
danakj1fd259a02016-04-16 03:17:0910442 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610443 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:4610444
tfarina42834112016-09-22 13:38:2010445 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110446 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:4610447
10448 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110449 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]2df19bb2010-08-25 20:13:4610450
bnc691fda62016-08-12 00:43:1610451 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:0110452 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:4610453
10454 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110455 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:4610456
bnc691fda62016-08-12 00:43:1610457 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:4610458
wezca1070932016-05-26 20:30:5210459 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:4610460 EXPECT_EQ(100, response->headers->GetContentLength());
10461}
10462
bncd16676a2016-07-20 16:23:0110463TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:4210464 HttpRequestInfo request;
10465 request.method = "GET";
bncce36dca22015-04-21 22:11:2310466 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:4310467 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
10468 "Chromium Ultra Awesome X Edition");
Ramin Halavatib5e433e2018-02-07 07:41:1010469 request.traffic_annotation =
10470 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210471
danakj1fd259a02016-04-16 03:17:0910472 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610473 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710474
[email protected]1c773ea12009-04-28 19:58:4210475 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310476 MockWrite(
10477 "GET / HTTP/1.1\r\n"
10478 "Host: www.example.org\r\n"
10479 "Connection: keep-alive\r\n"
10480 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210481 };
10482
10483 // Lastly, the server responds with the actual content.
10484 MockRead data_reads[] = {
10485 MockRead("HTTP/1.0 200 OK\r\n"),
10486 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10487 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610488 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210489 };
10490
Ryan Sleevib8d7ea02018-05-07 20:01:0110491 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710492 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210493
[email protected]49639fa2011-12-20 23:22:4110494 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210495
tfarina42834112016-09-22 13:38:2010496 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110497 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210498
10499 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110500 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210501}
10502
bncd16676a2016-07-20 16:23:0110503TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
Matt Menked732ea42019-03-08 12:05:0010504 // Test user agent values, used both for the request header of the original
10505 // request, and the value returned by the HttpUserAgentSettings. nullptr means
10506 // no request header / no HttpUserAgentSettings object.
10507 const char* kTestUserAgents[] = {nullptr, "", "Foopy"};
[email protected]da81f132010-08-18 23:39:2910508
Matt Menked732ea42019-03-08 12:05:0010509 for (const char* setting_user_agent : kTestUserAgents) {
10510 if (!setting_user_agent) {
10511 session_deps_.http_user_agent_settings.reset();
10512 } else {
10513 session_deps_.http_user_agent_settings =
10514 std::make_unique<StaticHttpUserAgentSettings>(
10515 std::string() /* accept-language */, setting_user_agent);
10516 }
10517 session_deps_.proxy_resolution_service =
10518 ProxyResolutionService::CreateFixed("myproxy:70",
10519 TRAFFIC_ANNOTATION_FOR_TESTS);
10520 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10521 for (const char* request_user_agent : kTestUserAgents) {
10522 HttpRequestInfo request;
10523 request.method = "GET";
10524 request.url = GURL("https://www.example.org/");
10525 if (request_user_agent) {
10526 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
10527 request_user_agent);
10528 }
10529 request.traffic_annotation =
10530 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710531
Matt Menked732ea42019-03-08 12:05:0010532 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]da81f132010-08-18 23:39:2910533
Matt Menked732ea42019-03-08 12:05:0010534 std::string expected_request;
10535 if (!setting_user_agent || strlen(setting_user_agent) == 0) {
10536 expected_request =
10537 "CONNECT www.example.org:443 HTTP/1.1\r\n"
10538 "Host: www.example.org:443\r\n"
10539 "Proxy-Connection: keep-alive\r\n\r\n";
10540 } else {
10541 expected_request = base::StringPrintf(
10542 "CONNECT www.example.org:443 HTTP/1.1\r\n"
10543 "Host: www.example.org:443\r\n"
10544 "Proxy-Connection: keep-alive\r\n"
10545 "User-Agent: %s\r\n\r\n",
10546 setting_user_agent);
10547 }
10548 MockWrite data_writes[] = {
10549 MockWrite(expected_request.c_str()),
10550 };
10551 MockRead data_reads[] = {
10552 // Return an error, so the transaction stops here (this test isn't
10553 // interested in the rest).
10554 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
10555 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
10556 MockRead("Proxy-Connection: close\r\n\r\n"),
10557 };
[email protected]da81f132010-08-18 23:39:2910558
Matt Menked732ea42019-03-08 12:05:0010559 StaticSocketDataProvider data(data_reads, data_writes);
10560 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:2910561
Matt Menked732ea42019-03-08 12:05:0010562 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:2910563
Matt Menked732ea42019-03-08 12:05:0010564 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
10565 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10566
10567 rv = callback.WaitForResult();
10568 EXPECT_THAT(rv, IsOk());
10569 }
10570 }
[email protected]da81f132010-08-18 23:39:2910571}
10572
bncd16676a2016-07-20 16:23:0110573TEST_F(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:4210574 HttpRequestInfo request;
10575 request.method = "GET";
bncce36dca22015-04-21 22:11:2310576 request.url = GURL("http://www.example.org/");
[email protected]c10450102011-06-27 09:06:1610577 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
10578 "http://the.previous.site.com/");
Ramin Halavatib5e433e2018-02-07 07:41:1010579 request.traffic_annotation =
10580 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210581
danakj1fd259a02016-04-16 03:17:0910582 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610583 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710584
[email protected]1c773ea12009-04-28 19:58:4210585 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310586 MockWrite(
10587 "GET / HTTP/1.1\r\n"
10588 "Host: www.example.org\r\n"
10589 "Connection: keep-alive\r\n"
10590 "Referer: http://the.previous.site.com/\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210591 };
10592
10593 // Lastly, the server responds with the actual content.
10594 MockRead data_reads[] = {
10595 MockRead("HTTP/1.0 200 OK\r\n"),
10596 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10597 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610598 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210599 };
10600
Ryan Sleevib8d7ea02018-05-07 20:01:0110601 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710602 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210603
[email protected]49639fa2011-12-20 23:22:4110604 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210605
tfarina42834112016-09-22 13:38:2010606 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110607 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210608
10609 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110610 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210611}
10612
bncd16676a2016-07-20 16:23:0110613TEST_F(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:4210614 HttpRequestInfo request;
10615 request.method = "POST";
bncce36dca22015-04-21 22:11:2310616 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010617 request.traffic_annotation =
10618 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210619
danakj1fd259a02016-04-16 03:17:0910620 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610621 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710622
[email protected]1c773ea12009-04-28 19:58:4210623 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310624 MockWrite(
10625 "POST / HTTP/1.1\r\n"
10626 "Host: www.example.org\r\n"
10627 "Connection: keep-alive\r\n"
10628 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210629 };
10630
10631 // Lastly, the server responds with the actual content.
10632 MockRead data_reads[] = {
10633 MockRead("HTTP/1.0 200 OK\r\n"),
10634 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10635 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610636 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210637 };
10638
Ryan Sleevib8d7ea02018-05-07 20:01:0110639 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710640 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210641
[email protected]49639fa2011-12-20 23:22:4110642 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210643
tfarina42834112016-09-22 13:38:2010644 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110645 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210646
10647 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110648 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210649}
10650
bncd16676a2016-07-20 16:23:0110651TEST_F(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:4210652 HttpRequestInfo request;
10653 request.method = "PUT";
bncce36dca22015-04-21 22:11:2310654 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010655 request.traffic_annotation =
10656 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210657
danakj1fd259a02016-04-16 03:17:0910658 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610659 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710660
[email protected]1c773ea12009-04-28 19:58:4210661 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310662 MockWrite(
10663 "PUT / HTTP/1.1\r\n"
10664 "Host: www.example.org\r\n"
10665 "Connection: keep-alive\r\n"
10666 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210667 };
10668
10669 // Lastly, the server responds with the actual content.
10670 MockRead data_reads[] = {
10671 MockRead("HTTP/1.0 200 OK\r\n"),
10672 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10673 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610674 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210675 };
10676
Ryan Sleevib8d7ea02018-05-07 20:01:0110677 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710678 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210679
[email protected]49639fa2011-12-20 23:22:4110680 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210681
tfarina42834112016-09-22 13:38:2010682 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110683 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210684
10685 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110686 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210687}
10688
bncd16676a2016-07-20 16:23:0110689TEST_F(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:4210690 HttpRequestInfo request;
10691 request.method = "HEAD";
bncce36dca22015-04-21 22:11:2310692 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010693 request.traffic_annotation =
10694 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210695
danakj1fd259a02016-04-16 03:17:0910696 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610697 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710698
[email protected]1c773ea12009-04-28 19:58:4210699 MockWrite data_writes[] = {
csharrisonf473dd192015-08-18 13:54:1310700 MockWrite("HEAD / HTTP/1.1\r\n"
10701 "Host: www.example.org\r\n"
10702 "Connection: keep-alive\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210703 };
10704
10705 // Lastly, the server responds with the actual content.
10706 MockRead data_reads[] = {
10707 MockRead("HTTP/1.0 200 OK\r\n"),
10708 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10709 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610710 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210711 };
10712
Ryan Sleevib8d7ea02018-05-07 20:01:0110713 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710714 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210715
[email protected]49639fa2011-12-20 23:22:4110716 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210717
tfarina42834112016-09-22 13:38:2010718 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110719 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210720
10721 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110722 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210723}
10724
bncd16676a2016-07-20 16:23:0110725TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:4210726 HttpRequestInfo request;
10727 request.method = "GET";
bncce36dca22015-04-21 22:11:2310728 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:4210729 request.load_flags = LOAD_BYPASS_CACHE;
Ramin Halavatib5e433e2018-02-07 07:41:1010730 request.traffic_annotation =
10731 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210732
danakj1fd259a02016-04-16 03:17:0910733 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610734 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710735
[email protected]1c773ea12009-04-28 19:58:4210736 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310737 MockWrite(
10738 "GET / HTTP/1.1\r\n"
10739 "Host: www.example.org\r\n"
10740 "Connection: keep-alive\r\n"
10741 "Pragma: no-cache\r\n"
10742 "Cache-Control: no-cache\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210743 };
10744
10745 // Lastly, the server responds with the actual content.
10746 MockRead data_reads[] = {
10747 MockRead("HTTP/1.0 200 OK\r\n"),
10748 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10749 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610750 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210751 };
10752
Ryan Sleevib8d7ea02018-05-07 20:01:0110753 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710754 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210755
[email protected]49639fa2011-12-20 23:22:4110756 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210757
tfarina42834112016-09-22 13:38:2010758 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110759 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210760
10761 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110762 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210763}
10764
bncd16676a2016-07-20 16:23:0110765TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:4210766 HttpRequestInfo request;
10767 request.method = "GET";
bncce36dca22015-04-21 22:11:2310768 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:4210769 request.load_flags = LOAD_VALIDATE_CACHE;
Ramin Halavatib5e433e2018-02-07 07:41:1010770 request.traffic_annotation =
10771 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210772
danakj1fd259a02016-04-16 03:17:0910773 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610774 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710775
[email protected]1c773ea12009-04-28 19:58:4210776 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310777 MockWrite(
10778 "GET / HTTP/1.1\r\n"
10779 "Host: www.example.org\r\n"
10780 "Connection: keep-alive\r\n"
10781 "Cache-Control: max-age=0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210782 };
10783
10784 // Lastly, the server responds with the actual content.
10785 MockRead data_reads[] = {
10786 MockRead("HTTP/1.0 200 OK\r\n"),
10787 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10788 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610789 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210790 };
10791
Ryan Sleevib8d7ea02018-05-07 20:01:0110792 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710793 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210794
[email protected]49639fa2011-12-20 23:22:4110795 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210796
tfarina42834112016-09-22 13:38:2010797 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110798 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210799
10800 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110801 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210802}
10803
bncd16676a2016-07-20 16:23:0110804TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:4210805 HttpRequestInfo request;
10806 request.method = "GET";
bncce36dca22015-04-21 22:11:2310807 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:4310808 request.extra_headers.SetHeader("FooHeader", "Bar");
Ramin Halavatib5e433e2018-02-07 07:41:1010809 request.traffic_annotation =
10810 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210811
danakj1fd259a02016-04-16 03:17:0910812 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610813 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710814
[email protected]1c773ea12009-04-28 19:58:4210815 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310816 MockWrite(
10817 "GET / HTTP/1.1\r\n"
10818 "Host: www.example.org\r\n"
10819 "Connection: keep-alive\r\n"
10820 "FooHeader: Bar\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210821 };
10822
10823 // Lastly, the server responds with the actual content.
10824 MockRead data_reads[] = {
10825 MockRead("HTTP/1.0 200 OK\r\n"),
10826 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10827 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610828 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210829 };
10830
Ryan Sleevib8d7ea02018-05-07 20:01:0110831 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710832 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210833
[email protected]49639fa2011-12-20 23:22:4110834 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210835
tfarina42834112016-09-22 13:38:2010836 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110837 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210838
10839 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110840 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210841}
10842
bncd16676a2016-07-20 16:23:0110843TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:4710844 HttpRequestInfo request;
10845 request.method = "GET";
bncce36dca22015-04-21 22:11:2310846 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:4310847 request.extra_headers.SetHeader("referer", "www.foo.com");
10848 request.extra_headers.SetHeader("hEllo", "Kitty");
10849 request.extra_headers.SetHeader("FoO", "bar");
Ramin Halavatib5e433e2018-02-07 07:41:1010850 request.traffic_annotation =
10851 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]270c6412010-03-29 22:02:4710852
danakj1fd259a02016-04-16 03:17:0910853 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610854 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710855
[email protected]270c6412010-03-29 22:02:4710856 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310857 MockWrite(
10858 "GET / HTTP/1.1\r\n"
10859 "Host: www.example.org\r\n"
10860 "Connection: keep-alive\r\n"
10861 "referer: www.foo.com\r\n"
10862 "hEllo: Kitty\r\n"
10863 "FoO: bar\r\n\r\n"),
[email protected]270c6412010-03-29 22:02:4710864 };
10865
10866 // Lastly, the server responds with the actual content.
10867 MockRead data_reads[] = {
10868 MockRead("HTTP/1.0 200 OK\r\n"),
10869 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10870 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610871 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:4710872 };
10873
Ryan Sleevib8d7ea02018-05-07 20:01:0110874 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710875 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:4710876
[email protected]49639fa2011-12-20 23:22:4110877 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:4710878
tfarina42834112016-09-22 13:38:2010879 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110880 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]270c6412010-03-29 22:02:4710881
10882 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110883 EXPECT_THAT(rv, IsOk());
[email protected]270c6412010-03-29 22:02:4710884}
10885
bncd16676a2016-07-20 16:23:0110886TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:2710887 HttpRequestInfo request;
10888 request.method = "GET";
bncce36dca22015-04-21 22:11:2310889 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010890 request.traffic_annotation =
10891 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710892
Lily Houghton8c2f97d2018-01-22 05:06:5910893 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910894 ProxyResolutionService::CreateFixedFromPacResult(
10895 "SOCKS myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110896 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710897 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:0210898
danakj1fd259a02016-04-16 03:17:0910899 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610900 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:0210901
[email protected]3cd17242009-06-23 02:59:0210902 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
10903 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
10904
10905 MockWrite data_writes[] = {
Avi Drissman4365a4782018-12-28 19:26:2410906 MockWrite(ASYNC, write_buffer, base::size(write_buffer)),
10907 MockWrite("GET / HTTP/1.1\r\n"
10908 "Host: www.example.org\r\n"
10909 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:0210910
10911 MockRead data_reads[] = {
Avi Drissman4365a4782018-12-28 19:26:2410912 MockRead(ASYNC, read_buffer, base::size(read_buffer)),
10913 MockRead("HTTP/1.0 200 OK\r\n"),
10914 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
10915 MockRead("Payload"), MockRead(SYNCHRONOUS, OK)};
[email protected]3cd17242009-06-23 02:59:0210916
Ryan Sleevib8d7ea02018-05-07 20:01:0110917 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710918 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:0210919
[email protected]49639fa2011-12-20 23:22:4110920 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:0210921
tfarina42834112016-09-22 13:38:2010922 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110923 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:0210924
10925 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110926 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0210927
bnc691fda62016-08-12 00:43:1610928 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210929 ASSERT_TRUE(response);
[email protected]3cd17242009-06-23 02:59:0210930
tbansal2ecbbc72016-10-06 17:15:4710931 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]029c83b62013-01-24 05:28:2010932 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1610933 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2010934 TestLoadTimingNotReusedWithPac(load_timing_info,
10935 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
10936
[email protected]3cd17242009-06-23 02:59:0210937 std::string response_text;
bnc691fda62016-08-12 00:43:1610938 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0110939 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0210940 EXPECT_EQ("Payload", response_text);
10941}
10942
bncd16676a2016-07-20 16:23:0110943TEST_F(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:2710944 HttpRequestInfo request;
10945 request.method = "GET";
bncce36dca22015-04-21 22:11:2310946 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010947 request.traffic_annotation =
10948 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710949
Lily Houghton8c2f97d2018-01-22 05:06:5910950 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910951 ProxyResolutionService::CreateFixedFromPacResult(
10952 "SOCKS myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110953 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710954 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:0210955
danakj1fd259a02016-04-16 03:17:0910956 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610957 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:0210958
[email protected]3cd17242009-06-23 02:59:0210959 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
10960 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
10961
10962 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310963 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
Avi Drissman4365a4782018-12-28 19:26:2410964 base::size(write_buffer)),
10965 MockWrite("GET / HTTP/1.1\r\n"
10966 "Host: www.example.org\r\n"
10967 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:0210968
10969 MockRead data_reads[] = {
Avi Drissman4365a4782018-12-28 19:26:2410970 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
10971 base::size(read_buffer)),
10972 MockRead("HTTP/1.0 200 OK\r\n"),
10973 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
10974 MockRead("Payload"), MockRead(SYNCHRONOUS, OK)};
[email protected]e0c27be2009-07-15 13:09:3510975
Ryan Sleevib8d7ea02018-05-07 20:01:0110976 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710977 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:3510978
[email protected]8ddf8322012-02-23 18:08:0610979 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710980 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:3510981
[email protected]49639fa2011-12-20 23:22:4110982 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:3510983
tfarina42834112016-09-22 13:38:2010984 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110985 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:3510986
10987 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110988 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3510989
[email protected]029c83b62013-01-24 05:28:2010990 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1610991 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2010992 TestLoadTimingNotReusedWithPac(load_timing_info,
10993 CONNECT_TIMING_HAS_SSL_TIMES);
10994
bnc691fda62016-08-12 00:43:1610995 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210996 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:4710997 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:3510998
10999 std::string response_text;
bnc691fda62016-08-12 00:43:1611000 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0111001 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3511002 EXPECT_EQ("Payload", response_text);
11003}
11004
bncd16676a2016-07-20 16:23:0111005TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:2011006 HttpRequestInfo request;
11007 request.method = "GET";
bncce36dca22015-04-21 22:11:2311008 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011009 request.traffic_annotation =
11010 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:2011011
Ramin Halavatica8d5252018-03-12 05:33:4911012 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
11013 "socks4://myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5111014 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0711015 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:2011016
danakj1fd259a02016-04-16 03:17:0911017 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611018 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:2011019
11020 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
11021 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
11022
11023 MockWrite data_writes[] = {
Avi Drissman4365a4782018-12-28 19:26:2411024 MockWrite(ASYNC, write_buffer, base::size(write_buffer)),
11025 MockWrite("GET / HTTP/1.1\r\n"
11026 "Host: www.example.org\r\n"
11027 "Connection: keep-alive\r\n\r\n")};
[email protected]029c83b62013-01-24 05:28:2011028
11029 MockRead data_reads[] = {
Avi Drissman4365a4782018-12-28 19:26:2411030 MockRead(ASYNC, read_buffer, base::size(read_buffer)),
11031 MockRead("HTTP/1.0 200 OK\r\n"),
11032 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
11033 MockRead("Payload"), MockRead(SYNCHRONOUS, OK)};
[email protected]029c83b62013-01-24 05:28:2011034
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]029c83b62013-01-24 05:28:2011037
11038 TestCompletionCallback callback;
11039
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]029c83b62013-01-24 05:28:2011042
11043 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111044 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:2011045
bnc691fda62016-08-12 00:43:1611046 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211047 ASSERT_TRUE(response);
[email protected]029c83b62013-01-24 05:28:2011048
11049 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1611050 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2011051 TestLoadTimingNotReused(load_timing_info,
11052 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
11053
11054 std::string response_text;
bnc691fda62016-08-12 00:43:1611055 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0111056 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:2011057 EXPECT_EQ("Payload", response_text);
11058}
11059
bncd16676a2016-07-20 16:23:0111060TEST_F(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:2711061 HttpRequestInfo request;
11062 request.method = "GET";
bncce36dca22015-04-21 22:11:2311063 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011064 request.traffic_annotation =
11065 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2711066
Lily Houghton8c2f97d2018-01-22 05:06:5911067 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4911068 ProxyResolutionService::CreateFixedFromPacResult(
11069 "SOCKS5 myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5111070 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0711071 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:3511072
danakj1fd259a02016-04-16 03:17:0911073 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611074 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:3511075
[email protected]e0c27be2009-07-15 13:09:3511076 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
11077 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:3711078 const char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:2311079 0x05, // Version
11080 0x01, // Command (CONNECT)
11081 0x00, // Reserved.
11082 0x03, // Address type (DOMAINNAME).
11083 0x0F, // Length of domain (15)
11084 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
11085 '.', 'o', 'r', 'g', 0x00, 0x50, // 16-bit port (80)
[email protected]f209dba2009-12-18 00:24:3711086 };
[email protected]e0c27be2009-07-15 13:09:3511087 const char kSOCKS5OkResponse[] =
11088 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
11089
11090 MockWrite data_writes[] = {
Avi Drissman4365a4782018-12-28 19:26:2411091 MockWrite(ASYNC, kSOCKS5GreetRequest, base::size(kSOCKS5GreetRequest)),
11092 MockWrite(ASYNC, kSOCKS5OkRequest, base::size(kSOCKS5OkRequest)),
11093 MockWrite("GET / HTTP/1.1\r\n"
11094 "Host: www.example.org\r\n"
11095 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:3511096
11097 MockRead data_reads[] = {
Avi Drissman4365a4782018-12-28 19:26:2411098 MockRead(ASYNC, kSOCKS5GreetResponse, base::size(kSOCKS5GreetResponse)),
11099 MockRead(ASYNC, kSOCKS5OkResponse, base::size(kSOCKS5OkResponse)),
11100 MockRead("HTTP/1.0 200 OK\r\n"),
11101 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
11102 MockRead("Payload"),
11103 MockRead(SYNCHRONOUS, OK)};
[email protected]e0c27be2009-07-15 13:09:3511104
Ryan Sleevib8d7ea02018-05-07 20:01:0111105 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0711106 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:3511107
[email protected]49639fa2011-12-20 23:22:4111108 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:3511109
tfarina42834112016-09-22 13:38:2011110 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111111 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:3511112
11113 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111114 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3511115
bnc691fda62016-08-12 00:43:1611116 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211117 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:4711118 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:3511119
[email protected]029c83b62013-01-24 05:28:2011120 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1611121 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2011122 TestLoadTimingNotReusedWithPac(load_timing_info,
11123 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
11124
[email protected]e0c27be2009-07-15 13:09:3511125 std::string response_text;
bnc691fda62016-08-12 00:43:1611126 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0111127 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3511128 EXPECT_EQ("Payload", response_text);
11129}
11130
bncd16676a2016-07-20 16:23:0111131TEST_F(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:2711132 HttpRequestInfo request;
11133 request.method = "GET";
bncce36dca22015-04-21 22:11:2311134 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011135 request.traffic_annotation =
11136 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2711137
Lily Houghton8c2f97d2018-01-22 05:06:5911138 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4911139 ProxyResolutionService::CreateFixedFromPacResult(
11140 "SOCKS5 myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5111141 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0711142 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:3511143
danakj1fd259a02016-04-16 03:17:0911144 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611145 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:3511146
[email protected]e0c27be2009-07-15 13:09:3511147 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
11148 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:3711149 const unsigned char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:2311150 0x05, // Version
11151 0x01, // Command (CONNECT)
11152 0x00, // Reserved.
11153 0x03, // Address type (DOMAINNAME).
11154 0x0F, // Length of domain (15)
11155 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
11156 '.', 'o', 'r', 'g', 0x01, 0xBB, // 16-bit port (443)
[email protected]f209dba2009-12-18 00:24:3711157 };
11158
[email protected]e0c27be2009-07-15 13:09:3511159 const char kSOCKS5OkResponse[] =
11160 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
11161
11162 MockWrite data_writes[] = {
Avi Drissman4365a4782018-12-28 19:26:2411163 MockWrite(ASYNC, kSOCKS5GreetRequest, base::size(kSOCKS5GreetRequest)),
bncce36dca22015-04-21 22:11:2311164 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
Avi Drissman4365a4782018-12-28 19:26:2411165 base::size(kSOCKS5OkRequest)),
11166 MockWrite("GET / HTTP/1.1\r\n"
11167 "Host: www.example.org\r\n"
11168 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:3511169
11170 MockRead data_reads[] = {
Avi Drissman4365a4782018-12-28 19:26:2411171 MockRead(ASYNC, kSOCKS5GreetResponse, base::size(kSOCKS5GreetResponse)),
11172 MockRead(ASYNC, kSOCKS5OkResponse, base::size(kSOCKS5OkResponse)),
11173 MockRead("HTTP/1.0 200 OK\r\n"),
11174 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
11175 MockRead("Payload"),
11176 MockRead(SYNCHRONOUS, OK)};
[email protected]3cd17242009-06-23 02:59:0211177
Ryan Sleevib8d7ea02018-05-07 20:01:0111178 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0711179 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:0211180
[email protected]8ddf8322012-02-23 18:08:0611181 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0711182 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:0211183
[email protected]49639fa2011-12-20 23:22:4111184 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:0211185
tfarina42834112016-09-22 13:38:2011186 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111187 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:0211188
11189 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111190 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0211191
bnc691fda62016-08-12 00:43:1611192 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211193 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:4711194 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]3cd17242009-06-23 02:59:0211195
[email protected]029c83b62013-01-24 05:28:2011196 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1611197 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2011198 TestLoadTimingNotReusedWithPac(load_timing_info,
11199 CONNECT_TIMING_HAS_SSL_TIMES);
11200
[email protected]3cd17242009-06-23 02:59:0211201 std::string response_text;
bnc691fda62016-08-12 00:43:1611202 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0111203 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0211204 EXPECT_EQ("Payload", response_text);
11205}
11206
[email protected]448d4ca52012-03-04 04:12:2311207namespace {
11208
Matt Menkef6edce752019-03-19 17:21:5611209// Tests that for connection endpoints the group ids are correctly set.
[email protected]2d731a32010-04-29 01:04:0611210
Matt Menkef6edce752019-03-19 17:21:5611211struct GroupIdTest {
[email protected]2d731a32010-04-29 01:04:0611212 std::string proxy_server;
11213 std::string url;
Matt Menkef6edce752019-03-19 17:21:5611214 ClientSocketPool::GroupId expected_group_id;
[email protected]e60e47a2010-07-14 03:37:1811215 bool ssl;
[email protected]2d731a32010-04-29 01:04:0611216};
11217
Matt Menkef6edce752019-03-19 17:21:5611218std::unique_ptr<HttpNetworkSession> SetupSessionForGroupIdTests(
[email protected]bb88e1d32013-05-03 23:11:0711219 SpdySessionDependencies* session_deps_) {
danakj1fd259a02016-04-16 03:17:0911220 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:0611221
bnc525e175a2016-06-20 12:36:4011222 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311223 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2111224 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnc7dc7e1b42015-07-28 14:43:1211225 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111226 http_server_properties->SetHttp2AlternativeService(
bncaa60ff402016-06-22 19:12:4211227 url::SchemeHostPort("https", "host.with.alternate", 443),
zhongyi3d4a55e72016-04-22 20:36:4611228 alternative_service, expiration);
[email protected]2d731a32010-04-29 01:04:0611229
11230 return session;
11231}
11232
Matt Menkef6edce752019-03-19 17:21:5611233int GroupIdTransactionHelper(const std::string& url,
11234 HttpNetworkSession* session) {
[email protected]2d731a32010-04-29 01:04:0611235 HttpRequestInfo request;
11236 request.method = "GET";
11237 request.url = GURL(url);
Ramin Halavatib5e433e2018-02-07 07:41:1011238 request.traffic_annotation =
11239 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d731a32010-04-29 01:04:0611240
bnc691fda62016-08-12 00:43:1611241 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
[email protected]cb9bf6ca2011-01-28 13:15:2711242
[email protected]49639fa2011-12-20 23:22:4111243 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:0611244
11245 // We do not complete this request, the dtor will clean the transaction up.
tfarina42834112016-09-22 13:38:2011246 return trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]2d731a32010-04-29 01:04:0611247}
11248
[email protected]448d4ca52012-03-04 04:12:2311249} // namespace
11250
Matt Menkef6edce752019-03-19 17:21:5611251TEST_F(HttpNetworkTransactionTest, GroupIdForDirectConnections) {
11252 const GroupIdTest tests[] = {
bncce36dca22015-04-21 22:11:2311253 {
Matt Menkef6edce752019-03-19 17:21:5611254 "", // unused
11255 "http://www.example.org/direct",
11256 ClientSocketPool::GroupId(HostPortPair("www.example.org", 80),
11257 ClientSocketPool::SocketType::kHttp,
11258 false /* privacy_mode */),
11259 false,
bncce36dca22015-04-21 22:11:2311260 },
11261 {
Matt Menkef6edce752019-03-19 17:21:5611262 "", // unused
11263 "http://[2001:1418:13:1::25]/direct",
11264 ClientSocketPool::GroupId(HostPortPair("2001:1418:13:1::25", 80),
11265 ClientSocketPool::SocketType::kHttp,
11266 false /* privacy_mode */),
11267 false,
bncce36dca22015-04-21 22:11:2311268 },
[email protected]04e5be32009-06-26 20:00:3111269
bncce36dca22015-04-21 22:11:2311270 // SSL Tests
11271 {
Matt Menkef6edce752019-03-19 17:21:5611272 "", // unused
11273 "https://www.example.org/direct_ssl",
11274 ClientSocketPool::GroupId(HostPortPair("www.example.org", 443),
11275 ClientSocketPool::SocketType::kSsl,
11276 false /* privacy_mode */),
11277 true,
bncce36dca22015-04-21 22:11:2311278 },
11279 {
Matt Menkef6edce752019-03-19 17:21:5611280 "", // unused
11281 "https://[2001:1418:13:1::25]/direct",
11282 ClientSocketPool::GroupId(HostPortPair("2001:1418:13:1::25", 443),
11283 ClientSocketPool::SocketType::kSsl,
11284 false /* privacy_mode */),
11285 true,
bncce36dca22015-04-21 22:11:2311286 },
11287 {
Matt Menkef6edce752019-03-19 17:21:5611288 "", // unused
11289 "https://host.with.alternate/direct",
11290 ClientSocketPool::GroupId(HostPortPair("host.with.alternate", 443),
11291 ClientSocketPool::SocketType::kSsl,
11292 false /* privacy_mode */),
11293 true,
bncce36dca22015-04-21 22:11:2311294 },
[email protected]2d731a32010-04-29 01:04:0611295 };
[email protected]2ff8b312010-04-26 22:20:5411296
Avi Drissman4365a4782018-12-28 19:26:2411297 for (size_t i = 0; i < base::size(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5911298 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4911299 ProxyResolutionService::CreateFixed(tests[i].proxy_server,
11300 TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:0911301 std::unique_ptr<HttpNetworkSession> session(
Matt Menkef6edce752019-03-19 17:21:5611302 SetupSessionForGroupIdTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:0611303
mmenkee65e7af2015-10-13 17:16:4211304 HttpNetworkSessionPeer peer(session.get());
Matt Menkef6edce752019-03-19 17:21:5611305 CaptureGroupIdTransportSocketPool* transport_conn_pool =
Matt Menked6fd2a52019-03-20 06:14:3611306 new CaptureGroupIdTransportSocketPool(&dummy_connect_job_params_);
Jeremy Roman0579ed62017-08-29 15:56:1911307 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
Matt Menked23ab952019-03-06 00:24:4011308 mock_pool_manager->SetSocketPool(ProxyServer::Direct(),
11309 base::WrapUnique(transport_conn_pool));
dchengc7eeda422015-12-26 03:56:4811310 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:0611311
11312 EXPECT_EQ(ERR_IO_PENDING,
Matt Menkef6edce752019-03-19 17:21:5611313 GroupIdTransactionHelper(tests[i].url, session.get()));
11314 EXPECT_EQ(tests[i].expected_group_id,
11315 transport_conn_pool->last_group_id_received());
Matt Menke9d5e2c92019-02-05 01:42:2311316 EXPECT_TRUE(transport_conn_pool->socket_requested());
[email protected]2d731a32010-04-29 01:04:0611317 }
[email protected]2d731a32010-04-29 01:04:0611318}
11319
Matt Menkef6edce752019-03-19 17:21:5611320TEST_F(HttpNetworkTransactionTest, GroupIdForHTTPProxyConnections) {
11321 const GroupIdTest tests[] = {
bncce36dca22015-04-21 22:11:2311322 {
Matt Menke4802de62019-03-08 22:47:5011323 "http_proxy",
11324 "http://www.example.org/http_proxy_normal",
Matt Menkef6edce752019-03-19 17:21:5611325 ClientSocketPool::GroupId(HostPortPair("www.example.org", 80),
11326 ClientSocketPool::SocketType::kHttp,
11327 false /* privacy_mode */),
Matt Menke4802de62019-03-08 22:47:5011328 false,
bncce36dca22015-04-21 22:11:2311329 },
[email protected]2d731a32010-04-29 01:04:0611330
bncce36dca22015-04-21 22:11:2311331 // SSL Tests
11332 {
Matt Menke4802de62019-03-08 22:47:5011333 "http_proxy",
11334 "https://www.example.org/http_connect_ssl",
Matt Menkef6edce752019-03-19 17:21:5611335 ClientSocketPool::GroupId(HostPortPair("www.example.org", 443),
11336 ClientSocketPool::SocketType::kSsl,
11337 false /* privacy_mode */),
Matt Menke4802de62019-03-08 22:47:5011338 true,
bncce36dca22015-04-21 22:11:2311339 },
[email protected]af3490e2010-10-16 21:02:2911340
bncce36dca22015-04-21 22:11:2311341 {
Matt Menke4802de62019-03-08 22:47:5011342 "http_proxy",
11343 "https://host.with.alternate/direct",
Matt Menkef6edce752019-03-19 17:21:5611344 ClientSocketPool::GroupId(HostPortPair("host.with.alternate", 443),
11345 ClientSocketPool::SocketType::kSsl,
11346 false /* privacy_mode */),
Matt Menke4802de62019-03-08 22:47:5011347 true,
bncce36dca22015-04-21 22:11:2311348 },
[email protected]45499252013-01-23 17:12:5611349
bncce36dca22015-04-21 22:11:2311350 {
Matt Menke4802de62019-03-08 22:47:5011351 "http_proxy",
11352 "ftp://ftp.google.com/http_proxy_normal",
Matt Menkef6edce752019-03-19 17:21:5611353 ClientSocketPool::GroupId(HostPortPair("ftp.google.com", 21),
11354 ClientSocketPool::SocketType::kFtp,
11355 false /* privacy_mode */),
Matt Menke4802de62019-03-08 22:47:5011356 false,
bncce36dca22015-04-21 22:11:2311357 },
[email protected]2d731a32010-04-29 01:04:0611358 };
11359
Avi Drissman4365a4782018-12-28 19:26:2411360 for (size_t i = 0; i < base::size(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5911361 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4911362 ProxyResolutionService::CreateFixed(tests[i].proxy_server,
11363 TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:0911364 std::unique_ptr<HttpNetworkSession> session(
Matt Menkef6edce752019-03-19 17:21:5611365 SetupSessionForGroupIdTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:0611366
mmenkee65e7af2015-10-13 17:16:4211367 HttpNetworkSessionPeer peer(session.get());
[email protected]2d731a32010-04-29 01:04:0611368
Matt Menkee8648fa2019-01-17 16:47:0711369 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
11370 HostPortPair("http_proxy", 80));
Matt Menkef6edce752019-03-19 17:21:5611371 CaptureGroupIdTransportSocketPool* http_proxy_pool =
Matt Menked6fd2a52019-03-20 06:14:3611372 new CaptureGroupIdTransportSocketPool(&dummy_connect_job_params_);
Jeremy Roman0579ed62017-08-29 15:56:1911373 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
Matt Menked23ab952019-03-06 00:24:4011374 mock_pool_manager->SetSocketPool(proxy_server,
11375 base::WrapUnique(http_proxy_pool));
dchengc7eeda422015-12-26 03:56:4811376 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:0611377
11378 EXPECT_EQ(ERR_IO_PENDING,
Matt Menkef6edce752019-03-19 17:21:5611379 GroupIdTransactionHelper(tests[i].url, session.get()));
11380 EXPECT_EQ(tests[i].expected_group_id,
11381 http_proxy_pool->last_group_id_received());
[email protected]2d731a32010-04-29 01:04:0611382 }
[email protected]2d731a32010-04-29 01:04:0611383}
11384
Matt Menkef6edce752019-03-19 17:21:5611385TEST_F(HttpNetworkTransactionTest, GroupIdForSOCKSConnections) {
11386 const GroupIdTest tests[] = {
bncce36dca22015-04-21 22:11:2311387 {
Matt Menke4802de62019-03-08 22:47:5011388 "socks4://socks_proxy:1080",
11389 "http://www.example.org/socks4_direct",
Matt Menkef6edce752019-03-19 17:21:5611390 ClientSocketPool::GroupId(HostPortPair("www.example.org", 80),
11391 ClientSocketPool::SocketType::kHttp,
11392 false /* privacy_mode */),
Matt Menke4802de62019-03-08 22:47:5011393 false,
bncce36dca22015-04-21 22:11:2311394 },
11395 {
Matt Menke4802de62019-03-08 22:47:5011396 "socks5://socks_proxy:1080",
11397 "http://www.example.org/socks5_direct",
Matt Menkef6edce752019-03-19 17:21:5611398 ClientSocketPool::GroupId(HostPortPair("www.example.org", 80),
11399 ClientSocketPool::SocketType::kHttp,
11400 false /* privacy_mode */),
Matt Menke4802de62019-03-08 22:47:5011401 false,
bncce36dca22015-04-21 22:11:2311402 },
[email protected]2d731a32010-04-29 01:04:0611403
bncce36dca22015-04-21 22:11:2311404 // SSL Tests
11405 {
Matt Menke4802de62019-03-08 22:47:5011406 "socks4://socks_proxy:1080",
11407 "https://www.example.org/socks4_ssl",
Matt Menkef6edce752019-03-19 17:21:5611408 ClientSocketPool::GroupId(HostPortPair("www.example.org", 443),
11409 ClientSocketPool::SocketType::kSsl,
11410 false /* privacy_mode */),
Matt Menke4802de62019-03-08 22:47:5011411 true,
bncce36dca22015-04-21 22:11:2311412 },
11413 {
Matt Menke4802de62019-03-08 22:47:5011414 "socks5://socks_proxy:1080",
11415 "https://www.example.org/socks5_ssl",
Matt Menkef6edce752019-03-19 17:21:5611416 ClientSocketPool::GroupId(HostPortPair("www.example.org", 443),
11417 ClientSocketPool::SocketType::kSsl,
11418 false /* privacy_mode */),
Matt Menke4802de62019-03-08 22:47:5011419 true,
bncce36dca22015-04-21 22:11:2311420 },
[email protected]af3490e2010-10-16 21:02:2911421
bncce36dca22015-04-21 22:11:2311422 {
Matt Menke4802de62019-03-08 22:47:5011423 "socks4://socks_proxy:1080",
11424 "https://host.with.alternate/direct",
Matt Menkef6edce752019-03-19 17:21:5611425 ClientSocketPool::GroupId(HostPortPair("host.with.alternate", 443),
11426 ClientSocketPool::SocketType::kSsl,
11427 false /* privacy_mode */),
Matt Menke4802de62019-03-08 22:47:5011428 true,
bncce36dca22015-04-21 22:11:2311429 },
[email protected]04e5be32009-06-26 20:00:3111430 };
11431
Avi Drissman4365a4782018-12-28 19:26:2411432 for (size_t i = 0; i < base::size(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5911433 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4911434 ProxyResolutionService::CreateFixed(tests[i].proxy_server,
11435 TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:0911436 std::unique_ptr<HttpNetworkSession> session(
Matt Menkef6edce752019-03-19 17:21:5611437 SetupSessionForGroupIdTests(&session_deps_));
[email protected]8b114dd72011-03-25 05:33:0211438
mmenkee65e7af2015-10-13 17:16:4211439 HttpNetworkSessionPeer peer(session.get());
[email protected]04e5be32009-06-26 20:00:3111440
Matt Menkee8648fa2019-01-17 16:47:0711441 ProxyServer proxy_server(
11442 ProxyServer::FromURI(tests[i].proxy_server, ProxyServer::SCHEME_HTTP));
11443 ASSERT_TRUE(proxy_server.is_valid());
Matt Menkef6edce752019-03-19 17:21:5611444 CaptureGroupIdTransportSocketPool* socks_conn_pool =
Matt Menked6fd2a52019-03-20 06:14:3611445 new CaptureGroupIdTransportSocketPool(&dummy_connect_job_params_);
Jeremy Roman0579ed62017-08-29 15:56:1911446 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
Matt Menked23ab952019-03-06 00:24:4011447 mock_pool_manager->SetSocketPool(proxy_server,
11448 base::WrapUnique(socks_conn_pool));
dchengc7eeda422015-12-26 03:56:4811449 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]04e5be32009-06-26 20:00:3111450
bnc691fda62016-08-12 00:43:1611451 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]04e5be32009-06-26 20:00:3111452
[email protected]2d731a32010-04-29 01:04:0611453 EXPECT_EQ(ERR_IO_PENDING,
Matt Menkef6edce752019-03-19 17:21:5611454 GroupIdTransactionHelper(tests[i].url, session.get()));
11455 EXPECT_EQ(tests[i].expected_group_id,
11456 socks_conn_pool->last_group_id_received());
[email protected]04e5be32009-06-26 20:00:3111457 }
11458}
11459
bncd16676a2016-07-20 16:23:0111460TEST_F(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:2711461 HttpRequestInfo request;
11462 request.method = "GET";
bncce36dca22015-04-21 22:11:2311463 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011464 request.traffic_annotation =
11465 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2711466
Ramin Halavatica8d5252018-03-12 05:33:4911467 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
11468 "myproxy:70;foobar:80", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]b59ff372009-07-15 22:04:3211469
[email protected]69719062010-01-05 20:09:2111470 // This simulates failure resolving all hostnames; that means we will fail
11471 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:0711472 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:3211473
danakj1fd259a02016-04-16 03:17:0911474 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611475 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]9172a982009-06-06 00:30:2511476
[email protected]49639fa2011-12-20 23:22:4111477 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:2511478
tfarina42834112016-09-22 13:38:2011479 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111480 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9172a982009-06-06 00:30:2511481
[email protected]9172a982009-06-06 00:30:2511482 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111483 EXPECT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]9172a982009-06-06 00:30:2511484}
11485
[email protected]0877e3d2009-10-17 22:29:5711486// Make sure we can handle an error when writing the request.
bncd16676a2016-07-20 16:23:0111487TEST_F(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:5711488 HttpRequestInfo request;
11489 request.method = "GET";
11490 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:1011491 request.traffic_annotation =
11492 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5711493
11494 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:0611495 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:5711496 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111497 StaticSocketDataProvider data(base::span<MockRead>(), write_failure);
[email protected]bb88e1d32013-05-03 23:11:0711498 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:0911499 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5711500
[email protected]49639fa2011-12-20 23:22:4111501 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5711502
bnc691fda62016-08-12 00:43:1611503 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5711504
tfarina42834112016-09-22 13:38:2011505 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111506 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5711507
11508 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111509 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:5911510
11511 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1611512 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5911513 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:5711514}
11515
zmo9528c9f42015-08-04 22:12:0811516// Check that a connection closed after the start of the headers finishes ok.
bncd16676a2016-07-20 16:23:0111517TEST_F(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:5711518 HttpRequestInfo request;
11519 request.method = "GET";
11520 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:1011521 request.traffic_annotation =
11522 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5711523
11524 MockRead data_reads[] = {
11525 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:0611526 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:5711527 };
11528
Ryan Sleevib8d7ea02018-05-07 20:01:0111529 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711530 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:0911531 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5711532
[email protected]49639fa2011-12-20 23:22:4111533 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5711534
bnc691fda62016-08-12 00:43:1611535 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5711536
tfarina42834112016-09-22 13:38:2011537 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111538 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5711539
11540 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111541 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:0811542
bnc691fda62016-08-12 00:43:1611543 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211544 ASSERT_TRUE(response);
zmo9528c9f42015-08-04 22:12:0811545
wezca1070932016-05-26 20:30:5211546 EXPECT_TRUE(response->headers);
zmo9528c9f42015-08-04 22:12:0811547 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
11548
11549 std::string response_data;
bnc691fda62016-08-12 00:43:1611550 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0111551 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:0811552 EXPECT_EQ("", response_data);
ttuttled9dbc652015-09-29 20:00:5911553
11554 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1611555 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5911556 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:5711557}
11558
11559// Make sure that a dropped connection while draining the body for auth
11560// restart does the right thing.
bncd16676a2016-07-20 16:23:0111561TEST_F(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:5711562 HttpRequestInfo request;
11563 request.method = "GET";
bncce36dca22015-04-21 22:11:2311564 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011565 request.traffic_annotation =
11566 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5711567
11568 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2311569 MockWrite(
11570 "GET / HTTP/1.1\r\n"
11571 "Host: www.example.org\r\n"
11572 "Connection: keep-alive\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:5711573 };
11574
11575 MockRead data_reads1[] = {
11576 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
11577 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
11578 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11579 MockRead("Content-Length: 14\r\n\r\n"),
11580 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:0611581 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:5711582 };
11583
Ryan Sleevib8d7ea02018-05-07 20:01:0111584 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:0711585 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:5711586
bnc691fda62016-08-12 00:43:1611587 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0877e3d2009-10-17 22:29:5711588 // be issuing -- the final header line contains the credentials.
11589 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:2311590 MockWrite(
11591 "GET / HTTP/1.1\r\n"
11592 "Host: www.example.org\r\n"
11593 "Connection: keep-alive\r\n"
11594 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:5711595 };
11596
11597 // Lastly, the server responds with the actual content.
11598 MockRead data_reads2[] = {
11599 MockRead("HTTP/1.1 200 OK\r\n"),
11600 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11601 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0611602 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:5711603 };
11604
Ryan Sleevib8d7ea02018-05-07 20:01:0111605 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:0711606 session_deps_.socket_factory->AddSocketDataProvider(&data2);
danakj1fd259a02016-04-16 03:17:0911607 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5711608
[email protected]49639fa2011-12-20 23:22:4111609 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:5711610
bnc691fda62016-08-12 00:43:1611611 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5011612
tfarina42834112016-09-22 13:38:2011613 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111614 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5711615
11616 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0111617 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:5711618
bnc691fda62016-08-12 00:43:1611619 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211620 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0411621 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:5711622
[email protected]49639fa2011-12-20 23:22:4111623 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:5711624
bnc691fda62016-08-12 00:43:1611625 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:0111626 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5711627
11628 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0111629 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:5711630
bnc691fda62016-08-12 00:43:1611631 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211632 ASSERT_TRUE(response);
11633 EXPECT_FALSE(response->auth_challenge);
[email protected]0877e3d2009-10-17 22:29:5711634 EXPECT_EQ(100, response->headers->GetContentLength());
11635}
11636
11637// Test HTTPS connections going through a proxy that sends extra data.
bncd16676a2016-07-20 16:23:0111638TEST_F(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
Ramin Halavatica8d5252018-03-12 05:33:4911639 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
11640 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5711641
11642 HttpRequestInfo request;
11643 request.method = "GET";
bncce36dca22015-04-21 22:11:2311644 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011645 request.traffic_annotation =
11646 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5711647
11648 MockRead proxy_reads[] = {
11649 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:0611650 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:5711651 };
11652
Ryan Sleevib8d7ea02018-05-07 20:01:0111653 StaticSocketDataProvider data(proxy_reads, base::span<MockWrite>());
[email protected]8ddf8322012-02-23 18:08:0611654 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:5711655
[email protected]bb88e1d32013-05-03 23:11:0711656 session_deps_.socket_factory->AddSocketDataProvider(&data);
11657 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:5711658
[email protected]49639fa2011-12-20 23:22:4111659 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5711660
[email protected]bb88e1d32013-05-03 23:11:0711661 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:5711662
danakj1fd259a02016-04-16 03:17:0911663 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611664 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5711665
tfarina42834112016-09-22 13:38:2011666 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111667 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5711668
11669 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111670 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]0877e3d2009-10-17 22:29:5711671}
11672
bncd16676a2016-07-20 16:23:0111673TEST_F(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:4611674 HttpRequestInfo request;
11675 request.method = "GET";
bncce36dca22015-04-21 22:11:2311676 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011677 request.traffic_annotation =
11678 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]9492e4a2010-02-24 00:58:4611679
danakj1fd259a02016-04-16 03:17:0911680 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611681 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2711682
[email protected]e22e1362009-11-23 21:31:1211683 MockRead data_reads[] = {
11684 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0611685 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:1211686 };
[email protected]9492e4a2010-02-24 00:58:4611687
Ryan Sleevib8d7ea02018-05-07 20:01:0111688 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711689 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:4611690
[email protected]49639fa2011-12-20 23:22:4111691 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:4611692
tfarina42834112016-09-22 13:38:2011693 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111694 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9492e4a2010-02-24 00:58:4611695
robpercival214763f2016-07-01 23:27:0111696 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]9492e4a2010-02-24 00:58:4611697
bnc691fda62016-08-12 00:43:1611698 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211699 ASSERT_TRUE(response);
[email protected]9492e4a2010-02-24 00:58:4611700
wezca1070932016-05-26 20:30:5211701 EXPECT_TRUE(response->headers);
[email protected]9492e4a2010-02-24 00:58:4611702 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
11703
11704 std::string response_data;
bnc691fda62016-08-12 00:43:1611705 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0111706 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]e22e1362009-11-23 21:31:1211707}
11708
bncd16676a2016-07-20 16:23:0111709TEST_F(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:1511710 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:5211711 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
avibf0746c2015-12-09 19:53:1411712 const uint64_t kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:2111713 UploadFileElementReader::ScopedOverridingContentLengthForTests
11714 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:3311715
danakj1fd259a02016-04-16 03:17:0911716 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:1911717 element_readers.push_back(std::make_unique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:1411718 base::ThreadTaskRunnerHandle::Get().get(), temp_file_path, 0,
ricea2deef682016-09-09 08:04:0711719 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:2211720 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:2711721
11722 HttpRequestInfo request;
11723 request.method = "POST";
bncce36dca22015-04-21 22:11:2311724 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:2711725 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1011726 request.traffic_annotation =
11727 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]329b68b2012-11-14 17:54:2711728
danakj1fd259a02016-04-16 03:17:0911729 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611730 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]95d88ffe2010-02-04 21:25:3311731
11732 MockRead data_reads[] = {
11733 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
11734 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611735 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:3311736 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111737 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711738 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:3311739
[email protected]49639fa2011-12-20 23:22:4111740 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:3311741
tfarina42834112016-09-22 13:38:2011742 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111743 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]95d88ffe2010-02-04 21:25:3311744
11745 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111746 EXPECT_THAT(rv, IsError(ERR_UPLOAD_FILE_CHANGED));
[email protected]95d88ffe2010-02-04 21:25:3311747
bnc691fda62016-08-12 00:43:1611748 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211749 ASSERT_TRUE(response);
[email protected]95d88ffe2010-02-04 21:25:3311750
maksim.sisove869bf52016-06-23 17:11:5211751 EXPECT_FALSE(response->headers);
[email protected]95d88ffe2010-02-04 21:25:3311752
[email protected]dd3aa792013-07-16 19:10:2311753 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:3311754}
11755
bncd16676a2016-07-20 16:23:0111756TEST_F(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:1511757 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:5211758 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:3611759 std::string temp_file_content("Unreadable file.");
lazyboy8df84fc2017-04-12 02:12:4811760 ASSERT_EQ(static_cast<int>(temp_file_content.length()),
11761 base::WriteFile(temp_file, temp_file_content.c_str(),
11762 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:1111763 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:3611764
danakj1fd259a02016-04-16 03:17:0911765 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:1911766 element_readers.push_back(std::make_unique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:1411767 base::ThreadTaskRunnerHandle::Get().get(), temp_file, 0,
ricea2deef682016-09-09 08:04:0711768 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:2211769 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:2711770
11771 HttpRequestInfo request;
11772 request.method = "POST";
bncce36dca22015-04-21 22:11:2311773 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:2711774 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1011775 request.traffic_annotation =
11776 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]329b68b2012-11-14 17:54:2711777
[email protected]999dd8c2013-11-12 06:45:5411778 // If we try to upload an unreadable file, the transaction should fail.
danakj1fd259a02016-04-16 03:17:0911779 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611780 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]6624b4622010-03-29 19:58:3611781
Ryan Sleevib8d7ea02018-05-07 20:01:0111782 StaticSocketDataProvider data;
[email protected]bb88e1d32013-05-03 23:11:0711783 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:3611784
[email protected]49639fa2011-12-20 23:22:4111785 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:3611786
tfarina42834112016-09-22 13:38:2011787 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111788 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6624b4622010-03-29 19:58:3611789
11790 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111791 EXPECT_THAT(rv, IsError(ERR_ACCESS_DENIED));
[email protected]6624b4622010-03-29 19:58:3611792
[email protected]dd3aa792013-07-16 19:10:2311793 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:3611794}
11795
bncd16676a2016-07-20 16:23:0111796TEST_F(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
[email protected]02cad5d2013-10-02 08:14:0311797 class FakeUploadElementReader : public UploadElementReader {
11798 public:
Chris Watkins7a41d3552017-12-01 02:13:2711799 FakeUploadElementReader() = default;
11800 ~FakeUploadElementReader() override = default;
[email protected]02cad5d2013-10-02 08:14:0311801
Matt Menkecc1d3a902018-02-05 18:27:3311802 CompletionOnceCallback TakeCallback() { return std::move(callback_); }
[email protected]02cad5d2013-10-02 08:14:0311803
11804 // UploadElementReader overrides:
Matt Menkecc1d3a902018-02-05 18:27:3311805 int Init(CompletionOnceCallback callback) override {
11806 callback_ = std::move(callback);
[email protected]02cad5d2013-10-02 08:14:0311807 return ERR_IO_PENDING;
11808 }
avibf0746c2015-12-09 19:53:1411809 uint64_t GetContentLength() const override { return 0; }
11810 uint64_t BytesRemaining() const override { return 0; }
dchengb03027d2014-10-21 12:00:2011811 int Read(IOBuffer* buf,
11812 int buf_length,
Matt Menkecc1d3a902018-02-05 18:27:3311813 CompletionOnceCallback callback) override {
[email protected]02cad5d2013-10-02 08:14:0311814 return ERR_FAILED;
11815 }
11816
11817 private:
Matt Menkecc1d3a902018-02-05 18:27:3311818 CompletionOnceCallback callback_;
[email protected]02cad5d2013-10-02 08:14:0311819 };
11820
11821 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
danakj1fd259a02016-04-16 03:17:0911822 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
11823 element_readers.push_back(base::WrapUnique(fake_reader));
olli.raula6df48b2a2015-11-26 07:40:2211824 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02cad5d2013-10-02 08:14:0311825
11826 HttpRequestInfo request;
11827 request.method = "POST";
bncce36dca22015-04-21 22:11:2311828 request.url = GURL("http://www.example.org/upload");
[email protected]02cad5d2013-10-02 08:14:0311829 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1011830 request.traffic_annotation =
11831 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02cad5d2013-10-02 08:14:0311832
danakj1fd259a02016-04-16 03:17:0911833 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5811834 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1911835 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]02cad5d2013-10-02 08:14:0311836
11837 StaticSocketDataProvider data;
11838 session_deps_.socket_factory->AddSocketDataProvider(&data);
11839
11840 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2011841 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111842 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
fdoray92e35a72016-06-10 15:54:5511843 base::RunLoop().RunUntilIdle();
[email protected]02cad5d2013-10-02 08:14:0311844
11845 // Transaction is pending on request body initialization.
Matt Menkecc1d3a902018-02-05 18:27:3311846 CompletionOnceCallback init_callback = fake_reader->TakeCallback();
11847 ASSERT_FALSE(init_callback.is_null());
[email protected]02cad5d2013-10-02 08:14:0311848
11849 // Return Init()'s result after the transaction gets destroyed.
11850 trans.reset();
Matt Menkecc1d3a902018-02-05 18:27:3311851 std::move(init_callback).Run(OK); // Should not crash.
[email protected]02cad5d2013-10-02 08:14:0311852}
11853
[email protected]aeefc9e82010-02-19 16:18:2711854// Tests that changes to Auth realms are treated like auth rejections.
bncd16676a2016-07-20 16:23:0111855TEST_F(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:2711856 HttpRequestInfo request;
11857 request.method = "GET";
bncce36dca22015-04-21 22:11:2311858 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011859 request.traffic_annotation =
11860 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]aeefc9e82010-02-19 16:18:2711861
11862 // First transaction will request a resource and receive a Basic challenge
11863 // with realm="first_realm".
11864 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2311865 MockWrite(
11866 "GET / HTTP/1.1\r\n"
11867 "Host: www.example.org\r\n"
11868 "Connection: keep-alive\r\n"
11869 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2711870 };
11871 MockRead data_reads1[] = {
11872 MockRead("HTTP/1.1 401 Unauthorized\r\n"
11873 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
11874 "\r\n"),
11875 };
11876
bnc691fda62016-08-12 00:43:1611877 // After calling trans.RestartWithAuth(), provide an Authentication header
[email protected]aeefc9e82010-02-19 16:18:2711878 // for first_realm. The server will reject and provide a challenge with
11879 // second_realm.
11880 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:2311881 MockWrite(
11882 "GET / HTTP/1.1\r\n"
11883 "Host: www.example.org\r\n"
11884 "Connection: keep-alive\r\n"
11885 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
11886 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2711887 };
11888 MockRead data_reads2[] = {
11889 MockRead("HTTP/1.1 401 Unauthorized\r\n"
11890 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
11891 "\r\n"),
11892 };
11893
11894 // This again fails, and goes back to first_realm. Make sure that the
11895 // entry is removed from cache.
11896 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:2311897 MockWrite(
11898 "GET / HTTP/1.1\r\n"
11899 "Host: www.example.org\r\n"
11900 "Connection: keep-alive\r\n"
11901 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
11902 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2711903 };
11904 MockRead data_reads3[] = {
11905 MockRead("HTTP/1.1 401 Unauthorized\r\n"
11906 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
11907 "\r\n"),
11908 };
11909
11910 // Try one last time (with the correct password) and get the resource.
11911 MockWrite data_writes4[] = {
bncce36dca22015-04-21 22:11:2311912 MockWrite(
11913 "GET / HTTP/1.1\r\n"
11914 "Host: www.example.org\r\n"
11915 "Connection: keep-alive\r\n"
11916 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
11917 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2711918 };
11919 MockRead data_reads4[] = {
11920 MockRead("HTTP/1.1 200 OK\r\n"
11921 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:5011922 "Content-Length: 5\r\n"
11923 "\r\n"
11924 "hello"),
[email protected]aeefc9e82010-02-19 16:18:2711925 };
11926
Ryan Sleevib8d7ea02018-05-07 20:01:0111927 StaticSocketDataProvider data1(data_reads1, data_writes1);
11928 StaticSocketDataProvider data2(data_reads2, data_writes2);
11929 StaticSocketDataProvider data3(data_reads3, data_writes3);
11930 StaticSocketDataProvider data4(data_reads4, data_writes4);
[email protected]bb88e1d32013-05-03 23:11:0711931 session_deps_.socket_factory->AddSocketDataProvider(&data1);
11932 session_deps_.socket_factory->AddSocketDataProvider(&data2);
11933 session_deps_.socket_factory->AddSocketDataProvider(&data3);
11934 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:2711935
[email protected]49639fa2011-12-20 23:22:4111936 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:2711937
danakj1fd259a02016-04-16 03:17:0911938 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611939 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5011940
[email protected]aeefc9e82010-02-19 16:18:2711941 // Issue the first request with Authorize headers. There should be a
11942 // password prompt for first_realm waiting to be filled in after the
11943 // transaction completes.
tfarina42834112016-09-22 13:38:2011944 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111945 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2711946 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0111947 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1611948 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211949 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0411950 const AuthChallengeInfo* challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5211951 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0411952 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4311953 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0411954 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1911955 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2711956
11957 // Issue the second request with an incorrect password. There should be a
11958 // password prompt for second_realm waiting to be filled in after the
11959 // transaction completes.
[email protected]49639fa2011-12-20 23:22:4111960 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:1611961 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBaz),
11962 callback2.callback());
robpercival214763f2016-07-01 23:27:0111963 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2711964 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0111965 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1611966 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211967 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0411968 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5211969 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0411970 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4311971 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0411972 EXPECT_EQ("second_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1911973 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2711974
11975 // Issue the third request with another incorrect password. There should be
11976 // a password prompt for first_realm waiting to be filled in. If the password
11977 // prompt is not present, it indicates that the HttpAuthCacheEntry for
11978 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:4111979 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:1611980 rv = trans.RestartWithAuth(AuthCredentials(kSecond, kFou),
11981 callback3.callback());
robpercival214763f2016-07-01 23:27:0111982 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2711983 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:0111984 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1611985 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211986 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0411987 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5211988 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0411989 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4311990 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0411991 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1911992 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2711993
11994 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:4111995 TestCompletionCallback callback4;
bnc691fda62016-08-12 00:43:1611996 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBar),
11997 callback4.callback());
robpercival214763f2016-07-01 23:27:0111998 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2711999 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:0112000 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612001 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212002 ASSERT_TRUE(response);
12003 EXPECT_FALSE(response->auth_challenge);
[email protected]aeefc9e82010-02-19 16:18:2712004}
12005
Bence Béky230ac612017-08-30 19:17:0812006// Regression test for https://crbug.com/754395.
12007TEST_F(HttpNetworkTransactionTest, IgnoreAltSvcWithInvalidCert) {
12008 MockRead data_reads[] = {
12009 MockRead("HTTP/1.1 200 OK\r\n"),
12010 MockRead(kAlternativeServiceHttpHeader),
12011 MockRead("\r\n"),
12012 MockRead("hello world"),
12013 MockRead(SYNCHRONOUS, OK),
12014 };
12015
12016 HttpRequestInfo request;
12017 request.method = "GET";
12018 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1012019 request.traffic_annotation =
12020 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Béky230ac612017-08-30 19:17:0812021
Ryan Sleevib8d7ea02018-05-07 20:01:0112022 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
Bence Béky230ac612017-08-30 19:17:0812023 session_deps_.socket_factory->AddSocketDataProvider(&data);
12024
12025 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4912026 ssl.ssl_info.cert =
12027 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
12028 ASSERT_TRUE(ssl.ssl_info.cert);
12029 ssl.ssl_info.cert_status = CERT_STATUS_COMMON_NAME_INVALID;
Bence Béky230ac612017-08-30 19:17:0812030 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12031
12032 TestCompletionCallback callback;
12033
12034 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12035 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
12036
12037 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
12038 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12039
12040 url::SchemeHostPort test_server(request.url);
12041 HttpServerProperties* http_server_properties =
12042 session->http_server_properties();
12043 EXPECT_TRUE(
12044 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
12045
12046 EXPECT_THAT(callback.WaitForResult(), IsOk());
12047
12048 const HttpResponseInfo* response = trans.GetResponseInfo();
12049 ASSERT_TRUE(response);
12050 ASSERT_TRUE(response->headers);
12051 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12052 EXPECT_FALSE(response->was_fetched_via_spdy);
12053 EXPECT_FALSE(response->was_alpn_negotiated);
12054
12055 std::string response_data;
12056 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
12057 EXPECT_EQ("hello world", response_data);
12058
12059 EXPECT_TRUE(
12060 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
12061}
12062
bncd16676a2016-07-20 16:23:0112063TEST_F(HttpNetworkTransactionTest, HonorAlternativeServiceHeader) {
bncc958faa2015-07-31 18:14:5212064 MockRead data_reads[] = {
12065 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312066 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212067 MockRead("\r\n"),
12068 MockRead("hello world"),
12069 MockRead(SYNCHRONOUS, OK),
12070 };
12071
12072 HttpRequestInfo request;
12073 request.method = "GET";
bncb26024382016-06-29 02:39:4512074 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1012075 request.traffic_annotation =
12076 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bncc958faa2015-07-31 18:14:5212077
Ryan Sleevib8d7ea02018-05-07 20:01:0112078 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:5212079 session_deps_.socket_factory->AddSocketDataProvider(&data);
12080
bncb26024382016-06-29 02:39:4512081 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4912082 ssl.ssl_info.cert =
12083 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
12084 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4512085 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12086
bncc958faa2015-07-31 18:14:5212087 TestCompletionCallback callback;
12088
danakj1fd259a02016-04-16 03:17:0912089 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1612090 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5212091
tfarina42834112016-09-22 13:38:2012092 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112093 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5212094
bncb26024382016-06-29 02:39:4512095 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4012096 HttpServerProperties* http_server_properties =
12097 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3412098 EXPECT_TRUE(
12099 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5212100
robpercival214763f2016-07-01 23:27:0112101 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5212102
bnc691fda62016-08-12 00:43:1612103 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212104 ASSERT_TRUE(response);
12105 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5212106 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12107 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212108 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5212109
12110 std::string response_data;
bnc691fda62016-08-12 00:43:1612111 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5212112 EXPECT_EQ("hello world", response_data);
12113
zhongyic4de03032017-05-19 04:07:3412114 AlternativeServiceInfoVector alternative_service_info_vector =
12115 http_server_properties->GetAlternativeServiceInfos(test_server);
12116 ASSERT_EQ(1u, alternative_service_info_vector.size());
12117 AlternativeService alternative_service(kProtoHTTP2, "mail.example.org", 443);
12118 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5412119 alternative_service_info_vector[0].alternative_service());
bncc958faa2015-07-31 18:14:5212120}
12121
bnce3dd56f2016-06-01 10:37:1112122// Regression test for https://crbug.com/615497.
bncd16676a2016-07-20 16:23:0112123TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1112124 DoNotParseAlternativeServiceHeaderOnInsecureRequest) {
bnce3dd56f2016-06-01 10:37:1112125 MockRead data_reads[] = {
12126 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312127 MockRead(kAlternativeServiceHttpHeader),
bnce3dd56f2016-06-01 10:37:1112128 MockRead("\r\n"),
12129 MockRead("hello world"),
12130 MockRead(SYNCHRONOUS, OK),
12131 };
12132
12133 HttpRequestInfo request;
12134 request.method = "GET";
12135 request.url = GURL("http://www.example.org/");
12136 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1012137 request.traffic_annotation =
12138 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnce3dd56f2016-06-01 10:37:1112139
Ryan Sleevib8d7ea02018-05-07 20:01:0112140 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
bnce3dd56f2016-06-01 10:37:1112141 session_deps_.socket_factory->AddSocketDataProvider(&data);
12142
12143 TestCompletionCallback callback;
12144
12145 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1612146 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1112147
12148 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4012149 HttpServerProperties* http_server_properties =
12150 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3412151 EXPECT_TRUE(
12152 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1112153
tfarina42834112016-09-22 13:38:2012154 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112155 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12156 EXPECT_THAT(callback.WaitForResult(), IsOk());
bnce3dd56f2016-06-01 10:37:1112157
bnc691fda62016-08-12 00:43:1612158 const HttpResponseInfo* response = trans.GetResponseInfo();
bnce3dd56f2016-06-01 10:37:1112159 ASSERT_TRUE(response);
12160 ASSERT_TRUE(response->headers);
12161 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12162 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212163 EXPECT_FALSE(response->was_alpn_negotiated);
bnce3dd56f2016-06-01 10:37:1112164
12165 std::string response_data;
bnc691fda62016-08-12 00:43:1612166 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnce3dd56f2016-06-01 10:37:1112167 EXPECT_EQ("hello world", response_data);
12168
zhongyic4de03032017-05-19 04:07:3412169 EXPECT_TRUE(
12170 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1112171}
12172
bnca86731e2017-04-17 12:31:2812173// HTTP/2 Alternative Services should be disabled by default.
bnc8bef8da22016-05-30 01:28:2512174// TODO(bnc): Remove when https://crbug.com/615413 is fixed.
bncd16676a2016-07-20 16:23:0112175TEST_F(HttpNetworkTransactionTest,
bnc8bef8da22016-05-30 01:28:2512176 DisableHTTP2AlternativeServicesWithDifferentHost) {
bnca86731e2017-04-17 12:31:2812177 session_deps_.enable_http2_alternative_service = false;
bncb26024382016-06-29 02:39:4512178
bnc8bef8da22016-05-30 01:28:2512179 HttpRequestInfo request;
12180 request.method = "GET";
bncb26024382016-06-29 02:39:4512181 request.url = GURL("https://www.example.org/");
bnc8bef8da22016-05-30 01:28:2512182 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1012183 request.traffic_annotation =
12184 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8bef8da22016-05-30 01:28:2512185
12186 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
12187 StaticSocketDataProvider first_data;
12188 first_data.set_connect_data(mock_connect);
12189 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4512190 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612191 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512192 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
bnc8bef8da22016-05-30 01:28:2512193
12194 MockRead data_reads[] = {
12195 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
12196 MockRead(ASYNC, OK),
12197 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112198 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
bnc8bef8da22016-05-30 01:28:2512199 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
12200
12201 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12202
bnc525e175a2016-06-20 12:36:4012203 HttpServerProperties* http_server_properties =
bnc8bef8da22016-05-30 01:28:2512204 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2112205 AlternativeService alternative_service(kProtoHTTP2, "different.example.org",
12206 444);
bnc8bef8da22016-05-30 01:28:2512207 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112208 http_server_properties->SetHttp2AlternativeService(
bnc8bef8da22016-05-30 01:28:2512209 url::SchemeHostPort(request.url), alternative_service, expiration);
12210
bnc691fda62016-08-12 00:43:1612211 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc8bef8da22016-05-30 01:28:2512212 TestCompletionCallback callback;
12213
tfarina42834112016-09-22 13:38:2012214 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc8bef8da22016-05-30 01:28:2512215 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0112216 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc8bef8da22016-05-30 01:28:2512217}
12218
bnce3dd56f2016-06-01 10:37:1112219// Regression test for https://crbug.com/615497:
12220// Alternative Services should be disabled for http origin.
bncd16676a2016-07-20 16:23:0112221TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1112222 DisableAlternativeServicesForInsecureOrigin) {
bnce3dd56f2016-06-01 10:37:1112223 HttpRequestInfo request;
12224 request.method = "GET";
12225 request.url = GURL("http://www.example.org/");
12226 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1012227 request.traffic_annotation =
12228 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnce3dd56f2016-06-01 10:37:1112229
12230 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
12231 StaticSocketDataProvider first_data;
12232 first_data.set_connect_data(mock_connect);
12233 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
12234
12235 MockRead data_reads[] = {
12236 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
12237 MockRead(ASYNC, OK),
12238 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112239 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
bnce3dd56f2016-06-01 10:37:1112240 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
12241
12242 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12243
bnc525e175a2016-06-20 12:36:4012244 HttpServerProperties* http_server_properties =
bnce3dd56f2016-06-01 10:37:1112245 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2112246 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnce3dd56f2016-06-01 10:37:1112247 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112248 http_server_properties->SetHttp2AlternativeService(
bnce3dd56f2016-06-01 10:37:1112249 url::SchemeHostPort(request.url), alternative_service, expiration);
12250
bnc691fda62016-08-12 00:43:1612251 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1112252 TestCompletionCallback callback;
12253
tfarina42834112016-09-22 13:38:2012254 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnce3dd56f2016-06-01 10:37:1112255 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0112256 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnce3dd56f2016-06-01 10:37:1112257}
12258
bncd16676a2016-07-20 16:23:0112259TEST_F(HttpNetworkTransactionTest, ClearAlternativeServices) {
bnc4f575852015-10-14 18:35:0812260 // Set an alternative service for origin.
danakj1fd259a02016-04-16 03:17:0912261 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4012262 HttpServerProperties* http_server_properties =
12263 session->http_server_properties();
bncb26024382016-06-29 02:39:4512264 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc3472afd2016-11-17 15:27:2112265 AlternativeService alternative_service(kProtoQUIC, "", 80);
bnc4f575852015-10-14 18:35:0812266 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112267 http_server_properties->SetQuicAlternativeService(
12268 test_server, alternative_service, expiration,
12269 session->params().quic_supported_versions);
zhongyic4de03032017-05-19 04:07:3412270 EXPECT_EQ(
12271 1u,
12272 http_server_properties->GetAlternativeServiceInfos(test_server).size());
bnc4f575852015-10-14 18:35:0812273
12274 // Send a clear header.
12275 MockRead data_reads[] = {
12276 MockRead("HTTP/1.1 200 OK\r\n"),
12277 MockRead("Alt-Svc: clear\r\n"),
12278 MockRead("\r\n"),
12279 MockRead("hello world"),
12280 MockRead(SYNCHRONOUS, OK),
12281 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112282 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
bnc4f575852015-10-14 18:35:0812283 session_deps_.socket_factory->AddSocketDataProvider(&data);
12284
bncb26024382016-06-29 02:39:4512285 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4912286 ssl.ssl_info.cert =
12287 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
12288 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4512289 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12290
bnc4f575852015-10-14 18:35:0812291 HttpRequestInfo request;
12292 request.method = "GET";
bncb26024382016-06-29 02:39:4512293 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1012294 request.traffic_annotation =
12295 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc4f575852015-10-14 18:35:0812296
12297 TestCompletionCallback callback;
12298
bnc691fda62016-08-12 00:43:1612299 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc4f575852015-10-14 18:35:0812300
tfarina42834112016-09-22 13:38:2012301 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112302 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc4f575852015-10-14 18:35:0812303
bnc691fda62016-08-12 00:43:1612304 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212305 ASSERT_TRUE(response);
12306 ASSERT_TRUE(response->headers);
bnc4f575852015-10-14 18:35:0812307 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12308 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212309 EXPECT_FALSE(response->was_alpn_negotiated);
bnc4f575852015-10-14 18:35:0812310
12311 std::string response_data;
bnc691fda62016-08-12 00:43:1612312 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc4f575852015-10-14 18:35:0812313 EXPECT_EQ("hello world", response_data);
12314
zhongyic4de03032017-05-19 04:07:3412315 EXPECT_TRUE(
12316 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnc4f575852015-10-14 18:35:0812317}
12318
bncd16676a2016-07-20 16:23:0112319TEST_F(HttpNetworkTransactionTest, HonorMultipleAlternativeServiceHeaders) {
bncc958faa2015-07-31 18:14:5212320 MockRead data_reads[] = {
12321 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312322 MockRead("Alt-Svc: h2=\"www.example.com:443\","),
12323 MockRead("h2=\":1234\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:5212324 MockRead("hello world"),
12325 MockRead(SYNCHRONOUS, OK),
12326 };
12327
12328 HttpRequestInfo request;
12329 request.method = "GET";
bncb26024382016-06-29 02:39:4512330 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1012331 request.traffic_annotation =
12332 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bncc958faa2015-07-31 18:14:5212333
Ryan Sleevib8d7ea02018-05-07 20:01:0112334 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:5212335 session_deps_.socket_factory->AddSocketDataProvider(&data);
12336
bncb26024382016-06-29 02:39:4512337 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4912338 ssl.ssl_info.cert =
12339 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
12340 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4512341 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12342
bncc958faa2015-07-31 18:14:5212343 TestCompletionCallback callback;
12344
danakj1fd259a02016-04-16 03:17:0912345 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1612346 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5212347
tfarina42834112016-09-22 13:38:2012348 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112349 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5212350
bncb26024382016-06-29 02:39:4512351 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc525e175a2016-06-20 12:36:4012352 HttpServerProperties* http_server_properties =
12353 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3412354 EXPECT_TRUE(
12355 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5212356
robpercival214763f2016-07-01 23:27:0112357 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5212358
bnc691fda62016-08-12 00:43:1612359 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212360 ASSERT_TRUE(response);
12361 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5212362 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12363 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212364 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5212365
12366 std::string response_data;
bnc691fda62016-08-12 00:43:1612367 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5212368 EXPECT_EQ("hello world", response_data);
12369
zhongyic4de03032017-05-19 04:07:3412370 AlternativeServiceInfoVector alternative_service_info_vector =
12371 http_server_properties->GetAlternativeServiceInfos(test_server);
12372 ASSERT_EQ(2u, alternative_service_info_vector.size());
12373
12374 AlternativeService alternative_service(kProtoHTTP2, "www.example.com", 443);
12375 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5412376 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3412377 AlternativeService alternative_service_2(kProtoHTTP2, "www.example.org",
12378 1234);
12379 EXPECT_EQ(alternative_service_2,
zhongyi422ce352017-06-09 23:28:5412380 alternative_service_info_vector[1].alternative_service());
bncc958faa2015-07-31 18:14:5212381}
12382
bncd16676a2016-07-20 16:23:0112383TEST_F(HttpNetworkTransactionTest, IdentifyQuicBroken) {
zhongyi3d4a55e72016-04-22 20:36:4612384 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0212385 HostPortPair alternative("alternative.example.org", 443);
12386 std::string origin_url = "https://origin.example.org:443";
12387 std::string alternative_url = "https://alternative.example.org:443";
12388
12389 // Negotiate HTTP/1.1 with alternative.example.org.
12390 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612391 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0212392 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12393
12394 // HTTP/1.1 data for request.
12395 MockWrite http_writes[] = {
12396 MockWrite("GET / HTTP/1.1\r\n"
12397 "Host: alternative.example.org\r\n"
12398 "Connection: keep-alive\r\n\r\n"),
12399 };
12400
12401 MockRead http_reads[] = {
12402 MockRead("HTTP/1.1 200 OK\r\n"
12403 "Content-Type: text/html; charset=iso-8859-1\r\n"
12404 "Content-Length: 40\r\n\r\n"
12405 "first HTTP/1.1 response from alternative"),
12406 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112407 StaticSocketDataProvider http_data(http_reads, http_writes);
zhongyi48704c182015-12-07 07:52:0212408 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12409
12410 StaticSocketDataProvider data_refused;
12411 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
12412 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
12413
zhongyi3d4a55e72016-04-22 20:36:4612414 // Set up a QUIC alternative service for server.
danakj1fd259a02016-04-16 03:17:0912415 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4012416 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0212417 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2112418 AlternativeService alternative_service(kProtoQUIC, alternative);
zhongyi48704c182015-12-07 07:52:0212419 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112420 http_server_properties->SetQuicAlternativeService(
12421 server, alternative_service, expiration,
12422 HttpNetworkSession::Params().quic_supported_versions);
zhongyi48704c182015-12-07 07:52:0212423 // Mark the QUIC alternative service as broken.
12424 http_server_properties->MarkAlternativeServiceBroken(alternative_service);
12425
zhongyi48704c182015-12-07 07:52:0212426 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4612427 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0212428 request.method = "GET";
12429 request.url = GURL(origin_url);
Ramin Halavatib5e433e2018-02-07 07:41:1012430 request.traffic_annotation =
12431 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
12432
zhongyi48704c182015-12-07 07:52:0212433 TestCompletionCallback callback;
12434 NetErrorDetails details;
12435 EXPECT_FALSE(details.quic_broken);
12436
tfarina42834112016-09-22 13:38:2012437 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1612438 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0212439 EXPECT_TRUE(details.quic_broken);
12440}
12441
bncd16676a2016-07-20 16:23:0112442TEST_F(HttpNetworkTransactionTest, IdentifyQuicNotBroken) {
zhongyi3d4a55e72016-04-22 20:36:4612443 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0212444 HostPortPair alternative1("alternative1.example.org", 443);
12445 HostPortPair alternative2("alternative2.example.org", 443);
12446 std::string origin_url = "https://origin.example.org:443";
12447 std::string alternative_url1 = "https://alternative1.example.org:443";
12448 std::string alternative_url2 = "https://alternative2.example.org:443";
12449
12450 // Negotiate HTTP/1.1 with alternative1.example.org.
12451 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612452 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0212453 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12454
12455 // HTTP/1.1 data for request.
12456 MockWrite http_writes[] = {
12457 MockWrite("GET / HTTP/1.1\r\n"
12458 "Host: alternative1.example.org\r\n"
12459 "Connection: keep-alive\r\n\r\n"),
12460 };
12461
12462 MockRead http_reads[] = {
12463 MockRead("HTTP/1.1 200 OK\r\n"
12464 "Content-Type: text/html; charset=iso-8859-1\r\n"
12465 "Content-Length: 40\r\n\r\n"
12466 "first HTTP/1.1 response from alternative1"),
12467 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112468 StaticSocketDataProvider http_data(http_reads, http_writes);
zhongyi48704c182015-12-07 07:52:0212469 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12470
12471 StaticSocketDataProvider data_refused;
12472 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
12473 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
12474
danakj1fd259a02016-04-16 03:17:0912475 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4012476 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0212477 session->http_server_properties();
12478
zhongyi3d4a55e72016-04-22 20:36:4612479 // Set up two QUIC alternative services for server.
zhongyi48704c182015-12-07 07:52:0212480 AlternativeServiceInfoVector alternative_service_info_vector;
12481 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
12482
bnc3472afd2016-11-17 15:27:2112483 AlternativeService alternative_service1(kProtoQUIC, alternative1);
zhongyie537a002017-06-27 16:48:2112484 alternative_service_info_vector.push_back(
12485 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
12486 alternative_service1, expiration,
12487 session->params().quic_supported_versions));
bnc3472afd2016-11-17 15:27:2112488 AlternativeService alternative_service2(kProtoQUIC, alternative2);
zhongyie537a002017-06-27 16:48:2112489 alternative_service_info_vector.push_back(
12490 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
12491 alternative_service2, expiration,
12492 session->params().quic_supported_versions));
zhongyi48704c182015-12-07 07:52:0212493
12494 http_server_properties->SetAlternativeServices(
zhongyi3d4a55e72016-04-22 20:36:4612495 server, alternative_service_info_vector);
zhongyi48704c182015-12-07 07:52:0212496
12497 // Mark one of the QUIC alternative service as broken.
12498 http_server_properties->MarkAlternativeServiceBroken(alternative_service1);
zhongyic4de03032017-05-19 04:07:3412499 EXPECT_EQ(2u,
12500 http_server_properties->GetAlternativeServiceInfos(server).size());
zhongyi48704c182015-12-07 07:52:0212501
zhongyi48704c182015-12-07 07:52:0212502 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4612503 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0212504 request.method = "GET";
12505 request.url = GURL(origin_url);
Ramin Halavatib5e433e2018-02-07 07:41:1012506 request.traffic_annotation =
12507 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
12508
zhongyi48704c182015-12-07 07:52:0212509 TestCompletionCallback callback;
12510 NetErrorDetails details;
12511 EXPECT_FALSE(details.quic_broken);
12512
tfarina42834112016-09-22 13:38:2012513 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1612514 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0212515 EXPECT_FALSE(details.quic_broken);
12516}
12517
bncd16676a2016-07-20 16:23:0112518TEST_F(HttpNetworkTransactionTest, MarkBrokenAlternateProtocolAndFallback) {
[email protected]564b4912010-03-09 16:30:4212519 HttpRequestInfo request;
12520 request.method = "GET";
bncb26024382016-06-29 02:39:4512521 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1012522 request.traffic_annotation =
12523 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]564b4912010-03-09 16:30:4212524
[email protected]d973e99a2012-02-17 21:02:3612525 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:4212526 StaticSocketDataProvider first_data;
12527 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712528 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4512529 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612530 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512531 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]564b4912010-03-09 16:30:4212532
12533 MockRead data_reads[] = {
12534 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12535 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0612536 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:4212537 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112538 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712539 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:4212540
danakj1fd259a02016-04-16 03:17:0912541 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:4212542
bnc525e175a2016-06-20 12:36:4012543 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5312544 session->http_server_properties();
zhongyi3d4a55e72016-04-22 20:36:4612545 const url::SchemeHostPort server(request.url);
[email protected]3912662a32011-10-04 00:51:1112546 // Port must be < 1024, or the header will be ignored (since initial port was
12547 // port 80 (another restricted port).
zhongyie537a002017-06-27 16:48:2112548 // Port is ignored by MockConnect anyway.
12549 const AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12550 666);
bnc7dc7e1b42015-07-28 14:43:1212551 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112552 http_server_properties->SetHttp2AlternativeService(
12553 server, alternative_service, expiration);
[email protected]564b4912010-03-09 16:30:4212554
bnc691fda62016-08-12 00:43:1612555 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112556 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:4212557
tfarina42834112016-09-22 13:38:2012558 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112559 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12560 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]564b4912010-03-09 16:30:4212561
bnc691fda62016-08-12 00:43:1612562 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212563 ASSERT_TRUE(response);
12564 ASSERT_TRUE(response->headers);
[email protected]564b4912010-03-09 16:30:4212565 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12566
12567 std::string response_data;
bnc691fda62016-08-12 00:43:1612568 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]564b4912010-03-09 16:30:4212569 EXPECT_EQ("hello world", response_data);
12570
zhongyic4de03032017-05-19 04:07:3412571 const AlternativeServiceInfoVector alternative_service_info_vector =
12572 http_server_properties->GetAlternativeServiceInfos(server);
12573 ASSERT_EQ(1u, alternative_service_info_vector.size());
12574 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5412575 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3412576 EXPECT_TRUE(
12577 http_server_properties->IsAlternativeServiceBroken(alternative_service));
[email protected]564b4912010-03-09 16:30:4212578}
12579
bnc55ff9da2015-08-19 18:42:3512580// Ensure that we are not allowed to redirect traffic via an alternate protocol
12581// to an unrestricted (port >= 1024) when the original traffic was on a
12582// restricted port (port < 1024). Ensure that we can redirect in all other
12583// cases.
bncd16676a2016-07-20 16:23:0112584TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:1112585 HttpRequestInfo restricted_port_request;
12586 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4512587 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1112588 restricted_port_request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1012589 restricted_port_request.traffic_annotation =
12590 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1112591
[email protected]d973e99a2012-02-17 21:02:3612592 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1112593 StaticSocketDataProvider first_data;
12594 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712595 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1112596
12597 MockRead data_reads[] = {
12598 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12599 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0612600 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1112601 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112602 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712603 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4512604 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612605 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512606 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1112607
danakj1fd259a02016-04-16 03:17:0912608 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1112609
bnc525e175a2016-06-20 12:36:4012610 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5312611 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1112612 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2112613 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12614 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1212615 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112616 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4612617 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5012618 expiration);
[email protected]3912662a32011-10-04 00:51:1112619
bnc691fda62016-08-12 00:43:1612620 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112621 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1112622
tfarina42834112016-09-22 13:38:2012623 int rv = trans.Start(&restricted_port_request, callback.callback(),
12624 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112625 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1112626 // Invalid change to unrestricted port should fail.
robpercival214763f2016-07-01 23:27:0112627 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_REFUSED));
[email protected]c54c6962013-02-01 04:53:1912628}
[email protected]3912662a32011-10-04 00:51:1112629
bnc55ff9da2015-08-19 18:42:3512630// Ensure that we are allowed to redirect traffic via an alternate protocol to
12631// an unrestricted (port >= 1024) when the original traffic was on a restricted
12632// port (port < 1024) if we set |enable_user_alternate_protocol_ports|.
bncd16676a2016-07-20 16:23:0112633TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedPermitted) {
[email protected]bb88e1d32013-05-03 23:11:0712634 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:1912635
12636 HttpRequestInfo restricted_port_request;
12637 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4512638 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]c54c6962013-02-01 04:53:1912639 restricted_port_request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1012640 restricted_port_request.traffic_annotation =
12641 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]c54c6962013-02-01 04:53:1912642
12643 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
12644 StaticSocketDataProvider first_data;
12645 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712646 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:1912647
12648 MockRead data_reads[] = {
12649 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12650 MockRead("hello world"),
12651 MockRead(ASYNC, OK),
12652 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112653 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712654 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4512655 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612656 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512657 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]c54c6962013-02-01 04:53:1912658
danakj1fd259a02016-04-16 03:17:0912659 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:1912660
bnc525e175a2016-06-20 12:36:4012661 HttpServerProperties* http_server_properties =
[email protected]c54c6962013-02-01 04:53:1912662 session->http_server_properties();
12663 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2112664 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12665 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1212666 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112667 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4612668 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5012669 expiration);
[email protected]c54c6962013-02-01 04:53:1912670
bnc691fda62016-08-12 00:43:1612671 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]c54c6962013-02-01 04:53:1912672 TestCompletionCallback callback;
12673
tfarina42834112016-09-22 13:38:2012674 EXPECT_EQ(ERR_IO_PENDING,
12675 trans.Start(&restricted_port_request, callback.callback(),
12676 NetLogWithSource()));
[email protected]c54c6962013-02-01 04:53:1912677 // Change to unrestricted port should succeed.
robpercival214763f2016-07-01 23:27:0112678 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1112679}
12680
bnc55ff9da2015-08-19 18:42:3512681// Ensure that we are not allowed to redirect traffic via an alternate protocol
12682// to an unrestricted (port >= 1024) when the original traffic was on a
12683// restricted port (port < 1024). Ensure that we can redirect in all other
12684// cases.
bncd16676a2016-07-20 16:23:0112685TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:1112686 HttpRequestInfo restricted_port_request;
12687 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4512688 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1112689 restricted_port_request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1012690 restricted_port_request.traffic_annotation =
12691 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1112692
[email protected]d973e99a2012-02-17 21:02:3612693 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1112694 StaticSocketDataProvider first_data;
12695 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712696 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1112697
12698 MockRead data_reads[] = {
12699 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12700 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0612701 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1112702 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112703 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712704 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1112705
bncb26024382016-06-29 02:39:4512706 SSLSocketDataProvider ssl(ASYNC, OK);
12707 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12708
danakj1fd259a02016-04-16 03:17:0912709 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1112710
bnc525e175a2016-06-20 12:36:4012711 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5312712 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1112713 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2112714 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12715 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1212716 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112717 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4612718 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5012719 expiration);
[email protected]3912662a32011-10-04 00:51:1112720
bnc691fda62016-08-12 00:43:1612721 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112722 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1112723
tfarina42834112016-09-22 13:38:2012724 int rv = trans.Start(&restricted_port_request, callback.callback(),
12725 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112726 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1112727 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0112728 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1112729}
12730
bnc55ff9da2015-08-19 18:42:3512731// Ensure that we are not allowed to redirect traffic via an alternate protocol
12732// to an unrestricted (port >= 1024) when the original traffic was on a
12733// restricted port (port < 1024). Ensure that we can redirect in all other
12734// cases.
bncd16676a2016-07-20 16:23:0112735TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:1112736 HttpRequestInfo unrestricted_port_request;
12737 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4512738 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1112739 unrestricted_port_request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1012740 unrestricted_port_request.traffic_annotation =
12741 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1112742
[email protected]d973e99a2012-02-17 21:02:3612743 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1112744 StaticSocketDataProvider first_data;
12745 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712746 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1112747
12748 MockRead data_reads[] = {
12749 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12750 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0612751 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1112752 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112753 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712754 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4512755 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612756 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512757 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1112758
danakj1fd259a02016-04-16 03:17:0912759 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1112760
bnc525e175a2016-06-20 12:36:4012761 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5312762 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1112763 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2112764 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12765 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1212766 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112767 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4612768 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5012769 expiration);
[email protected]3912662a32011-10-04 00:51:1112770
bnc691fda62016-08-12 00:43:1612771 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112772 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1112773
bnc691fda62016-08-12 00:43:1612774 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2012775 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112776 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1112777 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0112778 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1112779}
12780
bnc55ff9da2015-08-19 18:42:3512781// Ensure that we are not allowed to redirect traffic via an alternate protocol
12782// to an unrestricted (port >= 1024) when the original traffic was on a
12783// restricted port (port < 1024). Ensure that we can redirect in all other
12784// cases.
bncd16676a2016-07-20 16:23:0112785TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:1112786 HttpRequestInfo unrestricted_port_request;
12787 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4512788 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1112789 unrestricted_port_request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1012790 unrestricted_port_request.traffic_annotation =
12791 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1112792
[email protected]d973e99a2012-02-17 21:02:3612793 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1112794 StaticSocketDataProvider first_data;
12795 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712796 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1112797
12798 MockRead data_reads[] = {
12799 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12800 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0612801 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1112802 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112803 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712804 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1112805
bncb26024382016-06-29 02:39:4512806 SSLSocketDataProvider ssl(ASYNC, OK);
12807 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12808
danakj1fd259a02016-04-16 03:17:0912809 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1112810
bnc525e175a2016-06-20 12:36:4012811 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5312812 session->http_server_properties();
bnc0bbb02622015-07-23 10:06:2212813 const int kUnrestrictedAlternatePort = 1025;
bnc3472afd2016-11-17 15:27:2112814 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12815 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1212816 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112817 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4612818 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5012819 expiration);
[email protected]3912662a32011-10-04 00:51:1112820
bnc691fda62016-08-12 00:43:1612821 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112822 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1112823
bnc691fda62016-08-12 00:43:1612824 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2012825 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112826 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1112827 // Valid change to an unrestricted port should pass.
robpercival214763f2016-07-01 23:27:0112828 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1112829}
12830
bnc55ff9da2015-08-19 18:42:3512831// Ensure that we are not allowed to redirect traffic via an alternate protocol
Xida Chen9bfe0b62018-04-24 19:52:2112832// to an unsafe port, and that we resume the second HttpStreamFactory::Job once
12833// the alternate protocol request fails.
bncd16676a2016-07-20 16:23:0112834TEST_F(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:0212835 HttpRequestInfo request;
12836 request.method = "GET";
bncce36dca22015-04-21 22:11:2312837 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1012838 request.traffic_annotation =
12839 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]eb6234e2012-01-19 01:50:0212840
12841 // The alternate protocol request will error out before we attempt to connect,
12842 // so only the standard HTTP request will try to connect.
12843 MockRead data_reads[] = {
12844 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12845 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0612846 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:0212847 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112848 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712849 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:0212850
danakj1fd259a02016-04-16 03:17:0912851 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:0212852
bnc525e175a2016-06-20 12:36:4012853 HttpServerProperties* http_server_properties =
[email protected]eb6234e2012-01-19 01:50:0212854 session->http_server_properties();
12855 const int kUnsafePort = 7;
bnc3472afd2016-11-17 15:27:2112856 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12857 kUnsafePort);
bnc7dc7e1b42015-07-28 14:43:1212858 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112859 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4612860 url::SchemeHostPort(request.url), alternative_service, expiration);
[email protected]eb6234e2012-01-19 01:50:0212861
bnc691fda62016-08-12 00:43:1612862 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]eb6234e2012-01-19 01:50:0212863 TestCompletionCallback callback;
12864
tfarina42834112016-09-22 13:38:2012865 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112866 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]eb6234e2012-01-19 01:50:0212867 // The HTTP request should succeed.
robpercival214763f2016-07-01 23:27:0112868 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb6234e2012-01-19 01:50:0212869
bnc691fda62016-08-12 00:43:1612870 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212871 ASSERT_TRUE(response);
12872 ASSERT_TRUE(response->headers);
[email protected]eb6234e2012-01-19 01:50:0212873 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12874
12875 std::string response_data;
bnc691fda62016-08-12 00:43:1612876 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]eb6234e2012-01-19 01:50:0212877 EXPECT_EQ("hello world", response_data);
12878}
12879
bncd16676a2016-07-20 16:23:0112880TEST_F(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]2ff8b312010-04-26 22:20:5412881 HttpRequestInfo request;
12882 request.method = "GET";
bncb26024382016-06-29 02:39:4512883 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1012884 request.traffic_annotation =
12885 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2ff8b312010-04-26 22:20:5412886
12887 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212888 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312889 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212890 MockRead("\r\n"),
12891 MockRead("hello world"),
12892 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
12893 MockRead(ASYNC, OK)};
[email protected]2ff8b312010-04-26 22:20:5412894
Ryan Sleevib8d7ea02018-05-07 20:01:0112895 StaticSocketDataProvider first_transaction(data_reads,
12896 base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712897 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4512898 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612899 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512900 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5412901
bnc032658ba2016-09-26 18:17:1512902 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5412903
Ryan Hamilton0239aac2018-05-19 00:03:1312904 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4512905 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4112906 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5412907
Raul Tambre94493c652019-03-11 17:18:3512908 spdy::SpdySerializedFrame resp(
12909 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1312910 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5412911 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4112912 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5412913 };
12914
Ryan Sleevib8d7ea02018-05-07 20:01:0112915 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0712916 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5412917
[email protected]d973e99a2012-02-17 21:02:3612918 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0112919 StaticSocketDataProvider hanging_non_alternate_protocol_socket;
[email protected]2d6728692011-03-12 01:39:5512920 hanging_non_alternate_protocol_socket.set_connect_data(
12921 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0712922 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5512923 &hanging_non_alternate_protocol_socket);
12924
[email protected]49639fa2011-12-20 23:22:4112925 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5412926
danakj1fd259a02016-04-16 03:17:0912927 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5812928 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1912929 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5412930
tfarina42834112016-09-22 13:38:2012931 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112932 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12933 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412934
12935 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212936 ASSERT_TRUE(response);
12937 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5412938 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12939
12940 std::string response_data;
robpercival214763f2016-07-01 23:27:0112941 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412942 EXPECT_EQ("hello world", response_data);
12943
bnc87dcefc2017-05-25 12:47:5812944 trans =
Jeremy Roman0579ed62017-08-29 15:56:1912945 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5412946
tfarina42834112016-09-22 13:38:2012947 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112948 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12949 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412950
12951 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212952 ASSERT_TRUE(response);
12953 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212954 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5312955 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212956 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5412957
robpercival214763f2016-07-01 23:27:0112958 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412959 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:5412960}
12961
bncd16676a2016-07-20 16:23:0112962TEST_F(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]2d6728692011-03-12 01:39:5512963 HttpRequestInfo request;
12964 request.method = "GET";
bncb26024382016-06-29 02:39:4512965 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1012966 request.traffic_annotation =
12967 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d6728692011-03-12 01:39:5512968
bncb26024382016-06-29 02:39:4512969 // First transaction receives Alt-Svc header over HTTP/1.1.
[email protected]2d6728692011-03-12 01:39:5512970 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212971 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312972 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212973 MockRead("\r\n"),
12974 MockRead("hello world"),
12975 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
12976 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5512977 };
12978
Ryan Sleevib8d7ea02018-05-07 20:01:0112979 StaticSocketDataProvider http11_data(data_reads, base::span<MockWrite>());
bncb26024382016-06-29 02:39:4512980 session_deps_.socket_factory->AddSocketDataProvider(&http11_data);
[email protected]2d6728692011-03-12 01:39:5512981
bncb26024382016-06-29 02:39:4512982 SSLSocketDataProvider ssl_http11(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4912983 ssl_http11.ssl_info.cert =
12984 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
12985 ASSERT_TRUE(ssl_http11.ssl_info.cert);
bncb26024382016-06-29 02:39:4512986 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
12987
12988 // Second transaction starts an alternative and a non-alternative Job.
12989 // Both sockets hang.
[email protected]d973e99a2012-02-17 21:02:3612990 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0112991 StaticSocketDataProvider hanging_socket1;
mmenkecc2298e2015-12-07 18:20:1812992 hanging_socket1.set_connect_data(never_finishing_connect);
mmenkecc2298e2015-12-07 18:20:1812993 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket1);
12994
Ryan Sleevib8d7ea02018-05-07 20:01:0112995 StaticSocketDataProvider hanging_socket2;
mmenkecc2298e2015-12-07 18:20:1812996 hanging_socket2.set_connect_data(never_finishing_connect);
12997 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket2);
[email protected]2d6728692011-03-12 01:39:5512998
bncb26024382016-06-29 02:39:4512999 // Third transaction starts an alternative and a non-alternative job.
13000 // The non-alternative job hangs, but the alternative one succeeds.
13001 // The second transaction, still pending, binds to this socket.
Ryan Hamilton0239aac2018-05-19 00:03:1313002 spdy::SpdySerializedFrame req1(
bncb26024382016-06-29 02:39:4513003 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1313004 spdy::SpdySerializedFrame req2(
bncb26024382016-06-29 02:39:4513005 spdy_util_.ConstructSpdyGet("https://www.example.org/", 3, LOWEST));
[email protected]2d6728692011-03-12 01:39:5513006 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4113007 CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
[email protected]2d6728692011-03-12 01:39:5513008 };
Raul Tambre94493c652019-03-11 17:18:3513009 spdy::SpdySerializedFrame resp1(
13010 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1313011 spdy::SpdySerializedFrame data1(spdy_util_.ConstructSpdyDataFrame(1, true));
Raul Tambre94493c652019-03-11 17:18:3513012 spdy::SpdySerializedFrame resp2(
13013 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
Ryan Hamilton0239aac2018-05-19 00:03:1313014 spdy::SpdySerializedFrame data2(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]2d6728692011-03-12 01:39:5513015 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113016 CreateMockRead(resp1, 2), CreateMockRead(data1, 3),
13017 CreateMockRead(resp2, 4), CreateMockRead(data2, 5),
rch8e6c6c42015-05-01 14:05:1313018 MockRead(ASYNC, 0, 6),
[email protected]2d6728692011-03-12 01:39:5513019 };
13020
Ryan Sleevib8d7ea02018-05-07 20:01:0113021 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0713022 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:5513023
bnc032658ba2016-09-26 18:17:1513024 AddSSLSocketData();
bncb26024382016-06-29 02:39:4513025
Ryan Sleevib8d7ea02018-05-07 20:01:0113026 StaticSocketDataProvider hanging_socket3;
mmenkecc2298e2015-12-07 18:20:1813027 hanging_socket3.set_connect_data(never_finishing_connect);
13028 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket3);
[email protected]2d6728692011-03-12 01:39:5513029
danakj1fd259a02016-04-16 03:17:0913030 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:4113031 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:5013032 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5513033
tfarina42834112016-09-22 13:38:2013034 int rv = trans1.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113035 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13036 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5513037
13038 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5213039 ASSERT_TRUE(response);
13040 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5513041 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13042
13043 std::string response_data;
robpercival214763f2016-07-01 23:27:0113044 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5513045 EXPECT_EQ("hello world", response_data);
13046
[email protected]49639fa2011-12-20 23:22:4113047 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:5013048 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2013049 rv = trans2.Start(&request, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113050 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5513051
[email protected]49639fa2011-12-20 23:22:4113052 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:5013053 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2013054 rv = trans3.Start(&request, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113055 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5513056
robpercival214763f2016-07-01 23:27:0113057 EXPECT_THAT(callback2.WaitForResult(), IsOk());
13058 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5513059
13060 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5213061 ASSERT_TRUE(response);
13062 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213063 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5513064 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213065 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0113066 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5513067 EXPECT_EQ("hello!", response_data);
13068
13069 response = trans3.GetResponseInfo();
wezca1070932016-05-26 20:30:5213070 ASSERT_TRUE(response);
13071 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213072 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5513073 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213074 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0113075 ASSERT_THAT(ReadTransaction(&trans3, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5513076 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:5513077}
13078
bncd16676a2016-07-20 16:23:0113079TEST_F(HttpNetworkTransactionTest, StallAlternativeServiceForNpnSpdy) {
Bence Békybcae37092018-06-12 04:18:5313080 session_deps_.host_resolver->set_synchronous_mode(true);
13081
[email protected]2d6728692011-03-12 01:39:5513082 HttpRequestInfo request;
13083 request.method = "GET";
bncb26024382016-06-29 02:39:4513084 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1013085 request.traffic_annotation =
13086 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d6728692011-03-12 01:39:5513087
13088 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5213089 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4313090 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5213091 MockRead("\r\n"),
13092 MockRead("hello world"),
13093 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
13094 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5513095 };
13096
Ryan Sleevib8d7ea02018-05-07 20:01:0113097 StaticSocketDataProvider first_transaction(data_reads,
13098 base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0713099 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:5513100
[email protected]8ddf8322012-02-23 18:08:0613101 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4913102 ssl.ssl_info.cert =
13103 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
13104 ASSERT_TRUE(ssl.ssl_info.cert);
[email protected]bb88e1d32013-05-03 23:11:0713105 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5513106
[email protected]d973e99a2012-02-17 21:02:3613107 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0113108 StaticSocketDataProvider hanging_alternate_protocol_socket;
[email protected]2d6728692011-03-12 01:39:5513109 hanging_alternate_protocol_socket.set_connect_data(
13110 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0713111 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5513112 &hanging_alternate_protocol_socket);
13113
bncb26024382016-06-29 02:39:4513114 // 2nd request is just a copy of the first one, over HTTP/1.1 again.
Ryan Sleevib8d7ea02018-05-07 20:01:0113115 StaticSocketDataProvider second_transaction(data_reads,
13116 base::span<MockWrite>());
mmenkecc2298e2015-12-07 18:20:1813117 session_deps_.socket_factory->AddSocketDataProvider(&second_transaction);
bncb26024382016-06-29 02:39:4513118 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5513119
[email protected]49639fa2011-12-20 23:22:4113120 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:5513121
danakj1fd259a02016-04-16 03:17:0913122 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5813123 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1913124 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5513125
tfarina42834112016-09-22 13:38:2013126 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113127 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13128 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5513129
13130 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5213131 ASSERT_TRUE(response);
13132 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5513133 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13134
13135 std::string response_data;
robpercival214763f2016-07-01 23:27:0113136 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5513137 EXPECT_EQ("hello world", response_data);
13138
bnc87dcefc2017-05-25 12:47:5813139 trans =
Jeremy Roman0579ed62017-08-29 15:56:1913140 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5513141
tfarina42834112016-09-22 13:38:2013142 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113143 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13144 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5513145
13146 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5213147 ASSERT_TRUE(response);
13148 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5513149 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13150 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213151 EXPECT_FALSE(response->was_alpn_negotiated);
[email protected]2d6728692011-03-12 01:39:5513152
robpercival214763f2016-07-01 23:27:0113153 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5513154 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:5513155}
13156
bnc2e884782016-08-11 19:45:1913157// Test that proxy is resolved using the origin url,
13158// regardless of the alternative server.
13159TEST_F(HttpNetworkTransactionTest, UseOriginNotAlternativeForProxy) {
13160 // Configure proxy to bypass www.example.org, which is the origin URL.
13161 ProxyConfig proxy_config;
13162 proxy_config.proxy_rules().ParseFromString("myproxy:70");
13163 proxy_config.proxy_rules().bypass_rules.AddRuleFromString("www.example.org");
Ramin Halavatica8d5252018-03-12 05:33:4913164 auto proxy_config_service = std::make_unique<ProxyConfigServiceFixed>(
13165 ProxyConfigWithAnnotation(proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS));
bnc2e884782016-08-11 19:45:1913166
13167 CapturingProxyResolver capturing_proxy_resolver;
Jeremy Roman0579ed62017-08-29 15:56:1913168 auto proxy_resolver_factory = std::make_unique<CapturingProxyResolverFactory>(
bnc2e884782016-08-11 19:45:1913169 &capturing_proxy_resolver);
13170
13171 TestNetLog net_log;
13172
Bence Béky53a5aef2018-03-29 21:54:1213173 session_deps_.proxy_resolution_service =
13174 std::make_unique<ProxyResolutionService>(
13175 std::move(proxy_config_service), std::move(proxy_resolver_factory),
13176 &net_log);
bnc2e884782016-08-11 19:45:1913177
13178 session_deps_.net_log = &net_log;
13179
13180 // Configure alternative service with a hostname that is not bypassed by the
13181 // proxy.
13182 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13183 HttpServerProperties* http_server_properties =
13184 session->http_server_properties();
13185 url::SchemeHostPort server("https", "www.example.org", 443);
13186 HostPortPair alternative("www.example.com", 443);
bnc3472afd2016-11-17 15:27:2113187 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc2e884782016-08-11 19:45:1913188 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2113189 http_server_properties->SetHttp2AlternativeService(
13190 server, alternative_service, expiration);
bnc2e884782016-08-11 19:45:1913191
13192 // Non-alternative job should hang.
13193 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0113194 StaticSocketDataProvider hanging_alternate_protocol_socket;
bnc2e884782016-08-11 19:45:1913195 hanging_alternate_protocol_socket.set_connect_data(never_finishing_connect);
13196 session_deps_.socket_factory->AddSocketDataProvider(
13197 &hanging_alternate_protocol_socket);
13198
bnc032658ba2016-09-26 18:17:1513199 AddSSLSocketData();
bnc2e884782016-08-11 19:45:1913200
13201 HttpRequestInfo request;
13202 request.method = "GET";
13203 request.url = GURL("https://www.example.org/");
13204 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1013205 request.traffic_annotation =
13206 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc2e884782016-08-11 19:45:1913207
Ryan Hamilton0239aac2018-05-19 00:03:1313208 spdy::SpdySerializedFrame req(
bnc2e884782016-08-11 19:45:1913209 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
13210
13211 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
13212
Ryan Hamilton0239aac2018-05-19 00:03:1313213 spdy::SpdySerializedFrame resp(
13214 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
13215 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
bnc2e884782016-08-11 19:45:1913216 MockRead spdy_reads[] = {
13217 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
13218 };
13219
Ryan Sleevib8d7ea02018-05-07 20:01:0113220 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
bnc2e884782016-08-11 19:45:1913221 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
13222
13223 TestCompletionCallback callback;
13224
13225 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
13226
tfarina42834112016-09-22 13:38:2013227 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc2e884782016-08-11 19:45:1913228 EXPECT_THAT(callback.GetResult(rv), IsOk());
13229
13230 const HttpResponseInfo* response = trans.GetResponseInfo();
13231 ASSERT_TRUE(response);
13232 ASSERT_TRUE(response->headers);
13233 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
13234 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213235 EXPECT_TRUE(response->was_alpn_negotiated);
bnc2e884782016-08-11 19:45:1913236
13237 std::string response_data;
13238 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
13239 EXPECT_EQ("hello!", response_data);
13240
13241 // Origin host bypasses proxy, no resolution should have happened.
13242 ASSERT_TRUE(capturing_proxy_resolver.resolved().empty());
13243}
13244
bncd16676a2016-07-20 16:23:0113245TEST_F(HttpNetworkTransactionTest, UseAlternativeServiceForTunneledNpnSpdy) {
[email protected]631f1322010-04-30 17:59:1113246 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:4213247 proxy_config.set_auto_detect(true);
13248 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:1113249
sammc5dd160c2015-04-02 02:43:1313250 CapturingProxyResolver capturing_proxy_resolver;
Ramin Halavatica8d5252018-03-12 05:33:4913251 session_deps_.proxy_resolution_service =
13252 std::make_unique<ProxyResolutionService>(
13253 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
13254 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
13255 std::make_unique<CapturingProxyResolverFactory>(
13256 &capturing_proxy_resolver),
13257 nullptr);
vishal.b62985ca92015-04-17 08:45:5113258 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0713259 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:1113260
13261 HttpRequestInfo request;
13262 request.method = "GET";
bncb26024382016-06-29 02:39:4513263 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1013264 request.traffic_annotation =
13265 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]631f1322010-04-30 17:59:1113266
13267 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5213268 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4313269 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5213270 MockRead("\r\n"),
13271 MockRead("hello world"),
13272 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
13273 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:1113274 };
13275
Ryan Sleevib8d7ea02018-05-07 20:01:0113276 StaticSocketDataProvider first_transaction(data_reads,
13277 base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0713278 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4513279 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613280 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4513281 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]631f1322010-04-30 17:59:1113282
bnc032658ba2016-09-26 18:17:1513283 AddSSLSocketData();
[email protected]631f1322010-04-30 17:59:1113284
Ryan Hamilton0239aac2018-05-19 00:03:1313285 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4513286 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
[email protected]631f1322010-04-30 17:59:1113287 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1313288 MockWrite(ASYNC, 0,
bnc8bef8da22016-05-30 01:28:2513289 "CONNECT www.example.org:443 HTTP/1.1\r\n"
13290 "Host: www.example.org:443\r\n"
rch8e6c6c42015-05-01 14:05:1313291 "Proxy-Connection: keep-alive\r\n\r\n"),
bncdf80d44fd2016-07-15 20:27:4113292 CreateMockWrite(req, 2),
[email protected]631f1322010-04-30 17:59:1113293 };
13294
[email protected]d911f1b2010-05-05 22:39:4213295 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
13296
Raul Tambre94493c652019-03-11 17:18:3513297 spdy::SpdySerializedFrame resp(
13298 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1313299 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]631f1322010-04-30 17:59:1113300 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113301 MockRead(ASYNC, 1, kCONNECTResponse), CreateMockRead(resp, 3),
13302 CreateMockRead(data, 4), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5),
[email protected]631f1322010-04-30 17:59:1113303 };
13304
Ryan Sleevib8d7ea02018-05-07 20:01:0113305 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0713306 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:1113307
[email protected]d973e99a2012-02-17 21:02:3613308 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0113309 StaticSocketDataProvider hanging_non_alternate_protocol_socket;
[email protected]2d6728692011-03-12 01:39:5513310 hanging_non_alternate_protocol_socket.set_connect_data(
13311 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0713312 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5513313 &hanging_non_alternate_protocol_socket);
13314
[email protected]49639fa2011-12-20 23:22:4113315 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:1113316
danakj1fd259a02016-04-16 03:17:0913317 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5813318 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1913319 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1113320
tfarina42834112016-09-22 13:38:2013321 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea2dcd3bf2016-08-16 21:49:4113322 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13323 EXPECT_THAT(callback.WaitForResult(), IsOk());
13324
13325 const HttpResponseInfo* response = trans->GetResponseInfo();
13326 ASSERT_TRUE(response);
13327 ASSERT_TRUE(response->headers);
13328 EXPECT_EQ("HTTP/0.9 200 OK", response->headers->GetStatusLine());
13329 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213330 EXPECT_TRUE(response->was_alpn_negotiated);
mmenkea2dcd3bf2016-08-16 21:49:4113331
13332 std::string response_data;
13333 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
13334 EXPECT_EQ("hello world", response_data);
[email protected]631f1322010-04-30 17:59:1113335
bnc87dcefc2017-05-25 12:47:5813336 trans =
Jeremy Roman0579ed62017-08-29 15:56:1913337 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1113338
tfarina42834112016-09-22 13:38:2013339 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113340 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13341 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]631f1322010-04-30 17:59:1113342
mmenkea2dcd3bf2016-08-16 21:49:4113343 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5213344 ASSERT_TRUE(response);
13345 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213346 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5313347 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213348 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]631f1322010-04-30 17:59:1113349
robpercival214763f2016-07-01 23:27:0113350 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]631f1322010-04-30 17:59:1113351 EXPECT_EQ("hello!", response_data);
bncb26024382016-06-29 02:39:4513352 ASSERT_EQ(2u, capturing_proxy_resolver.resolved().size());
13353 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1313354 capturing_proxy_resolver.resolved()[0].spec());
bncce36dca22015-04-21 22:11:2313355 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1313356 capturing_proxy_resolver.resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:1113357
[email protected]029c83b62013-01-24 05:28:2013358 LoadTimingInfo load_timing_info;
13359 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
13360 TestLoadTimingNotReusedWithPac(load_timing_info,
13361 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:1113362}
[email protected]631f1322010-04-30 17:59:1113363
bncd16676a2016-07-20 16:23:0113364TEST_F(HttpNetworkTransactionTest,
bnc1c196c6e2016-05-28 13:51:4813365 UseAlternativeServiceForNpnSpdyWithExistingSpdySession) {
[email protected]2ff8b312010-04-26 22:20:5413366 HttpRequestInfo request;
13367 request.method = "GET";
bncb26024382016-06-29 02:39:4513368 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1013369 request.traffic_annotation =
13370 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2ff8b312010-04-26 22:20:5413371
13372 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5213373 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4313374 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5213375 MockRead("\r\n"),
13376 MockRead("hello world"),
13377 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:5413378 };
13379
Ryan Sleevib8d7ea02018-05-07 20:01:0113380 StaticSocketDataProvider first_transaction(data_reads,
13381 base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0713382 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4513383 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613384 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4513385 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5413386
bnc032658ba2016-09-26 18:17:1513387 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5413388
Ryan Hamilton0239aac2018-05-19 00:03:1313389 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4513390 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4113391 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5413392
Raul Tambre94493c652019-03-11 17:18:3513393 spdy::SpdySerializedFrame resp(
13394 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1313395 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5413396 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113397 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5413398 };
13399
Ryan Sleevib8d7ea02018-05-07 20:01:0113400 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0713401 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5413402
[email protected]83039bb2011-12-09 18:43:5513403 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5413404
danakj1fd259a02016-04-16 03:17:0913405 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:5413406
bnc87dcefc2017-05-25 12:47:5813407 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1913408 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5413409
tfarina42834112016-09-22 13:38:2013410 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113411 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13412 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5413413
13414 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5213415 ASSERT_TRUE(response);
13416 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5413417 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13418
13419 std::string response_data;
robpercival214763f2016-07-01 23:27:0113420 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5413421 EXPECT_EQ("hello world", response_data);
13422
13423 // Set up an initial SpdySession in the pool to reuse.
bnc8bef8da22016-05-30 01:28:2513424 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4013425 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
Matt Menke2436b2f2018-12-11 18:07:1113426 PRIVACY_MODE_DISABLED,
13427 SpdySessionKey::IsProxySession::kFalse, SocketTag());
[email protected]795cbf82013-07-22 09:37:2713428 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:5213429 CreateSpdySession(session.get(), key, NetLogWithSource());
[email protected]02b0c342010-09-25 21:09:3813430
bnc87dcefc2017-05-25 12:47:5813431 trans =
Jeremy Roman0579ed62017-08-29 15:56:1913432 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5413433
tfarina42834112016-09-22 13:38:2013434 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113435 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13436 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5413437
13438 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5213439 ASSERT_TRUE(response);
13440 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213441 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5313442 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213443 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5413444
robpercival214763f2016-07-01 23:27:0113445 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5413446 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:4213447}
13448
[email protected]044de0642010-06-17 10:42:1513449// GenerateAuthToken is a mighty big test.
13450// It tests all permutation of GenerateAuthToken behavior:
13451// - Synchronous and Asynchronous completion.
13452// - OK or error on completion.
13453// - Direct connection, non-authenticating proxy, and authenticating proxy.
13454// - HTTP or HTTPS backend (to include proxy tunneling).
13455// - Non-authenticating and authenticating backend.
13456//
[email protected]fe3b7dc2012-02-03 19:52:0913457// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:1513458// problems generating an auth token for an authenticating proxy, we don't
13459// need to test all permutations of the backend server).
13460//
13461// The test proceeds by going over each of the configuration cases, and
13462// potentially running up to three rounds in each of the tests. The TestConfig
13463// specifies both the configuration for the test as well as the expectations
13464// for the results.
bncd16676a2016-07-20 16:23:0113465TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:5013466 static const char kServer[] = "http://www.example.com";
13467 static const char kSecureServer[] = "https://www.example.com";
13468 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:1513469
13470 enum AuthTiming {
13471 AUTH_NONE,
13472 AUTH_SYNC,
13473 AUTH_ASYNC,
13474 };
13475
13476 const MockWrite kGet(
13477 "GET / HTTP/1.1\r\n"
13478 "Host: www.example.com\r\n"
13479 "Connection: keep-alive\r\n\r\n");
13480 const MockWrite kGetProxy(
13481 "GET http://www.example.com/ HTTP/1.1\r\n"
13482 "Host: www.example.com\r\n"
13483 "Proxy-Connection: keep-alive\r\n\r\n");
13484 const MockWrite kGetAuth(
13485 "GET / HTTP/1.1\r\n"
13486 "Host: www.example.com\r\n"
13487 "Connection: keep-alive\r\n"
13488 "Authorization: auth_token\r\n\r\n");
13489 const MockWrite kGetProxyAuth(
13490 "GET http://www.example.com/ HTTP/1.1\r\n"
13491 "Host: www.example.com\r\n"
13492 "Proxy-Connection: keep-alive\r\n"
13493 "Proxy-Authorization: auth_token\r\n\r\n");
13494 const MockWrite kGetAuthThroughProxy(
13495 "GET http://www.example.com/ HTTP/1.1\r\n"
13496 "Host: www.example.com\r\n"
13497 "Proxy-Connection: keep-alive\r\n"
13498 "Authorization: auth_token\r\n\r\n");
13499 const MockWrite kGetAuthWithProxyAuth(
13500 "GET http://www.example.com/ HTTP/1.1\r\n"
13501 "Host: www.example.com\r\n"
13502 "Proxy-Connection: keep-alive\r\n"
13503 "Proxy-Authorization: auth_token\r\n"
13504 "Authorization: auth_token\r\n\r\n");
13505 const MockWrite kConnect(
13506 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1713507 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1513508 "Proxy-Connection: keep-alive\r\n\r\n");
13509 const MockWrite kConnectProxyAuth(
13510 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1713511 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1513512 "Proxy-Connection: keep-alive\r\n"
13513 "Proxy-Authorization: auth_token\r\n\r\n");
13514
13515 const MockRead kSuccess(
13516 "HTTP/1.1 200 OK\r\n"
13517 "Content-Type: text/html; charset=iso-8859-1\r\n"
13518 "Content-Length: 3\r\n\r\n"
13519 "Yes");
13520 const MockRead kFailure(
13521 "Should not be called.");
13522 const MockRead kServerChallenge(
13523 "HTTP/1.1 401 Unauthorized\r\n"
13524 "WWW-Authenticate: Mock realm=server\r\n"
13525 "Content-Type: text/html; charset=iso-8859-1\r\n"
13526 "Content-Length: 14\r\n\r\n"
13527 "Unauthorized\r\n");
13528 const MockRead kProxyChallenge(
13529 "HTTP/1.1 407 Unauthorized\r\n"
13530 "Proxy-Authenticate: Mock realm=proxy\r\n"
13531 "Proxy-Connection: close\r\n"
13532 "Content-Type: text/html; charset=iso-8859-1\r\n"
13533 "Content-Length: 14\r\n\r\n"
13534 "Unauthorized\r\n");
13535 const MockRead kProxyConnected(
13536 "HTTP/1.1 200 Connection Established\r\n\r\n");
13537
13538 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
13539 // no constructors, but the C++ compiler on Windows warns about
13540 // unspecified data in compound literals. So, moved to using constructors,
13541 // and TestRound's created with the default constructor should not be used.
13542 struct TestRound {
13543 TestRound()
Raul Tambre94493c652019-03-11 17:18:3513544 : expected_rv(ERR_UNEXPECTED),
13545 extra_write(nullptr),
13546 extra_read(nullptr) {}
Raul Tambre8335a6d2019-02-21 16:57:4313547 TestRound(const MockWrite& write_arg,
13548 const MockRead& read_arg,
[email protected]044de0642010-06-17 10:42:1513549 int expected_rv_arg)
13550 : write(write_arg),
13551 read(read_arg),
13552 expected_rv(expected_rv_arg),
Raul Tambre94493c652019-03-11 17:18:3513553 extra_write(nullptr),
13554 extra_read(nullptr) {}
[email protected]044de0642010-06-17 10:42:1513555 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
13556 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:0113557 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:1513558 : write(write_arg),
13559 read(read_arg),
13560 expected_rv(expected_rv_arg),
13561 extra_write(extra_write_arg),
13562 extra_read(extra_read_arg) {
13563 }
13564 MockWrite write;
13565 MockRead read;
13566 int expected_rv;
13567 const MockWrite* extra_write;
13568 const MockRead* extra_read;
13569 };
13570
13571 static const int kNoSSL = 500;
13572
13573 struct TestConfig {
asanka463ca4262016-11-16 02:34:3113574 int line_number;
thestig9d3bb0c2015-01-24 00:49:5113575 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:1513576 AuthTiming proxy_auth_timing;
asanka463ca4262016-11-16 02:34:3113577 int first_generate_proxy_token_rv;
thestig9d3bb0c2015-01-24 00:49:5113578 const char* const server_url;
[email protected]044de0642010-06-17 10:42:1513579 AuthTiming server_auth_timing;
asanka463ca4262016-11-16 02:34:3113580 int first_generate_server_token_rv;
[email protected]044de0642010-06-17 10:42:1513581 int num_auth_rounds;
13582 int first_ssl_round;
asankae2257db2016-10-11 22:03:1613583 TestRound rounds[4];
[email protected]044de0642010-06-17 10:42:1513584 } test_configs[] = {
asankac93076192016-10-03 15:46:0213585 // Non-authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3113586 {__LINE__,
13587 nullptr,
asankac93076192016-10-03 15:46:0213588 AUTH_NONE,
13589 OK,
13590 kServer,
13591 AUTH_NONE,
13592 OK,
13593 1,
13594 kNoSSL,
13595 {TestRound(kGet, kSuccess, OK)}},
13596 // Authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3113597 {__LINE__,
13598 nullptr,
asankac93076192016-10-03 15:46:0213599 AUTH_NONE,
13600 OK,
13601 kServer,
13602 AUTH_SYNC,
13603 OK,
13604 2,
13605 kNoSSL,
13606 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513607 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113608 {__LINE__,
13609 nullptr,
asankac93076192016-10-03 15:46:0213610 AUTH_NONE,
13611 OK,
13612 kServer,
13613 AUTH_SYNC,
13614 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1613615 3,
13616 kNoSSL,
13617 {TestRound(kGet, kServerChallenge, OK),
13618 TestRound(kGet, kServerChallenge, OK),
13619 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113620 {__LINE__,
13621 nullptr,
asankae2257db2016-10-11 22:03:1613622 AUTH_NONE,
13623 OK,
13624 kServer,
13625 AUTH_SYNC,
13626 ERR_UNSUPPORTED_AUTH_SCHEME,
13627 2,
13628 kNoSSL,
13629 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113630 {__LINE__,
13631 nullptr,
asankae2257db2016-10-11 22:03:1613632 AUTH_NONE,
13633 OK,
13634 kServer,
13635 AUTH_SYNC,
13636 ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS,
13637 2,
13638 kNoSSL,
13639 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113640 {__LINE__,
13641 kProxy,
asankae2257db2016-10-11 22:03:1613642 AUTH_SYNC,
13643 ERR_FAILED,
13644 kServer,
13645 AUTH_NONE,
13646 OK,
13647 2,
13648 kNoSSL,
13649 {TestRound(kGetProxy, kProxyChallenge, OK),
13650 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3113651 {__LINE__,
13652 kProxy,
asankae2257db2016-10-11 22:03:1613653 AUTH_ASYNC,
13654 ERR_FAILED,
13655 kServer,
13656 AUTH_NONE,
13657 OK,
13658 2,
13659 kNoSSL,
13660 {TestRound(kGetProxy, kProxyChallenge, OK),
13661 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3113662 {__LINE__,
13663 nullptr,
asankae2257db2016-10-11 22:03:1613664 AUTH_NONE,
13665 OK,
13666 kServer,
13667 AUTH_SYNC,
13668 ERR_FAILED,
asankac93076192016-10-03 15:46:0213669 2,
13670 kNoSSL,
13671 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613672 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3113673 {__LINE__,
13674 nullptr,
asankae2257db2016-10-11 22:03:1613675 AUTH_NONE,
13676 OK,
13677 kServer,
13678 AUTH_ASYNC,
13679 ERR_FAILED,
13680 2,
13681 kNoSSL,
13682 {TestRound(kGet, kServerChallenge, OK),
13683 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3113684 {__LINE__,
13685 nullptr,
asankac93076192016-10-03 15:46:0213686 AUTH_NONE,
13687 OK,
13688 kServer,
13689 AUTH_ASYNC,
13690 OK,
13691 2,
13692 kNoSSL,
13693 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513694 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113695 {__LINE__,
13696 nullptr,
asankac93076192016-10-03 15:46:0213697 AUTH_NONE,
13698 OK,
13699 kServer,
13700 AUTH_ASYNC,
13701 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1613702 3,
asankac93076192016-10-03 15:46:0213703 kNoSSL,
13704 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613705 // The second round uses a HttpAuthHandlerMock that always succeeds.
13706 TestRound(kGet, kServerChallenge, OK),
13707 TestRound(kGetAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213708 // Non-authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3113709 {__LINE__,
13710 kProxy,
asankac93076192016-10-03 15:46:0213711 AUTH_NONE,
13712 OK,
13713 kServer,
13714 AUTH_NONE,
13715 OK,
13716 1,
13717 kNoSSL,
13718 {TestRound(kGetProxy, kSuccess, OK)}},
13719 // Authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3113720 {__LINE__,
13721 kProxy,
asankac93076192016-10-03 15:46:0213722 AUTH_NONE,
13723 OK,
13724 kServer,
13725 AUTH_SYNC,
13726 OK,
13727 2,
13728 kNoSSL,
13729 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513730 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113731 {__LINE__,
13732 kProxy,
asankac93076192016-10-03 15:46:0213733 AUTH_NONE,
13734 OK,
13735 kServer,
13736 AUTH_SYNC,
13737 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1613738 3,
asankac93076192016-10-03 15:46:0213739 kNoSSL,
13740 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613741 TestRound(kGetProxy, kServerChallenge, OK),
13742 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113743 {__LINE__,
13744 kProxy,
asankac93076192016-10-03 15:46:0213745 AUTH_NONE,
13746 OK,
13747 kServer,
13748 AUTH_ASYNC,
13749 OK,
13750 2,
13751 kNoSSL,
13752 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513753 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113754 {__LINE__,
13755 kProxy,
asankac93076192016-10-03 15:46:0213756 AUTH_NONE,
13757 OK,
13758 kServer,
13759 AUTH_ASYNC,
13760 ERR_INVALID_AUTH_CREDENTIALS,
13761 2,
13762 kNoSSL,
13763 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613764 TestRound(kGetProxy, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213765 // Non-authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3113766 {__LINE__,
13767 kProxy,
asankac93076192016-10-03 15:46:0213768 AUTH_SYNC,
13769 OK,
13770 kServer,
13771 AUTH_NONE,
13772 OK,
13773 2,
13774 kNoSSL,
13775 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513776 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113777 {__LINE__,
13778 kProxy,
asankac93076192016-10-03 15:46:0213779 AUTH_SYNC,
13780 ERR_INVALID_AUTH_CREDENTIALS,
13781 kServer,
13782 AUTH_NONE,
13783 OK,
13784 2,
13785 kNoSSL,
13786 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1613787 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113788 {__LINE__,
13789 kProxy,
asankac93076192016-10-03 15:46:0213790 AUTH_ASYNC,
13791 OK,
13792 kServer,
13793 AUTH_NONE,
13794 OK,
13795 2,
13796 kNoSSL,
13797 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513798 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113799 {__LINE__,
13800 kProxy,
asankac93076192016-10-03 15:46:0213801 AUTH_ASYNC,
13802 ERR_INVALID_AUTH_CREDENTIALS,
13803 kServer,
13804 AUTH_NONE,
13805 OK,
13806 2,
13807 kNoSSL,
13808 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1613809 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113810 {__LINE__,
13811 kProxy,
13812 AUTH_ASYNC,
13813 ERR_INVALID_AUTH_CREDENTIALS,
13814 kServer,
13815 AUTH_NONE,
13816 OK,
13817 3,
13818 kNoSSL,
13819 {TestRound(kGetProxy, kProxyChallenge, OK),
13820 TestRound(kGetProxy, kProxyChallenge, OK),
13821 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213822 // Authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3113823 {__LINE__,
13824 kProxy,
asankac93076192016-10-03 15:46:0213825 AUTH_SYNC,
13826 OK,
13827 kServer,
13828 AUTH_SYNC,
13829 OK,
13830 3,
13831 kNoSSL,
13832 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513833 TestRound(kGetProxyAuth, kServerChallenge, OK),
13834 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113835 {__LINE__,
13836 kProxy,
asankac93076192016-10-03 15:46:0213837 AUTH_SYNC,
13838 OK,
13839 kServer,
13840 AUTH_SYNC,
13841 ERR_INVALID_AUTH_CREDENTIALS,
13842 3,
13843 kNoSSL,
13844 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513845 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613846 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113847 {__LINE__,
13848 kProxy,
asankac93076192016-10-03 15:46:0213849 AUTH_ASYNC,
13850 OK,
13851 kServer,
13852 AUTH_SYNC,
13853 OK,
13854 3,
13855 kNoSSL,
13856 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513857 TestRound(kGetProxyAuth, kServerChallenge, OK),
13858 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113859 {__LINE__,
13860 kProxy,
asankac93076192016-10-03 15:46:0213861 AUTH_ASYNC,
13862 OK,
13863 kServer,
13864 AUTH_SYNC,
13865 ERR_INVALID_AUTH_CREDENTIALS,
13866 3,
13867 kNoSSL,
13868 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513869 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613870 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113871 {__LINE__,
13872 kProxy,
asankac93076192016-10-03 15:46:0213873 AUTH_SYNC,
13874 OK,
13875 kServer,
13876 AUTH_ASYNC,
13877 OK,
13878 3,
13879 kNoSSL,
13880 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513881 TestRound(kGetProxyAuth, kServerChallenge, OK),
13882 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113883 {__LINE__,
13884 kProxy,
13885 AUTH_SYNC,
13886 ERR_INVALID_AUTH_CREDENTIALS,
13887 kServer,
13888 AUTH_ASYNC,
13889 OK,
13890 4,
13891 kNoSSL,
13892 {TestRound(kGetProxy, kProxyChallenge, OK),
13893 TestRound(kGetProxy, kProxyChallenge, OK),
13894 TestRound(kGetProxyAuth, kServerChallenge, OK),
13895 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
13896 {__LINE__,
13897 kProxy,
asankac93076192016-10-03 15:46:0213898 AUTH_SYNC,
13899 OK,
13900 kServer,
13901 AUTH_ASYNC,
13902 ERR_INVALID_AUTH_CREDENTIALS,
13903 3,
13904 kNoSSL,
13905 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513906 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613907 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113908 {__LINE__,
13909 kProxy,
asankac93076192016-10-03 15:46:0213910 AUTH_ASYNC,
13911 OK,
13912 kServer,
13913 AUTH_ASYNC,
13914 OK,
13915 3,
13916 kNoSSL,
13917 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513918 TestRound(kGetProxyAuth, kServerChallenge, OK),
13919 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113920 {__LINE__,
13921 kProxy,
asankac93076192016-10-03 15:46:0213922 AUTH_ASYNC,
13923 OK,
13924 kServer,
13925 AUTH_ASYNC,
13926 ERR_INVALID_AUTH_CREDENTIALS,
13927 3,
13928 kNoSSL,
13929 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513930 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613931 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113932 {__LINE__,
13933 kProxy,
13934 AUTH_ASYNC,
13935 ERR_INVALID_AUTH_CREDENTIALS,
13936 kServer,
13937 AUTH_ASYNC,
13938 ERR_INVALID_AUTH_CREDENTIALS,
13939 4,
13940 kNoSSL,
13941 {TestRound(kGetProxy, kProxyChallenge, OK),
13942 TestRound(kGetProxy, kProxyChallenge, OK),
13943 TestRound(kGetProxyAuth, kServerChallenge, OK),
13944 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213945 // Non-authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3113946 {__LINE__,
13947 nullptr,
asankac93076192016-10-03 15:46:0213948 AUTH_NONE,
13949 OK,
13950 kSecureServer,
13951 AUTH_NONE,
13952 OK,
13953 1,
13954 0,
13955 {TestRound(kGet, kSuccess, OK)}},
13956 // Authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3113957 {__LINE__,
13958 nullptr,
asankac93076192016-10-03 15:46:0213959 AUTH_NONE,
13960 OK,
13961 kSecureServer,
13962 AUTH_SYNC,
13963 OK,
13964 2,
13965 0,
13966 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513967 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113968 {__LINE__,
13969 nullptr,
asankac93076192016-10-03 15:46:0213970 AUTH_NONE,
13971 OK,
13972 kSecureServer,
13973 AUTH_SYNC,
13974 ERR_INVALID_AUTH_CREDENTIALS,
13975 2,
13976 0,
asankae2257db2016-10-11 22:03:1613977 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113978 {__LINE__,
13979 nullptr,
asankac93076192016-10-03 15:46:0213980 AUTH_NONE,
13981 OK,
13982 kSecureServer,
13983 AUTH_ASYNC,
13984 OK,
13985 2,
13986 0,
13987 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513988 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113989 {__LINE__,
13990 nullptr,
asankac93076192016-10-03 15:46:0213991 AUTH_NONE,
13992 OK,
13993 kSecureServer,
13994 AUTH_ASYNC,
13995 ERR_INVALID_AUTH_CREDENTIALS,
13996 2,
13997 0,
asankae2257db2016-10-11 22:03:1613998 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213999 // Non-authenticating HTTPS server with a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3114000 {__LINE__,
14001 kProxy,
asankac93076192016-10-03 15:46:0214002 AUTH_NONE,
14003 OK,
14004 kSecureServer,
14005 AUTH_NONE,
14006 OK,
14007 1,
14008 0,
14009 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
14010 // Authenticating HTTPS server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3114011 {__LINE__,
14012 kProxy,
asankac93076192016-10-03 15:46:0214013 AUTH_NONE,
14014 OK,
14015 kSecureServer,
14016 AUTH_SYNC,
14017 OK,
14018 2,
14019 0,
14020 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1514021 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114022 {__LINE__,
14023 kProxy,
asankac93076192016-10-03 15:46:0214024 AUTH_NONE,
14025 OK,
14026 kSecureServer,
14027 AUTH_SYNC,
14028 ERR_INVALID_AUTH_CREDENTIALS,
14029 2,
14030 0,
14031 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1614032 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114033 {__LINE__,
14034 kProxy,
asankac93076192016-10-03 15:46:0214035 AUTH_NONE,
14036 OK,
14037 kSecureServer,
14038 AUTH_ASYNC,
14039 OK,
14040 2,
14041 0,
14042 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1514043 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114044 {__LINE__,
14045 kProxy,
asankac93076192016-10-03 15:46:0214046 AUTH_NONE,
14047 OK,
14048 kSecureServer,
14049 AUTH_ASYNC,
14050 ERR_INVALID_AUTH_CREDENTIALS,
14051 2,
14052 0,
14053 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1614054 TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0214055 // Non-Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3114056 {__LINE__,
14057 kProxy,
asankac93076192016-10-03 15:46:0214058 AUTH_SYNC,
14059 OK,
14060 kSecureServer,
14061 AUTH_NONE,
14062 OK,
14063 2,
14064 1,
14065 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1514066 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3114067 {__LINE__,
14068 kProxy,
asankac93076192016-10-03 15:46:0214069 AUTH_SYNC,
14070 ERR_INVALID_AUTH_CREDENTIALS,
14071 kSecureServer,
14072 AUTH_NONE,
14073 OK,
14074 2,
14075 kNoSSL,
14076 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1614077 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3114078 {__LINE__,
14079 kProxy,
asankae2257db2016-10-11 22:03:1614080 AUTH_SYNC,
14081 ERR_UNSUPPORTED_AUTH_SCHEME,
14082 kSecureServer,
14083 AUTH_NONE,
14084 OK,
14085 2,
14086 kNoSSL,
14087 {TestRound(kConnect, kProxyChallenge, OK),
14088 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3114089 {__LINE__,
14090 kProxy,
asankae2257db2016-10-11 22:03:1614091 AUTH_SYNC,
14092 ERR_UNEXPECTED,
14093 kSecureServer,
14094 AUTH_NONE,
14095 OK,
14096 2,
14097 kNoSSL,
14098 {TestRound(kConnect, kProxyChallenge, OK),
14099 TestRound(kConnect, kProxyConnected, ERR_UNEXPECTED)}},
asanka463ca4262016-11-16 02:34:3114100 {__LINE__,
14101 kProxy,
asankac93076192016-10-03 15:46:0214102 AUTH_ASYNC,
14103 OK,
14104 kSecureServer,
14105 AUTH_NONE,
14106 OK,
14107 2,
14108 1,
14109 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1514110 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3114111 {__LINE__,
14112 kProxy,
asankac93076192016-10-03 15:46:0214113 AUTH_ASYNC,
14114 ERR_INVALID_AUTH_CREDENTIALS,
14115 kSecureServer,
14116 AUTH_NONE,
14117 OK,
14118 2,
14119 kNoSSL,
14120 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1614121 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asankac93076192016-10-03 15:46:0214122 // Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3114123 {__LINE__,
14124 kProxy,
asankac93076192016-10-03 15:46:0214125 AUTH_SYNC,
14126 OK,
14127 kSecureServer,
14128 AUTH_SYNC,
14129 OK,
14130 3,
14131 1,
14132 {TestRound(kConnect, kProxyChallenge, OK),
14133 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14134 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1514135 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114136 {__LINE__,
14137 kProxy,
asankac93076192016-10-03 15:46:0214138 AUTH_SYNC,
14139 OK,
14140 kSecureServer,
14141 AUTH_SYNC,
14142 ERR_INVALID_AUTH_CREDENTIALS,
14143 3,
14144 1,
14145 {TestRound(kConnect, kProxyChallenge, OK),
14146 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14147 &kServerChallenge),
asankae2257db2016-10-11 22:03:1614148 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114149 {__LINE__,
14150 kProxy,
asankac93076192016-10-03 15:46:0214151 AUTH_ASYNC,
14152 OK,
14153 kSecureServer,
14154 AUTH_SYNC,
14155 OK,
14156 3,
14157 1,
14158 {TestRound(kConnect, kProxyChallenge, OK),
14159 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14160 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1514161 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114162 {__LINE__,
14163 kProxy,
asankac93076192016-10-03 15:46:0214164 AUTH_ASYNC,
14165 OK,
14166 kSecureServer,
14167 AUTH_SYNC,
14168 ERR_INVALID_AUTH_CREDENTIALS,
14169 3,
14170 1,
14171 {TestRound(kConnect, kProxyChallenge, OK),
14172 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14173 &kServerChallenge),
asankae2257db2016-10-11 22:03:1614174 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114175 {__LINE__,
14176 kProxy,
asankac93076192016-10-03 15:46:0214177 AUTH_SYNC,
14178 OK,
14179 kSecureServer,
14180 AUTH_ASYNC,
14181 OK,
14182 3,
14183 1,
14184 {TestRound(kConnect, kProxyChallenge, OK),
14185 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14186 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1514187 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114188 {__LINE__,
14189 kProxy,
asankac93076192016-10-03 15:46:0214190 AUTH_SYNC,
14191 OK,
14192 kSecureServer,
14193 AUTH_ASYNC,
14194 ERR_INVALID_AUTH_CREDENTIALS,
14195 3,
14196 1,
14197 {TestRound(kConnect, kProxyChallenge, OK),
14198 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14199 &kServerChallenge),
asankae2257db2016-10-11 22:03:1614200 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114201 {__LINE__,
14202 kProxy,
asankac93076192016-10-03 15:46:0214203 AUTH_ASYNC,
14204 OK,
14205 kSecureServer,
14206 AUTH_ASYNC,
14207 OK,
14208 3,
14209 1,
14210 {TestRound(kConnect, kProxyChallenge, OK),
14211 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14212 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1514213 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114214 {__LINE__,
14215 kProxy,
asankac93076192016-10-03 15:46:0214216 AUTH_ASYNC,
14217 OK,
14218 kSecureServer,
14219 AUTH_ASYNC,
14220 ERR_INVALID_AUTH_CREDENTIALS,
14221 3,
14222 1,
14223 {TestRound(kConnect, kProxyChallenge, OK),
14224 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14225 &kServerChallenge),
asankae2257db2016-10-11 22:03:1614226 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114227 {__LINE__,
14228 kProxy,
14229 AUTH_ASYNC,
14230 ERR_INVALID_AUTH_CREDENTIALS,
14231 kSecureServer,
14232 AUTH_ASYNC,
14233 ERR_INVALID_AUTH_CREDENTIALS,
14234 4,
14235 2,
14236 {TestRound(kConnect, kProxyChallenge, OK),
14237 TestRound(kConnect, kProxyChallenge, OK),
14238 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14239 &kServerChallenge),
14240 TestRound(kGet, kSuccess, OK)}},
[email protected]044de0642010-06-17 10:42:1514241 };
14242
asanka463ca4262016-11-16 02:34:3114243 for (const auto& test_config : test_configs) {
14244 SCOPED_TRACE(::testing::Message() << "Test config at "
14245 << test_config.line_number);
[email protected]2d01c262011-08-11 23:07:0814246 HttpAuthHandlerMock::Factory* auth_factory(
14247 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0714248 session_deps_.http_auth_handler_factory.reset(auth_factory);
asanka5ffd5d72016-03-23 16:20:4914249 SSLInfo empty_ssl_info;
[email protected]65d34382010-07-01 18:12:2614250
14251 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:1514252 if (test_config.proxy_auth_timing != AUTH_NONE) {
asanka463ca4262016-11-16 02:34:3114253 for (int n = 0; n < 3; n++) {
[email protected]2d01c262011-08-11 23:07:0814254 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
14255 std::string auth_challenge = "Mock realm=proxy";
14256 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:2414257 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
14258 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:0814259 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
tfarina42834112016-09-22 13:38:2014260 empty_ssl_info, origin,
14261 NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0814262 auth_handler->SetGenerateExpectation(
14263 test_config.proxy_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3114264 n == 0 ? test_config.first_generate_proxy_token_rv : OK);
[email protected]2d01c262011-08-11 23:07:0814265 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
14266 }
[email protected]044de0642010-06-17 10:42:1514267 }
14268 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:0014269 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:1514270 std::string auth_challenge = "Mock realm=server";
14271 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:2414272 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
14273 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:1514274 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2014275 empty_ssl_info, origin,
14276 NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1514277 auth_handler->SetGenerateExpectation(
14278 test_config.server_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3114279 test_config.first_generate_server_token_rv);
[email protected]2d01c262011-08-11 23:07:0814280 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
asankae2257db2016-10-11 22:03:1614281
14282 // The second handler always succeeds. It should only be used where there
14283 // are multiple auth sessions for server auth in the same network
14284 // transaction using the same auth scheme.
14285 std::unique_ptr<HttpAuthHandlerMock> second_handler =
Jeremy Roman0579ed62017-08-29 15:56:1914286 std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:1614287 second_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
14288 empty_ssl_info, origin,
14289 NetLogWithSource());
14290 second_handler->SetGenerateExpectation(true, OK);
14291 auth_factory->AddMockHandler(second_handler.release(),
14292 HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:1514293 }
14294 if (test_config.proxy_url) {
Lily Houghton8c2f97d2018-01-22 05:06:5914295 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4914296 ProxyResolutionService::CreateFixed(test_config.proxy_url,
14297 TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]044de0642010-06-17 10:42:1514298 } else {
Bence Béky53a5aef2018-03-29 21:54:1214299 session_deps_.proxy_resolution_service =
14300 ProxyResolutionService::CreateDirect();
[email protected]044de0642010-06-17 10:42:1514301 }
14302
14303 HttpRequestInfo request;
14304 request.method = "GET";
14305 request.url = GURL(test_config.server_url);
Ramin Halavatib5e433e2018-02-07 07:41:1014306 request.traffic_annotation =
14307 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]044de0642010-06-17 10:42:1514308
danakj1fd259a02016-04-16 03:17:0914309 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]044de0642010-06-17 10:42:1514310
rchcb68dc62015-05-21 04:45:3614311 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
14312
14313 std::vector<std::vector<MockRead>> mock_reads(1);
14314 std::vector<std::vector<MockWrite>> mock_writes(1);
[email protected]044de0642010-06-17 10:42:1514315 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2214316 SCOPED_TRACE(round);
[email protected]044de0642010-06-17 10:42:1514317 const TestRound& read_write_round = test_config.rounds[round];
14318
14319 // Set up expected reads and writes.
rchcb68dc62015-05-21 04:45:3614320 mock_reads.back().push_back(read_write_round.read);
14321 mock_writes.back().push_back(read_write_round.write);
14322
14323 // kProxyChallenge uses Proxy-Connection: close which means that the
14324 // socket is closed and a new one will be created for the next request.
mmenkee71e15332015-10-07 16:39:5414325 if (read_write_round.read.data == kProxyChallenge.data) {
rchcb68dc62015-05-21 04:45:3614326 mock_reads.push_back(std::vector<MockRead>());
14327 mock_writes.push_back(std::vector<MockWrite>());
[email protected]044de0642010-06-17 10:42:1514328 }
14329
rchcb68dc62015-05-21 04:45:3614330 if (read_write_round.extra_read) {
14331 mock_reads.back().push_back(*read_write_round.extra_read);
[email protected]044de0642010-06-17 10:42:1514332 }
rchcb68dc62015-05-21 04:45:3614333 if (read_write_round.extra_write) {
14334 mock_writes.back().push_back(*read_write_round.extra_write);
14335 }
[email protected]044de0642010-06-17 10:42:1514336
14337 // Add an SSL sequence if necessary.
[email protected]044de0642010-06-17 10:42:1514338 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0714339 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1514340 &ssl_socket_data_provider);
rchcb68dc62015-05-21 04:45:3614341 }
[email protected]044de0642010-06-17 10:42:1514342
danakj1fd259a02016-04-16 03:17:0914343 std::vector<std::unique_ptr<StaticSocketDataProvider>> data_providers;
rchcb68dc62015-05-21 04:45:3614344 for (size_t i = 0; i < mock_reads.size(); ++i) {
Jeremy Roman0579ed62017-08-29 15:56:1914345 data_providers.push_back(std::make_unique<StaticSocketDataProvider>(
Ryan Sleevib8d7ea02018-05-07 20:01:0114346 mock_reads[i], mock_writes[i]));
rchcb68dc62015-05-21 04:45:3614347 session_deps_.socket_factory->AddSocketDataProvider(
olli.raula525048c2015-12-10 07:38:3214348 data_providers.back().get());
rchcb68dc62015-05-21 04:45:3614349 }
14350
mmenkecc2298e2015-12-07 18:20:1814351 // Transaction must be created after DataProviders, so it's destroyed before
14352 // they are as well.
14353 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
14354
rchcb68dc62015-05-21 04:45:3614355 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2214356 SCOPED_TRACE(round);
rchcb68dc62015-05-21 04:45:3614357 const TestRound& read_write_round = test_config.rounds[round];
[email protected]044de0642010-06-17 10:42:1514358 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4114359 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1514360 int rv;
14361 if (round == 0) {
tfarina42834112016-09-22 13:38:2014362 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1514363 } else {
[email protected]49639fa2011-12-20 23:22:4114364 rv = trans.RestartWithAuth(
14365 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1514366 }
14367 if (rv == ERR_IO_PENDING)
14368 rv = callback.WaitForResult();
14369
14370 // Compare results with expected data.
asankae2257db2016-10-11 22:03:1614371 EXPECT_THAT(rv, IsError(read_write_round.expected_rv));
[email protected]0b0bf032010-09-21 18:08:5014372 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttlec0c828492015-05-15 01:25:5514373 if (read_write_round.expected_rv != OK) {
[email protected]044de0642010-06-17 10:42:1514374 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
14375 continue;
14376 }
14377 if (round + 1 < test_config.num_auth_rounds) {
wezca1070932016-05-26 20:30:5214378 EXPECT_TRUE(response->auth_challenge);
[email protected]044de0642010-06-17 10:42:1514379 } else {
wezca1070932016-05-26 20:30:5214380 EXPECT_FALSE(response->auth_challenge);
asankae2257db2016-10-11 22:03:1614381 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]044de0642010-06-17 10:42:1514382 }
14383 }
[email protected]e5ae96a2010-04-14 20:12:4514384 }
14385}
14386
bncd16676a2016-07-20 16:23:0114387TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1414388 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1414389 HttpAuthHandlerMock::Factory* auth_factory(
14390 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0714391 session_deps_.http_auth_handler_factory.reset(auth_factory);
Bence Béky53a5aef2018-03-29 21:54:1214392 session_deps_.proxy_resolution_service =
14393 ProxyResolutionService::CreateDirect();
[email protected]bb88e1d32013-05-03 23:11:0714394 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
[email protected]c871bce92010-07-15 21:51:1414395
14396 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
14397 auth_handler->set_connection_based(true);
14398 std::string auth_challenge = "Mock realm=server";
14399 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2414400 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
14401 auth_challenge.end());
asanka5ffd5d72016-03-23 16:20:4914402 SSLInfo empty_ssl_info;
[email protected]c871bce92010-07-15 21:51:1414403 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2014404 empty_ssl_info, origin, NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0814405 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1414406
[email protected]c871bce92010-07-15 21:51:1414407 int rv = OK;
Raul Tambre94493c652019-03-11 17:18:3514408 const HttpResponseInfo* response = nullptr;
[email protected]c871bce92010-07-15 21:51:1414409 HttpRequestInfo request;
14410 request.method = "GET";
14411 request.url = origin;
Ramin Halavatib5e433e2018-02-07 07:41:1014412 request.traffic_annotation =
14413 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2714414
danakj1fd259a02016-04-16 03:17:0914415 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1014416
14417 // Use a TCP Socket Pool with only one connection per group. This is used
14418 // to validate that the TCP socket is not released to the pool between
14419 // each round of multi-round authentication.
mmenkee65e7af2015-10-13 17:16:4214420 HttpNetworkSessionPeer session_peer(session.get());
Matt Menked6fd2a52019-03-20 06:14:3614421 CommonConnectJobParams common_connect_job_params(
14422 session->CreateCommonConnectJobParams());
[email protected]ab739042011-04-07 15:22:2814423 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
Tarun Bansala7635092019-02-20 10:00:5914424 50, // Max sockets for pool
14425 1, // Max sockets per group
14426 base::TimeDelta::FromSeconds(10), // unused_idle_socket_timeout
Matt Menked6fd2a52019-03-20 06:14:3614427 &common_connect_job_params, session_deps_.ssl_config_service.get());
Jeremy Roman0579ed62017-08-29 15:56:1914428 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
Matt Menked23ab952019-03-06 00:24:4014429 mock_pool_manager->SetSocketPool(ProxyServer::Direct(),
14430 base::WrapUnique(transport_pool));
dchengc7eeda422015-12-26 03:56:4814431 session_peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]7ef4cbbb2011-02-06 11:19:1014432
bnc691fda62016-08-12 00:43:1614433 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4114434 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1414435
14436 const MockWrite kGet(
14437 "GET / HTTP/1.1\r\n"
14438 "Host: www.example.com\r\n"
14439 "Connection: keep-alive\r\n\r\n");
14440 const MockWrite kGetAuth(
14441 "GET / HTTP/1.1\r\n"
14442 "Host: www.example.com\r\n"
14443 "Connection: keep-alive\r\n"
14444 "Authorization: auth_token\r\n\r\n");
14445
14446 const MockRead kServerChallenge(
14447 "HTTP/1.1 401 Unauthorized\r\n"
14448 "WWW-Authenticate: Mock realm=server\r\n"
14449 "Content-Type: text/html; charset=iso-8859-1\r\n"
14450 "Content-Length: 14\r\n\r\n"
14451 "Unauthorized\r\n");
14452 const MockRead kSuccess(
14453 "HTTP/1.1 200 OK\r\n"
14454 "Content-Type: text/html; charset=iso-8859-1\r\n"
14455 "Content-Length: 3\r\n\r\n"
14456 "Yes");
14457
14458 MockWrite writes[] = {
14459 // First round
14460 kGet,
14461 // Second round
14462 kGetAuth,
14463 // Third round
14464 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3014465 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1014466 kGetAuth,
14467 // Competing request
14468 kGet,
[email protected]c871bce92010-07-15 21:51:1414469 };
14470 MockRead reads[] = {
14471 // First round
14472 kServerChallenge,
14473 // Second round
14474 kServerChallenge,
14475 // Third round
[email protected]eca50e122010-09-11 14:03:3014476 kServerChallenge,
14477 // Fourth round
[email protected]c871bce92010-07-15 21:51:1414478 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1014479 // Competing response
14480 kSuccess,
[email protected]c871bce92010-07-15 21:51:1414481 };
Ryan Sleevib8d7ea02018-05-07 20:01:0114482 StaticSocketDataProvider data_provider(reads, writes);
[email protected]bb88e1d32013-05-03 23:11:0714483 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1414484
Matt Menkef6edce752019-03-19 17:21:5614485 const ClientSocketPool::GroupId kSocketGroup(
14486 HostPortPair("www.example.com", 80), ClientSocketPool::SocketType::kHttp,
14487 false /* privacy_mode */);
[email protected]7ef4cbbb2011-02-06 11:19:1014488
14489 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1414490 auth_handler->SetGenerateExpectation(false, OK);
tfarina42834112016-09-22 13:38:2014491 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]c871bce92010-07-15 21:51:1414492 if (rv == ERR_IO_PENDING)
14493 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114494 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1614495 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214496 ASSERT_TRUE(response);
14497 EXPECT_TRUE(response->auth_challenge);
Raul Tambre8335a6d2019-02-21 16:57:4314498 EXPECT_EQ(0u, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3114499 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
14500 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1414501
[email protected]7ef4cbbb2011-02-06 11:19:1014502 // In between rounds, another request comes in for the same domain.
14503 // It should not be able to grab the TCP socket that trans has already
14504 // claimed.
bnc691fda62016-08-12 00:43:1614505 HttpNetworkTransaction trans_compete(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4114506 TestCompletionCallback callback_compete;
tfarina42834112016-09-22 13:38:2014507 rv = trans_compete.Start(&request, callback_compete.callback(),
14508 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114509 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7ef4cbbb2011-02-06 11:19:1014510 // callback_compete.WaitForResult at this point would stall forever,
14511 // since the HttpNetworkTransaction does not release the request back to
14512 // the pool until after authentication completes.
14513
14514 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1414515 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1614516 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1414517 if (rv == ERR_IO_PENDING)
14518 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114519 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1614520 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214521 ASSERT_TRUE(response);
14522 EXPECT_FALSE(response->auth_challenge);
Raul Tambre8335a6d2019-02-21 16:57:4314523 EXPECT_EQ(0u, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3114524 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
14525 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1414526
[email protected]7ef4cbbb2011-02-06 11:19:1014527 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1414528 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1614529 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1414530 if (rv == ERR_IO_PENDING)
14531 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114532 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1614533 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214534 ASSERT_TRUE(response);
14535 EXPECT_FALSE(response->auth_challenge);
Raul Tambre8335a6d2019-02-21 16:57:4314536 EXPECT_EQ(0u, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3114537 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
14538 auth_handler->state());
[email protected]eca50e122010-09-11 14:03:3014539
[email protected]7ef4cbbb2011-02-06 11:19:1014540 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3014541 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1614542 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3014543 if (rv == ERR_IO_PENDING)
14544 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114545 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1614546 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214547 ASSERT_TRUE(response);
14548 EXPECT_FALSE(response->auth_challenge);
Raul Tambre8335a6d2019-02-21 16:57:4314549 EXPECT_EQ(0u, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1014550
asanka463ca4262016-11-16 02:34:3114551 // In WAIT_FOR_CHALLENGE, although in reality the auth handler is done. A real
14552 // auth handler should transition to a DONE state in concert with the remote
14553 // server. But that's not something we can test here with a mock handler.
14554 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_CHALLENGE,
14555 auth_handler->state());
14556
[email protected]7ef4cbbb2011-02-06 11:19:1014557 // Read the body since the fourth round was successful. This will also
14558 // release the socket back to the pool.
Victor Costan9c7302b2018-08-27 16:39:4414559 scoped_refptr<IOBufferWithSize> io_buf =
14560 base::MakeRefCounted<IOBufferWithSize>(50);
bnc691fda62016-08-12 00:43:1614561 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1014562 if (rv == ERR_IO_PENDING)
14563 rv = callback.WaitForResult();
14564 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1614565 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1014566 EXPECT_EQ(0, rv);
14567 // There are still 0 idle sockets, since the trans_compete transaction
14568 // will be handed it immediately after trans releases it to the group.
Raul Tambre8335a6d2019-02-21 16:57:4314569 EXPECT_EQ(0u, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1014570
14571 // The competing request can now finish. Wait for the headers and then
14572 // read the body.
14573 rv = callback_compete.WaitForResult();
robpercival214763f2016-07-01 23:27:0114574 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1614575 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1014576 if (rv == ERR_IO_PENDING)
14577 rv = callback.WaitForResult();
14578 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1614579 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1014580 EXPECT_EQ(0, rv);
14581
14582 // Finally, the socket is released to the group.
Raul Tambre8335a6d2019-02-21 16:57:4314583 EXPECT_EQ(1u, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1414584}
14585
[email protected]65041fa2010-05-21 06:56:5314586// This tests the case that a request is issued via http instead of spdy after
14587// npn is negotiated.
bncd16676a2016-07-20 16:23:0114588TEST_F(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]65041fa2010-05-21 06:56:5314589 HttpRequestInfo request;
14590 request.method = "GET";
bncce36dca22015-04-21 22:11:2314591 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1014592 request.traffic_annotation =
14593 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]65041fa2010-05-21 06:56:5314594
14595 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2314596 MockWrite(
14597 "GET / HTTP/1.1\r\n"
14598 "Host: www.example.org\r\n"
14599 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5314600 };
14601
14602 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5214603 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4314604 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5214605 MockRead("\r\n"),
14606 MockRead("hello world"),
14607 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5314608 };
14609
[email protected]8ddf8322012-02-23 18:08:0614610 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614611 ssl.next_proto = kProtoHTTP11;
[email protected]65041fa2010-05-21 06:56:5314612
[email protected]bb88e1d32013-05-03 23:11:0714613 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5314614
Ryan Sleevib8d7ea02018-05-07 20:01:0114615 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0714616 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5314617
[email protected]49639fa2011-12-20 23:22:4114618 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5314619
danakj1fd259a02016-04-16 03:17:0914620 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614621 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]65041fa2010-05-21 06:56:5314622
tfarina42834112016-09-22 13:38:2014623 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]65041fa2010-05-21 06:56:5314624
robpercival214763f2016-07-01 23:27:0114625 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14626 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]65041fa2010-05-21 06:56:5314627
bnc691fda62016-08-12 00:43:1614628 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214629 ASSERT_TRUE(response);
14630 ASSERT_TRUE(response->headers);
[email protected]65041fa2010-05-21 06:56:5314631 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
14632
14633 std::string response_data;
bnc691fda62016-08-12 00:43:1614634 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]65041fa2010-05-21 06:56:5314635 EXPECT_EQ("hello world", response_data);
14636
14637 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214638 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]65041fa2010-05-21 06:56:5314639}
[email protected]26ef6582010-06-24 02:30:4714640
bnc55ff9da2015-08-19 18:42:3514641// Simulate the SSL handshake completing with an NPN negotiation followed by an
14642// immediate server closing of the socket.
14643// Regression test for https://crbug.com/46369.
bncd16676a2016-07-20 16:23:0114644TEST_F(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:4714645 HttpRequestInfo request;
14646 request.method = "GET";
bncce36dca22015-04-21 22:11:2314647 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1014648 request.traffic_annotation =
14649 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]26ef6582010-06-24 02:30:4714650
[email protected]8ddf8322012-02-23 18:08:0614651 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614652 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0714653 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4714654
Ryan Hamilton0239aac2018-05-19 00:03:1314655 spdy::SpdySerializedFrame req(
14656 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4114657 MockWrite spdy_writes[] = {CreateMockWrite(req, 1)};
[email protected]26ef6582010-06-24 02:30:4714658
14659 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0614660 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4714661 };
14662
Ryan Sleevib8d7ea02018-05-07 20:01:0114663 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0714664 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4714665
[email protected]49639fa2011-12-20 23:22:4114666 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4714667
danakj1fd259a02016-04-16 03:17:0914668 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614669 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]26ef6582010-06-24 02:30:4714670
tfarina42834112016-09-22 13:38:2014671 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114672 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14673 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]26ef6582010-06-24 02:30:4714674}
[email protected]65d34382010-07-01 18:12:2614675
[email protected]795cbf82013-07-22 09:37:2714676// A subclass of HttpAuthHandlerMock that records the request URL when
14677// it gets it. This is needed since the auth handler may get destroyed
14678// before we get a chance to query it.
14679class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
14680 public:
14681 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
14682
Chris Watkins7a41d3552017-12-01 02:13:2714683 ~UrlRecordingHttpAuthHandlerMock() override = default;
[email protected]795cbf82013-07-22 09:37:2714684
14685 protected:
dchengb03027d2014-10-21 12:00:2014686 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
14687 const HttpRequestInfo* request,
Bence Béky7236fb72018-08-01 14:35:0914688 CompletionOnceCallback callback,
dchengb03027d2014-10-21 12:00:2014689 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2714690 *url_ = request->url;
14691 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
Bence Béky7236fb72018-08-01 14:35:0914692 credentials, request, std::move(callback), auth_token);
[email protected]795cbf82013-07-22 09:37:2714693 }
14694
14695 private:
14696 GURL* url_;
14697};
14698
[email protected]8e6441ca2010-08-19 05:56:3814699// Test that if we cancel the transaction as the connection is completing, that
14700// everything tears down correctly.
bncd16676a2016-07-20 16:23:0114701TEST_F(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3814702 // Setup everything about the connection to complete synchronously, so that
14703 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
14704 // for is the callback from the HttpStreamRequest.
14705 // Then cancel the transaction.
14706 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3614707 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3814708 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0614709 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
14710 MockRead(SYNCHRONOUS, "hello world"),
14711 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3814712 };
14713
[email protected]8e6441ca2010-08-19 05:56:3814714 HttpRequestInfo request;
14715 request.method = "GET";
bncce36dca22015-04-21 22:11:2314716 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1014717 request.traffic_annotation =
14718 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8e6441ca2010-08-19 05:56:3814719
danakj1fd259a02016-04-16 03:17:0914720 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5814721 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1914722 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2714723
Ryan Sleevib8d7ea02018-05-07 20:01:0114724 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]8e6441ca2010-08-19 05:56:3814725 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0714726 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3814727
[email protected]49639fa2011-12-20 23:22:4114728 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3814729
vishal.b62985ca92015-04-17 08:45:5114730 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4114731 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114732 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8e6441ca2010-08-19 05:56:3814733 trans.reset(); // Cancel the transaction here.
14734
fdoray92e35a72016-06-10 15:54:5514735 base::RunLoop().RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3014736}
14737
[email protected]ecab6e052014-05-16 14:58:1214738// Test that if a transaction is cancelled after receiving the headers, the
14739// stream is drained properly and added back to the socket pool. The main
14740// purpose of this test is to make sure that an HttpStreamParser can be read
14741// from after the HttpNetworkTransaction and the objects it owns have been
14742// deleted.
14743// See http://crbug.com/368418
bncd16676a2016-07-20 16:23:0114744TEST_F(HttpNetworkTransactionTest, CancelAfterHeaders) {
[email protected]ecab6e052014-05-16 14:58:1214745 MockRead data_reads[] = {
14746 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
14747 MockRead(ASYNC, "Content-Length: 2\r\n"),
14748 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
14749 MockRead(ASYNC, "1"),
14750 // 2 async reads are necessary to trigger a ReadResponseBody call after the
14751 // HttpNetworkTransaction has been deleted.
14752 MockRead(ASYNC, "2"),
14753 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
14754 };
Ryan Sleevib8d7ea02018-05-07 20:01:0114755 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]ecab6e052014-05-16 14:58:1214756 session_deps_.socket_factory->AddSocketDataProvider(&data);
14757
danakj1fd259a02016-04-16 03:17:0914758 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]ecab6e052014-05-16 14:58:1214759
14760 {
14761 HttpRequestInfo request;
14762 request.method = "GET";
bncce36dca22015-04-21 22:11:2314763 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1014764 request.traffic_annotation =
14765 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ecab6e052014-05-16 14:58:1214766
dcheng48459ac22014-08-26 00:46:4114767 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1214768 TestCompletionCallback callback;
14769
tfarina42834112016-09-22 13:38:2014770 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114771 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ecab6e052014-05-16 14:58:1214772 callback.WaitForResult();
14773
14774 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214775 ASSERT_TRUE(response);
14776 EXPECT_TRUE(response->headers);
[email protected]ecab6e052014-05-16 14:58:1214777 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
14778
14779 // The transaction and HttpRequestInfo are deleted.
14780 }
14781
14782 // Let the HttpResponseBodyDrainer drain the socket.
fdoray92e35a72016-06-10 15:54:5514783 base::RunLoop().RunUntilIdle();
[email protected]ecab6e052014-05-16 14:58:1214784
14785 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4114786 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1214787}
14788
[email protected]76a505b2010-08-25 06:23:0014789// Test a basic GET request through a proxy.
bncd16676a2016-07-20 16:23:0114790TEST_F(HttpNetworkTransactionTest, ProxyGet) {
Lily Houghton8c2f97d2018-01-22 05:06:5914791 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4914792 ProxyResolutionService::CreateFixedFromPacResult(
14793 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5114794 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714795 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0914796 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0014797
[email protected]76a505b2010-08-25 06:23:0014798 HttpRequestInfo request;
14799 request.method = "GET";
bncce36dca22015-04-21 22:11:2314800 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1014801 request.traffic_annotation =
14802 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0014803
14804 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2314805 MockWrite(
14806 "GET http://www.example.org/ HTTP/1.1\r\n"
14807 "Host: www.example.org\r\n"
14808 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014809 };
14810
14811 MockRead data_reads1[] = {
14812 MockRead("HTTP/1.1 200 OK\r\n"),
14813 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14814 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0614815 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0014816 };
14817
Ryan Sleevib8d7ea02018-05-07 20:01:0114818 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:0714819 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0014820
[email protected]49639fa2011-12-20 23:22:4114821 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0014822
bnc691fda62016-08-12 00:43:1614823 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0914824 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1614825 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0914826 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
14827 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5014828
bnc691fda62016-08-12 00:43:1614829 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114830 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0014831
14832 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0114833 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:0014834
bnc691fda62016-08-12 00:43:1614835 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214836 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0014837
14838 EXPECT_TRUE(response->headers->IsKeepAlive());
14839 EXPECT_EQ(200, response->headers->response_code());
14840 EXPECT_EQ(100, response->headers->GetContentLength());
14841 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4714842 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
14843 HostPortPair::FromString("myproxy:70")),
14844 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0914845 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
14846 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
14847 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0014848 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2014849
14850 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1614851 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2014852 TestLoadTimingNotReusedWithPac(load_timing_info,
14853 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0014854}
14855
14856// Test a basic HTTPS GET request through a proxy.
bncd16676a2016-07-20 16:23:0114857TEST_F(HttpNetworkTransactionTest, ProxyTunnelGet) {
Lily Houghton8c2f97d2018-01-22 05:06:5914858 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4914859 ProxyResolutionService::CreateFixedFromPacResult(
14860 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5114861 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714862 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0914863 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0014864
[email protected]76a505b2010-08-25 06:23:0014865 HttpRequestInfo request;
14866 request.method = "GET";
bncce36dca22015-04-21 22:11:2314867 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1014868 request.traffic_annotation =
14869 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0014870
14871 // Since we have proxy, should try to establish tunnel.
14872 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1714873 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
14874 "Host: www.example.org:443\r\n"
14875 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014876
rsleevidb16bb02015-11-12 23:47:1714877 MockWrite("GET / HTTP/1.1\r\n"
14878 "Host: www.example.org\r\n"
14879 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014880 };
14881
14882 MockRead data_reads1[] = {
14883 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
14884
14885 MockRead("HTTP/1.1 200 OK\r\n"),
14886 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14887 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0614888 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0014889 };
14890
Ryan Sleevib8d7ea02018-05-07 20:01:0114891 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:0714892 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0614893 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0714894 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0014895
[email protected]49639fa2011-12-20 23:22:4114896 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0014897
bnc691fda62016-08-12 00:43:1614898 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0914899 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1614900 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0914901 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
14902 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5014903
bnc691fda62016-08-12 00:43:1614904 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114905 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0014906
14907 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0114908 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:4614909 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4014910 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0014911 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014912 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
14913 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0014914 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4014915 entries, pos,
mikecirone8b85c432016-09-08 19:11:0014916 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
14917 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0014918
bnc691fda62016-08-12 00:43:1614919 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214920 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0014921
14922 EXPECT_TRUE(response->headers->IsKeepAlive());
14923 EXPECT_EQ(200, response->headers->response_code());
14924 EXPECT_EQ(100, response->headers->GetContentLength());
14925 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
14926 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4714927 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
14928 HostPortPair::FromString("myproxy:70")),
14929 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0914930 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
14931 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
14932 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]029c83b62013-01-24 05:28:2014933
14934 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1614935 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2014936 TestLoadTimingNotReusedWithPac(load_timing_info,
14937 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0014938}
14939
rsleevidb16bb02015-11-12 23:47:1714940// Test a basic HTTPS GET request through a proxy, connecting to an IPv6
14941// literal host.
bncd16676a2016-07-20 16:23:0114942TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetIPv6) {
Lily Houghton8c2f97d2018-01-22 05:06:5914943 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4914944 ProxyResolutionService::CreateFixedFromPacResult(
14945 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
rsleevidb16bb02015-11-12 23:47:1714946 BoundTestNetLog log;
14947 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0914948 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
rsleevidb16bb02015-11-12 23:47:1714949
14950 HttpRequestInfo request;
14951 request.method = "GET";
Eric Romanda790f92018-11-07 19:17:1514952 request.url = GURL("https://[::2]:443/");
Ramin Halavatib5e433e2018-02-07 07:41:1014953 request.traffic_annotation =
14954 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rsleevidb16bb02015-11-12 23:47:1714955
14956 // Since we have proxy, should try to establish tunnel.
14957 MockWrite data_writes1[] = {
Eric Romanda790f92018-11-07 19:17:1514958 MockWrite("CONNECT [::2]:443 HTTP/1.1\r\n"
14959 "Host: [::2]:443\r\n"
rsleevidb16bb02015-11-12 23:47:1714960 "Proxy-Connection: keep-alive\r\n\r\n"),
14961
14962 MockWrite("GET / HTTP/1.1\r\n"
Eric Romanda790f92018-11-07 19:17:1514963 "Host: [::2]\r\n"
rsleevidb16bb02015-11-12 23:47:1714964 "Connection: keep-alive\r\n\r\n"),
14965 };
14966
14967 MockRead data_reads1[] = {
14968 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
14969
14970 MockRead("HTTP/1.1 200 OK\r\n"),
14971 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14972 MockRead("Content-Length: 100\r\n\r\n"),
14973 MockRead(SYNCHRONOUS, OK),
14974 };
14975
Ryan Sleevib8d7ea02018-05-07 20:01:0114976 StaticSocketDataProvider data1(data_reads1, data_writes1);
rsleevidb16bb02015-11-12 23:47:1714977 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14978 SSLSocketDataProvider ssl(ASYNC, OK);
14979 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14980
14981 TestCompletionCallback callback1;
14982
bnc691fda62016-08-12 00:43:1614983 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
rsleevidb16bb02015-11-12 23:47:1714984
bnc691fda62016-08-12 00:43:1614985 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114986 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rsleevidb16bb02015-11-12 23:47:1714987
14988 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0114989 EXPECT_THAT(rv, IsOk());
rsleevidb16bb02015-11-12 23:47:1714990 TestNetLogEntry::List entries;
14991 log.GetEntries(&entries);
14992 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014993 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
14994 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1714995 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014996 entries, pos,
14997 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
14998 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1714999
bnc691fda62016-08-12 00:43:1615000 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5215001 ASSERT_TRUE(response);
rsleevidb16bb02015-11-12 23:47:1715002
15003 EXPECT_TRUE(response->headers->IsKeepAlive());
15004 EXPECT_EQ(200, response->headers->response_code());
15005 EXPECT_EQ(100, response->headers->GetContentLength());
15006 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
15007 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4715008 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
15009 HostPortPair::FromString("myproxy:70")),
15010 response->proxy_server);
rsleevidb16bb02015-11-12 23:47:1715011
15012 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1615013 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
rsleevidb16bb02015-11-12 23:47:1715014 TestLoadTimingNotReusedWithPac(load_timing_info,
15015 CONNECT_TIMING_HAS_SSL_TIMES);
15016}
15017
[email protected]76a505b2010-08-25 06:23:0015018// Test a basic HTTPS GET request through a proxy, but the server hangs up
15019// while establishing the tunnel.
bncd16676a2016-07-20 16:23:0115020TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
Ramin Halavatica8d5252018-03-12 05:33:4915021 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
15022 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5115023 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0715024 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0915025 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0015026
[email protected]76a505b2010-08-25 06:23:0015027 HttpRequestInfo request;
15028 request.method = "GET";
bncce36dca22015-04-21 22:11:2315029 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1015030 request.traffic_annotation =
15031 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0015032
15033 // Since we have proxy, should try to establish tunnel.
15034 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1715035 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
15036 "Host: www.example.org:443\r\n"
15037 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0015038
rsleevidb16bb02015-11-12 23:47:1715039 MockWrite("GET / HTTP/1.1\r\n"
15040 "Host: www.example.org\r\n"
15041 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0015042 };
15043
15044 MockRead data_reads1[] = {
[email protected]76a505b2010-08-25 06:23:0015045 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0615046 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0015047 };
15048
Ryan Sleevib8d7ea02018-05-07 20:01:0115049 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:0715050 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0615051 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0715052 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0015053
[email protected]49639fa2011-12-20 23:22:4115054 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0015055
bnc691fda62016-08-12 00:43:1615056 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5015057
bnc691fda62016-08-12 00:43:1615058 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0115059 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0015060
15061 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0115062 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
mmenke43758e62015-05-04 21:09:4615063 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4015064 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0015065 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0015066 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
15067 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0015068 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4015069 entries, pos,
mikecirone8b85c432016-09-08 19:11:0015070 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
15071 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0015072}
15073
[email protected]749eefa82010-09-13 22:14:0315074// Test for crbug.com/55424.
bncd16676a2016-07-20 16:23:0115075TEST_F(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
Ryan Hamilton0239aac2018-05-19 00:03:1315076 spdy::SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4915077 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4115078 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]749eefa82010-09-13 22:14:0315079
Raul Tambre94493c652019-03-11 17:18:3515080 spdy::SpdySerializedFrame resp(
15081 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1315082 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0315083 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115084 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0315085 };
15086
Ryan Sleevib8d7ea02018-05-07 20:01:0115087 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0715088 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0315089
[email protected]8ddf8322012-02-23 18:08:0615090 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615091 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0715092 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0315093
danakj1fd259a02016-04-16 03:17:0915094 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0315095
15096 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2315097 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4015098 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
Matt Menke2436b2f2018-12-11 18:07:1115099 PRIVACY_MODE_DISABLED,
15100 SpdySessionKey::IsProxySession::kFalse, SocketTag());
[email protected]795cbf82013-07-22 09:37:2715101 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:5215102 CreateSpdySession(session.get(), key, NetLogWithSource());
[email protected]749eefa82010-09-13 22:14:0315103
15104 HttpRequestInfo request;
15105 request.method = "GET";
bncce36dca22015-04-21 22:11:2315106 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1015107 request.traffic_annotation =
15108 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]749eefa82010-09-13 22:14:0315109
bnc691fda62016-08-12 00:43:1615110 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]749eefa82010-09-13 22:14:0315111
[email protected]41d64e82013-07-03 22:44:2615112 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2015113 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115114 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15115 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]749eefa82010-09-13 22:14:0315116}
15117
[email protected]73b8dd222010-11-11 19:55:2415118// Given a net error, cause that error to be returned from the first Write()
bnc691fda62016-08-12 00:43:1615119// call and verify that the HttpNetworkTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0215120void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0715121 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2915122 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2715123 request_info.url = GURL("https://www.example.com/");
15124 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2915125 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:1015126 request_info.traffic_annotation =
15127 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2715128
[email protected]8ddf8322012-02-23 18:08:0615129 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2915130 MockWrite data_writes[] = {
15131 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2415132 };
Ryan Sleevib8d7ea02018-05-07 20:01:0115133 StaticSocketDataProvider data(base::span<MockRead>(), data_writes);
[email protected]bb88e1d32013-05-03 23:11:0715134 session_deps_.socket_factory->AddSocketDataProvider(&data);
15135 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2415136
danakj1fd259a02016-04-16 03:17:0915137 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615138 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]73b8dd222010-11-11 19:55:2415139
[email protected]49639fa2011-12-20 23:22:4115140 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2015141 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
ttuttle859dc7a2015-04-23 19:42:2915142 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2415143 rv = callback.WaitForResult();
15144 ASSERT_EQ(error, rv);
15145}
15146
bncd16676a2016-07-20 16:23:0115147TEST_F(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2415148 // Just check a grab bag of cert errors.
15149 static const int kErrors[] = {
15150 ERR_CERT_COMMON_NAME_INVALID,
15151 ERR_CERT_AUTHORITY_INVALID,
15152 ERR_CERT_DATE_INVALID,
15153 };
Avi Drissman4365a4782018-12-28 19:26:2415154 for (size_t i = 0; i < base::size(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0615155 CheckErrorIsPassedBack(kErrors[i], ASYNC);
15156 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2415157 }
15158}
15159
[email protected]bd0b6772011-01-11 19:59:3015160// Ensure that a client certificate is removed from the SSL client auth
15161// cache when:
15162// 1) No proxy is involved.
15163// 2) TLS False Start is disabled.
15164// 3) The initial TLS handshake requests a client certificate.
15165// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0115166TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_NoFalseStart) {
ttuttle859dc7a2015-04-23 19:42:2915167 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2715168 request_info.url = GURL("https://www.example.com/");
15169 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2915170 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:1015171 request_info.traffic_annotation =
15172 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2715173
[email protected]bd0b6772011-01-11 19:59:3015174 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4115175 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3015176
15177 // [ssl_]data1 contains the data for the first SSL handshake. When a
15178 // CertificateRequest is received for the first time, the handshake will
15179 // be aborted to allow the caller to provide a certificate.
ttuttle859dc7a2015-04-23 19:42:2915180 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3015181 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715182 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
Ryan Sleevib8d7ea02018-05-07 20:01:0115183 StaticSocketDataProvider data1;
[email protected]bb88e1d32013-05-03 23:11:0715184 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3015185
15186 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
15187 // False Start is not being used, the result of the SSL handshake will be
15188 // returned as part of the SSLClientSocket::Connect() call. This test
15189 // matches the result of a server sending a handshake_failure alert,
15190 // rather than a Finished message, because it requires a client
15191 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2915192 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3015193 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715194 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
Ryan Sleevib8d7ea02018-05-07 20:01:0115195 StaticSocketDataProvider data2;
[email protected]bb88e1d32013-05-03 23:11:0715196 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3015197
15198 // [ssl_]data3 contains the data for the third SSL handshake. When a
15199 // connection to a server fails during an SSL handshake,
Steven Valdez0ef94d02018-11-19 23:28:1315200 // HttpNetworkTransaction will attempt to fallback to TLSv1.2 if the previous
15201 // connection was attempted with TLSv1.3. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3015202 // of the HttpNetworkTransaction. Because this test failure is due to
15203 // requiring a client certificate, this fallback handshake should also
15204 // fail.
ttuttle859dc7a2015-04-23 19:42:2915205 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
Steven Valdez0ef94d02018-11-19 23:28:1315206 ssl_data3.expected_ssl_version_max = SSL_PROTOCOL_VERSION_TLS1_2;
[email protected]bd0b6772011-01-11 19:59:3015207 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715208 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
Ryan Sleevib8d7ea02018-05-07 20:01:0115209 StaticSocketDataProvider data3;
[email protected]bb88e1d32013-05-03 23:11:0715210 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3015211
[email protected]80c75f682012-05-26 16:22:1715212 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
15213 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4215214 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
15215 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]80c75f682012-05-26 16:22:1715216 // of the HttpNetworkTransaction. Because this test failure is due to
15217 // requiring a client certificate, this fallback handshake should also
15218 // fail.
ttuttle859dc7a2015-04-23 19:42:2915219 SSLSocketDataProvider ssl_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1715220 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715221 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
Ryan Sleevib8d7ea02018-05-07 20:01:0115222 StaticSocketDataProvider data4;
[email protected]bb88e1d32013-05-03 23:11:0715223 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1715224
danakj1fd259a02016-04-16 03:17:0915225 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615226 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3015227
[email protected]bd0b6772011-01-11 19:59:3015228 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4115229 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2015230 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115231 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3015232
15233 // Complete the SSL handshake, which should abort due to requiring a
15234 // client certificate.
15235 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115236 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3015237
15238 // Indicate that no certificate should be supplied. From the perspective
15239 // of SSLClientCertCache, NULL is just as meaningful as a real
15240 // certificate, so this is the same as supply a
15241 // legitimate-but-unacceptable certificate.
Raul Tambre94493c652019-03-11 17:18:3515242 rv = trans.RestartWithCertificate(nullptr, nullptr, callback.callback());
robpercival214763f2016-07-01 23:27:0115243 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3015244
15245 // Ensure the certificate was added to the client auth cache before
15246 // allowing the connection to continue restarting.
15247 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5415248 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4115249 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415250 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5215251 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3015252
15253 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1715254 // then consume ssl_data3 and ssl_data4, both of which should also fail.
15255 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3015256 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115257 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3015258
15259 // Ensure that the client certificate is removed from the cache on a
15260 // handshake failure.
[email protected]791879c2013-12-17 07:22:4115261 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415262 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3015263}
15264
15265// Ensure that a client certificate is removed from the SSL client auth
15266// cache when:
15267// 1) No proxy is involved.
15268// 2) TLS False Start is enabled.
15269// 3) The initial TLS handshake requests a client certificate.
15270// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0115271TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2915272 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2715273 request_info.url = GURL("https://www.example.com/");
15274 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2915275 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:1015276 request_info.traffic_annotation =
15277 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2715278
[email protected]bd0b6772011-01-11 19:59:3015279 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4115280 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3015281
15282 // When TLS False Start is used, SSLClientSocket::Connect() calls will
15283 // return successfully after reading up to the peer's Certificate message.
15284 // This is to allow the caller to call SSLClientSocket::Write(), which can
15285 // enqueue application data to be sent in the same packet as the
15286 // ChangeCipherSpec and Finished messages.
15287 // The actual handshake will be finished when SSLClientSocket::Read() is
15288 // called, which expects to process the peer's ChangeCipherSpec and
15289 // Finished messages. If there was an error negotiating with the peer,
15290 // such as due to the peer requiring a client certificate when none was
15291 // supplied, the alert sent by the peer won't be processed until Read() is
15292 // called.
15293
15294 // Like the non-False Start case, when a client certificate is requested by
15295 // the peer, the handshake is aborted during the Connect() call.
15296 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2915297 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3015298 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715299 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
Ryan Sleevib8d7ea02018-05-07 20:01:0115300 StaticSocketDataProvider data1;
[email protected]bb88e1d32013-05-03 23:11:0715301 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3015302
15303 // When a client certificate is supplied, Connect() will not be aborted
15304 // when the peer requests the certificate. Instead, the handshake will
15305 // artificially succeed, allowing the caller to write the HTTP request to
15306 // the socket. The handshake messages are not processed until Read() is
15307 // called, which then detects that the handshake was aborted, due to the
15308 // peer sending a handshake_failure because it requires a client
15309 // certificate.
ttuttle859dc7a2015-04-23 19:42:2915310 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3015311 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715312 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2915313 MockRead data2_reads[] = {
15314 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3015315 };
Ryan Sleevib8d7ea02018-05-07 20:01:0115316 StaticSocketDataProvider data2(data2_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0715317 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3015318
15319 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1715320 // the data for the SSL handshake once the TLSv1.1 connection falls back to
15321 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2915322 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3015323 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715324 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
Ryan Sleevib8d7ea02018-05-07 20:01:0115325 StaticSocketDataProvider data3(data2_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0715326 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3015327
[email protected]80c75f682012-05-26 16:22:1715328 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
15329 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2915330 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1715331 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715332 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
Ryan Sleevib8d7ea02018-05-07 20:01:0115333 StaticSocketDataProvider data4(data2_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0715334 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1715335
[email protected]7799de12013-05-30 05:52:5115336 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2915337 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5115338 ssl_data5.cert_request_info = cert_request.get();
15339 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
Ryan Sleevib8d7ea02018-05-07 20:01:0115340 StaticSocketDataProvider data5(data2_reads, base::span<MockWrite>());
[email protected]7799de12013-05-30 05:52:5115341 session_deps_.socket_factory->AddSocketDataProvider(&data5);
15342
danakj1fd259a02016-04-16 03:17:0915343 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615344 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3015345
[email protected]bd0b6772011-01-11 19:59:3015346 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4115347 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2015348 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115349 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3015350
15351 // Complete the SSL handshake, which should abort due to requiring a
15352 // client certificate.
15353 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115354 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3015355
15356 // Indicate that no certificate should be supplied. From the perspective
15357 // of SSLClientCertCache, NULL is just as meaningful as a real
15358 // certificate, so this is the same as supply a
15359 // legitimate-but-unacceptable certificate.
Raul Tambre94493c652019-03-11 17:18:3515360 rv = trans.RestartWithCertificate(nullptr, nullptr, callback.callback());
robpercival214763f2016-07-01 23:27:0115361 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3015362
15363 // Ensure the certificate was added to the client auth cache before
15364 // allowing the connection to continue restarting.
15365 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5415366 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4115367 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415368 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5215369 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3015370
[email protected]bd0b6772011-01-11 19:59:3015371 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1715372 // then consume ssl_data3 and ssl_data4, both of which should also fail.
15373 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3015374 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115375 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3015376
15377 // Ensure that the client certificate is removed from the cache on a
15378 // handshake failure.
[email protected]791879c2013-12-17 07:22:4115379 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415380 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3015381}
15382
[email protected]8c405132011-01-11 22:03:1815383// Ensure that a client certificate is removed from the SSL client auth
15384// cache when:
15385// 1) An HTTPS proxy is involved.
15386// 3) The HTTPS proxy requests a client certificate.
15387// 4) The client supplies an invalid/unacceptable certificate for the
15388// proxy.
15389// The test is repeated twice, first for connecting to an HTTPS endpoint,
15390// then for connecting to an HTTP endpoint.
bncd16676a2016-07-20 16:23:0115391TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
Ramin Halavatica8d5252018-03-12 05:33:4915392 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
15393 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5115394 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0715395 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1815396
15397 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4115398 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1815399
15400 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
15401 // [ssl_]data[1-3]. Rather than represending the endpoint
15402 // (www.example.com:443), they represent failures with the HTTPS proxy
15403 // (proxy:70).
ttuttle859dc7a2015-04-23 19:42:2915404 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1815405 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715406 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
Ryan Sleevib8d7ea02018-05-07 20:01:0115407 StaticSocketDataProvider data1;
[email protected]bb88e1d32013-05-03 23:11:0715408 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1815409
ttuttle859dc7a2015-04-23 19:42:2915410 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1815411 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715412 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
Ryan Sleevib8d7ea02018-05-07 20:01:0115413 StaticSocketDataProvider data2;
[email protected]bb88e1d32013-05-03 23:11:0715414 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1815415
[email protected]80c75f682012-05-26 16:22:1715416 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
15417#if 0
ttuttle859dc7a2015-04-23 19:42:2915418 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1815419 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715420 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
Ryan Sleevib8d7ea02018-05-07 20:01:0115421 StaticSocketDataProvider data3;
[email protected]bb88e1d32013-05-03 23:11:0715422 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1715423#endif
[email protected]8c405132011-01-11 22:03:1815424
ttuttle859dc7a2015-04-23 19:42:2915425 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1815426 requests[0].url = GURL("https://www.example.com/");
15427 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2915428 requests[0].load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:1015429 requests[0].traffic_annotation =
15430 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c405132011-01-11 22:03:1815431
15432 requests[1].url = GURL("http://www.example.com/");
15433 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2915434 requests[1].load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:1015435 requests[1].traffic_annotation =
15436 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c405132011-01-11 22:03:1815437
Avi Drissman4365a4782018-12-28 19:26:2415438 for (size_t i = 0; i < base::size(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0715439 session_deps_.socket_factory->ResetNextMockIndexes();
danakj1fd259a02016-04-16 03:17:0915440 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615441 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]8c405132011-01-11 22:03:1815442
15443 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4115444 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2015445 int rv = trans.Start(&requests[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115446 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1815447
15448 // Complete the SSL handshake, which should abort due to requiring a
15449 // client certificate.
15450 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115451 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]8c405132011-01-11 22:03:1815452
15453 // Indicate that no certificate should be supplied. From the perspective
15454 // of SSLClientCertCache, NULL is just as meaningful as a real
15455 // certificate, so this is the same as supply a
15456 // legitimate-but-unacceptable certificate.
Raul Tambre94493c652019-03-11 17:18:3515457 rv = trans.RestartWithCertificate(nullptr, nullptr, callback.callback());
robpercival214763f2016-07-01 23:27:0115458 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1815459
15460 // Ensure the certificate was added to the client auth cache before
15461 // allowing the connection to continue restarting.
15462 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5415463 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4115464 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415465 HostPortPair("proxy", 70), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5215466 ASSERT_FALSE(client_cert);
[email protected]8c405132011-01-11 22:03:1815467 // Ensure the certificate was NOT cached for the endpoint. This only
15468 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4115469 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415470 HostPortPair("www.example.com", 443), &client_cert,
15471 &client_private_key));
[email protected]8c405132011-01-11 22:03:1815472
15473 // Restart the handshake. This will consume ssl_data2, which fails, and
15474 // then consume ssl_data3, which should also fail. The result code is
15475 // checked against what ssl_data3 should return.
15476 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115477 ASSERT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]8c405132011-01-11 22:03:1815478
15479 // Now that the new handshake has failed, ensure that the client
15480 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4115481 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415482 HostPortPair("proxy", 70), &client_cert, &client_private_key));
[email protected]791879c2013-12-17 07:22:4115483 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415484 HostPortPair("www.example.com", 443), &client_cert,
15485 &client_private_key));
[email protected]8c405132011-01-11 22:03:1815486 }
15487}
15488
bncd16676a2016-07-20 16:23:0115489TEST_F(HttpNetworkTransactionTest, UseIPConnectionPooling) {
[email protected]e3ceb682011-06-28 23:55:4615490 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1915491 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0915492 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4615493
bnc032658ba2016-09-26 18:17:1515494 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4615495
Ryan Hamilton0239aac2018-05-19 00:03:1315496 spdy::SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4915497 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3815498 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1315499 spdy::SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3715500 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4615501 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115502 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4615503 };
Ryan Hamilton0239aac2018-05-19 00:03:1315504 spdy::SpdySerializedFrame host1_resp(
Raul Tambre94493c652019-03-11 17:18:3515505 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1315506 spdy::SpdySerializedFrame host1_resp_body(
bncdf80d44fd2016-07-15 20:27:4115507 spdy_util_.ConstructSpdyDataFrame(1, true));
Ryan Hamilton0239aac2018-05-19 00:03:1315508 spdy::SpdySerializedFrame host2_resp(
Raul Tambre94493c652019-03-11 17:18:3515509 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
Ryan Hamilton0239aac2018-05-19 00:03:1315510 spdy::SpdySerializedFrame host2_resp_body(
bncdf80d44fd2016-07-15 20:27:4115511 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4615512 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115513 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
15514 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1315515 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4615516 };
15517
eroman36d84e54432016-03-17 03:23:0215518 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0215519 MockConnect connect(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115520 SequencedSocketData spdy_data(connect, spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0715521 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4615522
[email protected]aa22b242011-11-16 18:58:2915523 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4615524 HttpRequestInfo request1;
15525 request1.method = "GET";
bncce36dca22015-04-21 22:11:2315526 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4615527 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015528 request1.traffic_annotation =
15529 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015530 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4615531
tfarina42834112016-09-22 13:38:2015532 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115533 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15534 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615535
15536 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5215537 ASSERT_TRUE(response);
15538 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215539 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4615540
15541 std::string response_data;
robpercival214763f2016-07-01 23:27:0115542 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615543 EXPECT_EQ("hello!", response_data);
15544
bnca4d611d2016-09-22 19:55:3715545 // Preload mail.example.com into HostCache.
Eric Orthf4db66a2019-02-19 21:35:3315546 rv = session_deps_.host_resolver->LoadIntoCache(
15547 HostPortPair("mail.example.com", 443), base::nullopt);
robpercival214763f2016-07-01 23:27:0115548 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4615549
15550 HttpRequestInfo request2;
15551 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3715552 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4615553 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015554 request2.traffic_annotation =
15555 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015556 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4615557
tfarina42834112016-09-22 13:38:2015558 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115559 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15560 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615561
15562 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215563 ASSERT_TRUE(response);
15564 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215565 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4615566 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215567 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115568 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615569 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4615570}
15571
bncd16676a2016-07-20 16:23:0115572TEST_F(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d2b5f092012-06-08 23:55:0215573 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1915574 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0915575 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0215576
bnc032658ba2016-09-26 18:17:1515577 AddSSLSocketData();
[email protected]d2b5f092012-06-08 23:55:0215578
Ryan Hamilton0239aac2018-05-19 00:03:1315579 spdy::SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4915580 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3815581 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1315582 spdy::SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3715583 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0215584 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115585 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0215586 };
Ryan Hamilton0239aac2018-05-19 00:03:1315587 spdy::SpdySerializedFrame host1_resp(
Raul Tambre94493c652019-03-11 17:18:3515588 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1315589 spdy::SpdySerializedFrame host1_resp_body(
bncdf80d44fd2016-07-15 20:27:4115590 spdy_util_.ConstructSpdyDataFrame(1, true));
Ryan Hamilton0239aac2018-05-19 00:03:1315591 spdy::SpdySerializedFrame host2_resp(
Raul Tambre94493c652019-03-11 17:18:3515592 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
Ryan Hamilton0239aac2018-05-19 00:03:1315593 spdy::SpdySerializedFrame host2_resp_body(
bncdf80d44fd2016-07-15 20:27:4115594 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0215595 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115596 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
15597 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1315598 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0215599 };
15600
eroman36d84e54432016-03-17 03:23:0215601 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0215602 MockConnect connect(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115603 SequencedSocketData spdy_data(connect, spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0715604 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0215605
15606 TestCompletionCallback callback;
15607 HttpRequestInfo request1;
15608 request1.method = "GET";
bncce36dca22015-04-21 22:11:2315609 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0215610 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015611 request1.traffic_annotation =
15612 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015613 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0215614
tfarina42834112016-09-22 13:38:2015615 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115616 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15617 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0215618
15619 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5215620 ASSERT_TRUE(response);
15621 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215622 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0215623
15624 std::string response_data;
robpercival214763f2016-07-01 23:27:0115625 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0215626 EXPECT_EQ("hello!", response_data);
15627
15628 HttpRequestInfo request2;
15629 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3715630 request2.url = GURL("https://mail.example.com/");
[email protected]d2b5f092012-06-08 23:55:0215631 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015632 request2.traffic_annotation =
15633 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015634 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0215635
tfarina42834112016-09-22 13:38:2015636 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115637 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15638 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0215639
15640 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215641 ASSERT_TRUE(response);
15642 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215643 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0215644 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215645 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115646 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0215647 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0215648}
15649
bnc8016c1f2017-03-31 02:11:2915650// Regression test for https://crbug.com/546991.
15651// The server might not be able to serve an IP pooled request, and might send a
15652// 421 Misdirected Request response status to indicate this.
15653// HttpNetworkTransaction should reset the request and retry without IP pooling.
15654TEST_F(HttpNetworkTransactionTest, RetryWithoutConnectionPooling) {
15655 // Two hosts resolve to the same IP address.
15656 const std::string ip_addr = "1.2.3.4";
15657 IPAddress ip;
15658 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
15659 IPEndPoint peer_addr = IPEndPoint(ip, 443);
15660
Jeremy Roman0579ed62017-08-29 15:56:1915661 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
bnc8016c1f2017-03-31 02:11:2915662 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
15663 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
15664
15665 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15666
15667 // Two requests on the first connection.
Ryan Hamilton0239aac2018-05-19 00:03:1315668 spdy::SpdySerializedFrame req1(
bnc8016c1f2017-03-31 02:11:2915669 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
15670 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1315671 spdy::SpdySerializedFrame req2(
bnc8016c1f2017-03-31 02:11:2915672 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1315673 spdy::SpdySerializedFrame rst(
15674 spdy_util_.ConstructSpdyRstStream(3, spdy::ERROR_CODE_CANCEL));
bnc8016c1f2017-03-31 02:11:2915675 MockWrite writes1[] = {
15676 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
15677 CreateMockWrite(rst, 6),
15678 };
15679
15680 // The first one succeeds, the second gets error 421 Misdirected Request.
Ryan Hamilton0239aac2018-05-19 00:03:1315681 spdy::SpdySerializedFrame resp1(
15682 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
15683 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
15684 spdy::SpdyHeaderBlock response_headers;
15685 response_headers[spdy::kHttp2StatusHeader] = "421";
15686 spdy::SpdySerializedFrame resp2(
bnc8016c1f2017-03-31 02:11:2915687 spdy_util_.ConstructSpdyReply(3, std::move(response_headers)));
15688 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
15689 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
15690
15691 MockConnect connect1(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115692 SequencedSocketData data1(connect1, reads1, writes1);
bnc8016c1f2017-03-31 02:11:2915693 session_deps_.socket_factory->AddSocketDataProvider(&data1);
15694
15695 AddSSLSocketData();
15696
15697 // Retry the second request on a second connection.
15698 SpdyTestUtil spdy_util2;
Ryan Hamilton0239aac2018-05-19 00:03:1315699 spdy::SpdySerializedFrame req3(
bnc8016c1f2017-03-31 02:11:2915700 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
15701 MockWrite writes2[] = {
15702 CreateMockWrite(req3, 0),
15703 };
15704
Ryan Hamilton0239aac2018-05-19 00:03:1315705 spdy::SpdySerializedFrame resp3(
15706 spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
15707 spdy::SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
bnc8016c1f2017-03-31 02:11:2915708 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
15709 MockRead(ASYNC, 0, 3)};
15710
15711 MockConnect connect2(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115712 SequencedSocketData data2(connect2, reads2, writes2);
bnc8016c1f2017-03-31 02:11:2915713 session_deps_.socket_factory->AddSocketDataProvider(&data2);
15714
15715 AddSSLSocketData();
15716
15717 // Preload mail.example.org into HostCache.
Eric Orthf4db66a2019-02-19 21:35:3315718 int rv = session_deps_.host_resolver->LoadIntoCache(
15719 HostPortPair("mail.example.com", 443), base::nullopt);
bnc8016c1f2017-03-31 02:11:2915720 EXPECT_THAT(rv, IsOk());
15721
15722 HttpRequestInfo request1;
15723 request1.method = "GET";
15724 request1.url = GURL("https://www.example.org/");
15725 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015726 request1.traffic_annotation =
15727 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8016c1f2017-03-31 02:11:2915728 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
15729
Eric Orthf4db66a2019-02-19 21:35:3315730 TestCompletionCallback callback;
bnc8016c1f2017-03-31 02:11:2915731 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
15732 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15733 rv = callback.WaitForResult();
15734 EXPECT_THAT(rv, IsOk());
15735
15736 const HttpResponseInfo* response = trans1.GetResponseInfo();
15737 ASSERT_TRUE(response);
15738 ASSERT_TRUE(response->headers);
15739 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
15740 EXPECT_TRUE(response->was_fetched_via_spdy);
15741 EXPECT_TRUE(response->was_alpn_negotiated);
15742 std::string response_data;
15743 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
15744 EXPECT_EQ("hello!", response_data);
15745
15746 HttpRequestInfo request2;
15747 request2.method = "GET";
15748 request2.url = GURL("https://mail.example.org/");
15749 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015750 request2.traffic_annotation =
15751 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8016c1f2017-03-31 02:11:2915752 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
15753
15754 BoundTestNetLog log;
15755 rv = trans2.Start(&request2, callback.callback(), log.bound());
15756 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15757 rv = callback.WaitForResult();
15758 EXPECT_THAT(rv, IsOk());
15759
15760 response = trans2.GetResponseInfo();
15761 ASSERT_TRUE(response);
15762 ASSERT_TRUE(response->headers);
15763 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
15764 EXPECT_TRUE(response->was_fetched_via_spdy);
15765 EXPECT_TRUE(response->was_alpn_negotiated);
15766 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
15767 EXPECT_EQ("hello!", response_data);
15768
15769 TestNetLogEntry::List entries;
15770 log.GetEntries(&entries);
davidbence688ae2017-05-04 15:12:5915771 ExpectLogContainsSomewhere(
15772 entries, 0, NetLogEventType::HTTP_TRANSACTION_RESTART_MISDIRECTED_REQUEST,
bnc8016c1f2017-03-31 02:11:2915773 NetLogEventPhase::NONE);
davidbence688ae2017-05-04 15:12:5915774}
15775
15776// Test that HTTP 421 responses are properly returned to the caller if received
15777// on the retry as well. HttpNetworkTransaction should not infinite loop or lose
15778// portions of the response.
15779TEST_F(HttpNetworkTransactionTest, ReturnHTTP421OnRetry) {
15780 // Two hosts resolve to the same IP address.
15781 const std::string ip_addr = "1.2.3.4";
15782 IPAddress ip;
15783 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
15784 IPEndPoint peer_addr = IPEndPoint(ip, 443);
15785
Jeremy Roman0579ed62017-08-29 15:56:1915786 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
davidbence688ae2017-05-04 15:12:5915787 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
15788 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
15789
15790 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15791
15792 // Two requests on the first connection.
Ryan Hamilton0239aac2018-05-19 00:03:1315793 spdy::SpdySerializedFrame req1(
davidbence688ae2017-05-04 15:12:5915794 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
15795 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1315796 spdy::SpdySerializedFrame req2(
davidbence688ae2017-05-04 15:12:5915797 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1315798 spdy::SpdySerializedFrame rst(
15799 spdy_util_.ConstructSpdyRstStream(3, spdy::ERROR_CODE_CANCEL));
davidbence688ae2017-05-04 15:12:5915800 MockWrite writes1[] = {
15801 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
15802 CreateMockWrite(rst, 6),
15803 };
15804
15805 // The first one succeeds, the second gets error 421 Misdirected Request.
Ryan Hamilton0239aac2018-05-19 00:03:1315806 spdy::SpdySerializedFrame resp1(
15807 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
15808 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
15809 spdy::SpdyHeaderBlock response_headers;
15810 response_headers[spdy::kHttp2StatusHeader] = "421";
15811 spdy::SpdySerializedFrame resp2(
davidbence688ae2017-05-04 15:12:5915812 spdy_util_.ConstructSpdyReply(3, response_headers.Clone()));
15813 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
15814 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
15815
15816 MockConnect connect1(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115817 SequencedSocketData data1(connect1, reads1, writes1);
davidbence688ae2017-05-04 15:12:5915818 session_deps_.socket_factory->AddSocketDataProvider(&data1);
15819
15820 AddSSLSocketData();
15821
15822 // Retry the second request on a second connection. It returns 421 Misdirected
15823 // Retry again.
15824 SpdyTestUtil spdy_util2;
Ryan Hamilton0239aac2018-05-19 00:03:1315825 spdy::SpdySerializedFrame req3(
davidbence688ae2017-05-04 15:12:5915826 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
15827 MockWrite writes2[] = {
15828 CreateMockWrite(req3, 0),
15829 };
15830
Ryan Hamilton0239aac2018-05-19 00:03:1315831 spdy::SpdySerializedFrame resp3(
davidbence688ae2017-05-04 15:12:5915832 spdy_util2.ConstructSpdyReply(1, std::move(response_headers)));
Ryan Hamilton0239aac2018-05-19 00:03:1315833 spdy::SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
davidbence688ae2017-05-04 15:12:5915834 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
15835 MockRead(ASYNC, 0, 3)};
15836
15837 MockConnect connect2(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115838 SequencedSocketData data2(connect2, reads2, writes2);
davidbence688ae2017-05-04 15:12:5915839 session_deps_.socket_factory->AddSocketDataProvider(&data2);
15840
15841 AddSSLSocketData();
15842
15843 // Preload mail.example.org into HostCache.
Eric Orthf4db66a2019-02-19 21:35:3315844 int rv = session_deps_.host_resolver->LoadIntoCache(
15845 HostPortPair("mail.example.com", 443), base::nullopt);
davidbence688ae2017-05-04 15:12:5915846 EXPECT_THAT(rv, IsOk());
15847
15848 HttpRequestInfo request1;
15849 request1.method = "GET";
15850 request1.url = GURL("https://www.example.org/");
15851 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015852 request1.traffic_annotation =
15853 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
davidbence688ae2017-05-04 15:12:5915854 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
15855
Eric Orthf4db66a2019-02-19 21:35:3315856 TestCompletionCallback callback;
davidbence688ae2017-05-04 15:12:5915857 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
15858 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15859 rv = callback.WaitForResult();
15860 EXPECT_THAT(rv, IsOk());
15861
15862 const HttpResponseInfo* response = trans1.GetResponseInfo();
15863 ASSERT_TRUE(response);
15864 ASSERT_TRUE(response->headers);
15865 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
15866 EXPECT_TRUE(response->was_fetched_via_spdy);
15867 EXPECT_TRUE(response->was_alpn_negotiated);
15868 std::string response_data;
15869 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
15870 EXPECT_EQ("hello!", response_data);
15871
15872 HttpRequestInfo request2;
15873 request2.method = "GET";
15874 request2.url = GURL("https://mail.example.org/");
15875 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015876 request2.traffic_annotation =
15877 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
davidbence688ae2017-05-04 15:12:5915878 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
15879
15880 BoundTestNetLog log;
15881 rv = trans2.Start(&request2, callback.callback(), log.bound());
15882 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15883 rv = callback.WaitForResult();
15884 EXPECT_THAT(rv, IsOk());
15885
15886 // After a retry, the 421 Misdirected Request is reported back up to the
15887 // caller.
15888 response = trans2.GetResponseInfo();
15889 ASSERT_TRUE(response);
15890 ASSERT_TRUE(response->headers);
15891 EXPECT_EQ("HTTP/1.1 421", response->headers->GetStatusLine());
15892 EXPECT_TRUE(response->was_fetched_via_spdy);
15893 EXPECT_TRUE(response->was_alpn_negotiated);
15894 EXPECT_TRUE(response->ssl_info.cert);
15895 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
15896 EXPECT_EQ("hello!", response_data);
bnc8016c1f2017-03-31 02:11:2915897}
15898
bncd16676a2016-07-20 16:23:0115899TEST_F(HttpNetworkTransactionTest,
mmenke5c642132015-06-02 16:05:1315900 UseIPConnectionPoolingWithHostCacheExpiration) {
Eric Orth1da75de2019-02-20 21:10:3415901 // Set up HostResolver to invalidate cached entries after 1 cached resolve.
15902 session_deps_.host_resolver =
15903 std::make_unique<MockCachingHostResolver>(1 /* cache_invalidation_num */);
danakj1fd259a02016-04-16 03:17:0915904 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4615905
bnc032658ba2016-09-26 18:17:1515906 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4615907
Ryan Hamilton0239aac2018-05-19 00:03:1315908 spdy::SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4915909 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3815910 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1315911 spdy::SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3715912 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4615913 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115914 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4615915 };
Ryan Hamilton0239aac2018-05-19 00:03:1315916 spdy::SpdySerializedFrame host1_resp(
Raul Tambre94493c652019-03-11 17:18:3515917 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1315918 spdy::SpdySerializedFrame host1_resp_body(
bncdf80d44fd2016-07-15 20:27:4115919 spdy_util_.ConstructSpdyDataFrame(1, true));
Ryan Hamilton0239aac2018-05-19 00:03:1315920 spdy::SpdySerializedFrame host2_resp(
Raul Tambre94493c652019-03-11 17:18:3515921 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
Ryan Hamilton0239aac2018-05-19 00:03:1315922 spdy::SpdySerializedFrame host2_resp_body(
bncdf80d44fd2016-07-15 20:27:4115923 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4615924 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115925 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
15926 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1315927 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4615928 };
15929
eroman36d84e54432016-03-17 03:23:0215930 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0215931 MockConnect connect(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115932 SequencedSocketData spdy_data(connect, spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0715933 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4615934
[email protected]aa22b242011-11-16 18:58:2915935 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4615936 HttpRequestInfo request1;
15937 request1.method = "GET";
bncce36dca22015-04-21 22:11:2315938 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4615939 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015940 request1.traffic_annotation =
15941 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015942 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4615943
tfarina42834112016-09-22 13:38:2015944 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115945 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15946 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615947
15948 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5215949 ASSERT_TRUE(response);
15950 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215951 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4615952
15953 std::string response_data;
robpercival214763f2016-07-01 23:27:0115954 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615955 EXPECT_EQ("hello!", response_data);
15956
15957 // Preload cache entries into HostCache.
Eric Orthf4db66a2019-02-19 21:35:3315958 rv = session_deps_.host_resolver->LoadIntoCache(
15959 HostPortPair("mail.example.com", 443), base::nullopt);
robpercival214763f2016-07-01 23:27:0115960 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4615961
15962 HttpRequestInfo request2;
15963 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3715964 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4615965 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015966 request2.traffic_annotation =
15967 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015968 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4615969
tfarina42834112016-09-22 13:38:2015970 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115971 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15972 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615973
15974 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215975 ASSERT_TRUE(response);
15976 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215977 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4615978 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215979 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115980 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615981 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4615982}
15983
bncd16676a2016-07-20 16:23:0115984TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2315985 const std::string https_url = "https://www.example.org:8080/";
15986 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0415987
15988 // SPDY GET for HTTPS URL
Ryan Hamilton0239aac2018-05-19 00:03:1315989 spdy::SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4915990 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0415991
15992 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4115993 CreateMockWrite(req1, 0),
[email protected]8450d722012-07-02 19:14:0415994 };
15995
Raul Tambre94493c652019-03-11 17:18:3515996 spdy::SpdySerializedFrame resp1(
15997 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1315998 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
bncdf80d44fd2016-07-15 20:27:4115999 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
mmenkee24011922015-12-17 22:12:5916000 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)};
[email protected]8450d722012-07-02 19:14:0416001
Ryan Sleevib8d7ea02018-05-07 20:01:0116002 SequencedSocketData data1(reads1, writes1);
[email protected]8450d722012-07-02 19:14:0416003 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5716004 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0416005
16006 // HTTP GET for the HTTP URL
16007 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1316008 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3416009 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2316010 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3416011 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0416012 };
16013
16014 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1316015 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
16016 MockRead(ASYNC, 2, "hello"),
16017 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0416018 };
16019
Ryan Sleevib8d7ea02018-05-07 20:01:0116020 SequencedSocketData data2(reads2, writes2);
[email protected]8450d722012-07-02 19:14:0416021
[email protected]8450d722012-07-02 19:14:0416022 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616023 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0716024 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16025 session_deps_.socket_factory->AddSocketDataProvider(&data1);
16026 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0416027
danakj1fd259a02016-04-16 03:17:0916028 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0416029
16030 // Start the first transaction to set up the SpdySession
16031 HttpRequestInfo request1;
16032 request1.method = "GET";
16033 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0416034 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016035 request1.traffic_annotation =
16036 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016037 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0416038 TestCompletionCallback callback1;
16039 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016040 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5516041 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0416042
robpercival214763f2016-07-01 23:27:0116043 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0416044 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
16045
16046 // Now, start the HTTP request
16047 HttpRequestInfo request2;
16048 request2.method = "GET";
16049 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0416050 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016051 request2.traffic_annotation =
16052 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016053 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0416054 TestCompletionCallback callback2;
16055 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016056 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5516057 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0416058
robpercival214763f2016-07-01 23:27:0116059 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0416060 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
16061}
16062
bnc5452e2a2015-05-08 16:27:4216063// Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
16064// with the alternative server. That connection should not be used.
bncd16676a2016-07-20 16:23:0116065TEST_F(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
bnc8bef8da22016-05-30 01:28:2516066 url::SchemeHostPort server("https", "www.example.org", 443);
16067 HostPortPair alternative("www.example.org", 444);
bnc5452e2a2015-05-08 16:27:4216068
bnc8bef8da22016-05-30 01:28:2516069 // Negotiate HTTP/1.1 with alternative.
bnc5452e2a2015-05-08 16:27:4216070 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616071 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4216072 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16073
16074 // No data should be read from the alternative, because HTTP/1.1 is
16075 // negotiated.
16076 StaticSocketDataProvider data;
16077 session_deps_.socket_factory->AddSocketDataProvider(&data);
16078
16079 // This test documents that an alternate Job should not be used if HTTP/1.1 is
zhongyi3d4a55e72016-04-22 20:36:4616080 // negotiated. In order to test this, a failed connection to the server is
bnc5452e2a2015-05-08 16:27:4216081 // mocked. This way the request relies on the alternate Job.
16082 StaticSocketDataProvider data_refused;
16083 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
16084 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
16085
zhongyi3d4a55e72016-04-22 20:36:4616086 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0916087 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4016088 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4216089 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2116090 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1216091 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2116092 http_server_properties->SetHttp2AlternativeService(
16093 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4216094
bnc5452e2a2015-05-08 16:27:4216095 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4616096 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4216097 request.method = "GET";
bnc8bef8da22016-05-30 01:28:2516098 request.url = GURL("https://www.example.org:443");
Ramin Halavatib5e433e2018-02-07 07:41:1016099 request.traffic_annotation =
16100 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4216101 TestCompletionCallback callback;
16102
16103 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
bnc94c92842016-09-21 15:22:5216104 // negotiated, the alternate Job should fail with ERR_ALPN_NEGOTIATION_FAILED.
tfarina42834112016-09-22 13:38:2016105 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc94c92842016-09-21 15:22:5216106 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_ALPN_NEGOTIATION_FAILED));
bnc5452e2a2015-05-08 16:27:4216107}
16108
bnc40448a532015-05-11 19:13:1416109// A request to a server with an alternative service fires two Jobs: one to the
zhongyi3d4a55e72016-04-22 20:36:4616110// server, and an alternate one to the alternative server. If the former
bnc40448a532015-05-11 19:13:1416111// succeeds, the request should succeed, even if the latter fails because
16112// HTTP/1.1 is negotiated which is insufficient for alternative service.
bncd16676a2016-07-20 16:23:0116113TEST_F(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
bnc8bef8da22016-05-30 01:28:2516114 url::SchemeHostPort server("https", "www.example.org", 443);
16115 HostPortPair alternative("www.example.org", 444);
bnc40448a532015-05-11 19:13:1416116
16117 // Negotiate HTTP/1.1 with alternative.
16118 SSLSocketDataProvider alternative_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616119 alternative_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1416120 session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
16121
16122 // No data should be read from the alternative, because HTTP/1.1 is
16123 // negotiated.
16124 StaticSocketDataProvider data;
16125 session_deps_.socket_factory->AddSocketDataProvider(&data);
16126
zhongyi3d4a55e72016-04-22 20:36:4616127 // Negotiate HTTP/1.1 with server.
bnc40448a532015-05-11 19:13:1416128 SSLSocketDataProvider origin_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616129 origin_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1416130 session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
16131
16132 MockWrite http_writes[] = {
bnc8bef8da22016-05-30 01:28:2516133 MockWrite("GET / HTTP/1.1\r\n"
16134 "Host: www.example.org\r\n"
16135 "Connection: keep-alive\r\n\r\n"),
16136 MockWrite("GET /second HTTP/1.1\r\n"
16137 "Host: www.example.org\r\n"
16138 "Connection: keep-alive\r\n\r\n"),
bnc40448a532015-05-11 19:13:1416139 };
16140
16141 MockRead http_reads[] = {
16142 MockRead("HTTP/1.1 200 OK\r\n"),
16143 MockRead("Content-Type: text/html\r\n"),
16144 MockRead("Content-Length: 6\r\n\r\n"),
16145 MockRead("foobar"),
16146 MockRead("HTTP/1.1 200 OK\r\n"),
16147 MockRead("Content-Type: text/html\r\n"),
16148 MockRead("Content-Length: 7\r\n\r\n"),
16149 MockRead("another"),
16150 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116151 StaticSocketDataProvider http_data(http_reads, http_writes);
bnc40448a532015-05-11 19:13:1416152 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16153
zhongyi3d4a55e72016-04-22 20:36:4616154 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0916155 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4016156 HttpServerProperties* http_server_properties =
bnc40448a532015-05-11 19:13:1416157 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2116158 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1216159 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2116160 http_server_properties->SetHttp2AlternativeService(
16161 server, alternative_service, expiration);
bnc40448a532015-05-11 19:13:1416162
16163 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
16164 HttpRequestInfo request1;
16165 request1.method = "GET";
bnc8bef8da22016-05-30 01:28:2516166 request1.url = GURL("https://www.example.org:443");
bnc40448a532015-05-11 19:13:1416167 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016168 request1.traffic_annotation =
16169 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc40448a532015-05-11 19:13:1416170 TestCompletionCallback callback1;
16171
tfarina42834112016-09-22 13:38:2016172 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1416173 rv = callback1.GetResult(rv);
robpercival214763f2016-07-01 23:27:0116174 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1416175
16176 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5216177 ASSERT_TRUE(response1);
16178 ASSERT_TRUE(response1->headers);
bnc40448a532015-05-11 19:13:1416179 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
16180
16181 std::string response_data1;
robpercival214763f2016-07-01 23:27:0116182 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc40448a532015-05-11 19:13:1416183 EXPECT_EQ("foobar", response_data1);
16184
16185 // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
16186 // for alternative service.
16187 EXPECT_TRUE(
16188 http_server_properties->IsAlternativeServiceBroken(alternative_service));
16189
zhongyi3d4a55e72016-04-22 20:36:4616190 // Since |alternative_service| is broken, a second transaction to server
bnc40448a532015-05-11 19:13:1416191 // should not start an alternate Job. It should pool to existing connection
zhongyi3d4a55e72016-04-22 20:36:4616192 // to server.
bnc40448a532015-05-11 19:13:1416193 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
16194 HttpRequestInfo request2;
16195 request2.method = "GET";
bnc8bef8da22016-05-30 01:28:2516196 request2.url = GURL("https://www.example.org:443/second");
bnc40448a532015-05-11 19:13:1416197 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016198 request2.traffic_annotation =
16199 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc40448a532015-05-11 19:13:1416200 TestCompletionCallback callback2;
16201
tfarina42834112016-09-22 13:38:2016202 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1416203 rv = callback2.GetResult(rv);
robpercival214763f2016-07-01 23:27:0116204 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1416205
16206 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5216207 ASSERT_TRUE(response2);
16208 ASSERT_TRUE(response2->headers);
bnc40448a532015-05-11 19:13:1416209 EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
16210
16211 std::string response_data2;
robpercival214763f2016-07-01 23:27:0116212 ASSERT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
bnc40448a532015-05-11 19:13:1416213 EXPECT_EQ("another", response_data2);
16214}
16215
bnc5452e2a2015-05-08 16:27:4216216// Alternative service requires HTTP/2 (or SPDY), but there is already a
16217// HTTP/1.1 socket open to the alternative server. That socket should not be
16218// used.
bncd16676a2016-07-20 16:23:0116219TEST_F(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
zhongyi3d4a55e72016-04-22 20:36:4616220 url::SchemeHostPort server("https", "origin.example.org", 443);
bnc5452e2a2015-05-08 16:27:4216221 HostPortPair alternative("alternative.example.org", 443);
16222 std::string origin_url = "https://origin.example.org:443";
16223 std::string alternative_url = "https://alternative.example.org:443";
16224
16225 // Negotiate HTTP/1.1 with alternative.example.org.
16226 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616227 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4216228 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16229
16230 // HTTP/1.1 data for |request1| and |request2|.
16231 MockWrite http_writes[] = {
16232 MockWrite(
16233 "GET / HTTP/1.1\r\n"
16234 "Host: alternative.example.org\r\n"
16235 "Connection: keep-alive\r\n\r\n"),
16236 MockWrite(
16237 "GET / HTTP/1.1\r\n"
16238 "Host: alternative.example.org\r\n"
16239 "Connection: keep-alive\r\n\r\n"),
16240 };
16241
16242 MockRead http_reads[] = {
16243 MockRead(
16244 "HTTP/1.1 200 OK\r\n"
16245 "Content-Type: text/html; charset=iso-8859-1\r\n"
16246 "Content-Length: 40\r\n\r\n"
16247 "first HTTP/1.1 response from alternative"),
16248 MockRead(
16249 "HTTP/1.1 200 OK\r\n"
16250 "Content-Type: text/html; charset=iso-8859-1\r\n"
16251 "Content-Length: 41\r\n\r\n"
16252 "second HTTP/1.1 response from alternative"),
16253 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116254 StaticSocketDataProvider http_data(http_reads, http_writes);
bnc5452e2a2015-05-08 16:27:4216255 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16256
16257 // This test documents that an alternate Job should not pool to an already
16258 // existing HTTP/1.1 connection. In order to test this, a failed connection
zhongyi3d4a55e72016-04-22 20:36:4616259 // to the server is mocked. This way |request2| relies on the alternate Job.
bnc5452e2a2015-05-08 16:27:4216260 StaticSocketDataProvider data_refused;
16261 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
16262 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
16263
zhongyi3d4a55e72016-04-22 20:36:4616264 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0916265 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4016266 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4216267 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2116268 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1216269 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2116270 http_server_properties->SetHttp2AlternativeService(
16271 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4216272
16273 // First transaction to alternative to open an HTTP/1.1 socket.
bnc5452e2a2015-05-08 16:27:4216274 HttpRequestInfo request1;
krasinc06a72a2016-12-21 03:42:4616275 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4216276 request1.method = "GET";
16277 request1.url = GURL(alternative_url);
16278 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016279 request1.traffic_annotation =
16280 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4216281 TestCompletionCallback callback1;
16282
tfarina42834112016-09-22 13:38:2016283 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116284 EXPECT_THAT(callback1.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1616285 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4216286 ASSERT_TRUE(response1);
wezca1070932016-05-26 20:30:5216287 ASSERT_TRUE(response1->headers);
bnc5452e2a2015-05-08 16:27:4216288 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5216289 EXPECT_TRUE(response1->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4216290 EXPECT_FALSE(response1->was_fetched_via_spdy);
16291 std::string response_data1;
bnc691fda62016-08-12 00:43:1616292 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc5452e2a2015-05-08 16:27:4216293 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
16294
16295 // Request for origin.example.org, which has an alternative service. This
16296 // will start two Jobs: the alternative looks for connections to pool to,
16297 // finds one which is HTTP/1.1, and should ignore it, and should not try to
zhongyi3d4a55e72016-04-22 20:36:4616298 // open other connections to alternative server. The Job to server fails, so
bnc5452e2a2015-05-08 16:27:4216299 // this request fails.
bnc5452e2a2015-05-08 16:27:4216300 HttpRequestInfo request2;
krasinc06a72a2016-12-21 03:42:4616301 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4216302 request2.method = "GET";
16303 request2.url = GURL(origin_url);
16304 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016305 request2.traffic_annotation =
16306 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4216307 TestCompletionCallback callback2;
16308
tfarina42834112016-09-22 13:38:2016309 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116310 EXPECT_THAT(callback2.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc5452e2a2015-05-08 16:27:4216311
16312 // Another transaction to alternative. This is to test that the HTTP/1.1
16313 // socket is still open and in the pool.
bnc5452e2a2015-05-08 16:27:4216314 HttpRequestInfo request3;
krasinc06a72a2016-12-21 03:42:4616315 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4216316 request3.method = "GET";
16317 request3.url = GURL(alternative_url);
16318 request3.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016319 request3.traffic_annotation =
16320 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4216321 TestCompletionCallback callback3;
16322
tfarina42834112016-09-22 13:38:2016323 rv = trans3.Start(&request3, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116324 EXPECT_THAT(callback3.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1616325 const HttpResponseInfo* response3 = trans3.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4216326 ASSERT_TRUE(response3);
wezca1070932016-05-26 20:30:5216327 ASSERT_TRUE(response3->headers);
bnc5452e2a2015-05-08 16:27:4216328 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5216329 EXPECT_TRUE(response3->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4216330 EXPECT_FALSE(response3->was_fetched_via_spdy);
16331 std::string response_data3;
bnc691fda62016-08-12 00:43:1616332 ASSERT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
bnc5452e2a2015-05-08 16:27:4216333 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
16334}
16335
bncd16676a2016-07-20 16:23:0116336TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2316337 const std::string https_url = "https://www.example.org:8080/";
16338 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0416339
rdsmithebb50aa2015-11-12 03:44:3816340 // Separate SPDY util instance for naked and wrapped requests.
bncd16676a2016-07-20 16:23:0116341 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:3816342
[email protected]8450d722012-07-02 19:14:0416343 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2316344 const HostPortPair host_port_pair("www.example.org", 8080);
Matt Menke6e879bd2019-03-18 17:26:0416345 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
16346 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
16347 host_port_pair));
Ryan Hamilton0239aac2018-05-19 00:03:1316348 spdy::SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4916349 spdy_util_wrapped.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1316350 spdy::SpdySerializedFrame wrapped_req1(
[email protected]23e482282013-06-14 16:08:0216351 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3916352
16353 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
Ryan Hamilton0239aac2018-05-19 00:03:1316354 spdy::SpdyHeaderBlock req2_block;
16355 req2_block[spdy::kHttp2MethodHeader] = "GET";
16356 req2_block[spdy::kHttp2AuthorityHeader] = "www.example.org:8080";
16357 req2_block[spdy::kHttp2SchemeHeader] = "http";
16358 req2_block[spdy::kHttp2PathHeader] = "/";
16359 spdy::SpdySerializedFrame req2(
bnc42331402016-07-25 13:36:1516360 spdy_util_.ConstructSpdyHeaders(3, std::move(req2_block), MEDIUM, true));
[email protected]8450d722012-07-02 19:14:0416361
16362 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4116363 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_req1, 2),
16364 CreateMockWrite(req2, 6),
[email protected]8450d722012-07-02 19:14:0416365 };
16366
Ryan Hamilton0239aac2018-05-19 00:03:1316367 spdy::SpdySerializedFrame conn_resp(
bnc42331402016-07-25 13:36:1516368 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316369 spdy::SpdySerializedFrame resp1(
bnc42331402016-07-25 13:36:1516370 spdy_util_wrapped.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316371 spdy::SpdySerializedFrame body1(
16372 spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
16373 spdy::SpdySerializedFrame wrapped_resp1(
rdsmithebb50aa2015-11-12 03:44:3816374 spdy_util_wrapped.ConstructWrappedSpdyFrame(resp1, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316375 spdy::SpdySerializedFrame wrapped_body1(
rdsmithebb50aa2015-11-12 03:44:3816376 spdy_util_wrapped.ConstructWrappedSpdyFrame(body1, 1));
Raul Tambre94493c652019-03-11 17:18:3516377 spdy::SpdySerializedFrame resp2(
16378 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
Ryan Hamilton0239aac2018-05-19 00:03:1316379 spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
mmenke666a6fea2015-12-19 04:16:3316380 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4116381 CreateMockRead(conn_resp, 1),
mmenke666a6fea2015-12-19 04:16:3316382 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:4116383 CreateMockRead(wrapped_resp1, 4),
16384 CreateMockRead(wrapped_body1, 5),
mmenke666a6fea2015-12-19 04:16:3316385 MockRead(ASYNC, ERR_IO_PENDING, 7),
bncdf80d44fd2016-07-15 20:27:4116386 CreateMockRead(resp2, 8),
16387 CreateMockRead(body2, 9),
mmenke666a6fea2015-12-19 04:16:3316388 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 10),
16389 };
[email protected]8450d722012-07-02 19:14:0416390
Ryan Sleevib8d7ea02018-05-07 20:01:0116391 SequencedSocketData data1(reads1, writes1);
[email protected]8450d722012-07-02 19:14:0416392 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5716393 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0416394
Lily Houghton8c2f97d2018-01-22 05:06:5916395 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4916396 ProxyResolutionService::CreateFixedFromPacResult(
16397 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5116398 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0716399 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0416400 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3616401 ssl1.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3316402 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0416403 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3616404 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3316405 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
16406 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0416407
danakj1fd259a02016-04-16 03:17:0916408 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]8450d722012-07-02 19:14:0416409
16410 // Start the first transaction to set up the SpdySession
16411 HttpRequestInfo request1;
16412 request1.method = "GET";
16413 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0416414 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016415 request1.traffic_annotation =
16416 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016417 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0416418 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:2016419 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0416420
mmenke666a6fea2015-12-19 04:16:3316421 // This pause is a hack to avoid running into https://crbug.com/497228.
16422 data1.RunUntilPaused();
16423 base::RunLoop().RunUntilIdle();
16424 data1.Resume();
robpercival214763f2016-07-01 23:27:0116425 EXPECT_THAT(callback1.GetResult(rv), IsOk());
[email protected]8450d722012-07-02 19:14:0416426 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
16427
[email protected]f6c63db52013-02-02 00:35:2216428 LoadTimingInfo load_timing_info1;
16429 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
16430 TestLoadTimingNotReusedWithPac(load_timing_info1,
16431 CONNECT_TIMING_HAS_SSL_TIMES);
16432
mmenke666a6fea2015-12-19 04:16:3316433 // Now, start the HTTP request.
[email protected]8450d722012-07-02 19:14:0416434 HttpRequestInfo request2;
16435 request2.method = "GET";
16436 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0416437 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016438 request2.traffic_annotation =
16439 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016440 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0416441 TestCompletionCallback callback2;
tfarina42834112016-09-22 13:38:2016442 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0416443
mmenke666a6fea2015-12-19 04:16:3316444 // This pause is a hack to avoid running into https://crbug.com/497228.
16445 data1.RunUntilPaused();
16446 base::RunLoop().RunUntilIdle();
16447 data1.Resume();
robpercival214763f2016-07-01 23:27:0116448 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenke666a6fea2015-12-19 04:16:3316449
[email protected]8450d722012-07-02 19:14:0416450 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2216451
16452 LoadTimingInfo load_timing_info2;
16453 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
16454 // The established SPDY sessions is considered reused by the HTTP request.
16455 TestLoadTimingReusedWithPac(load_timing_info2);
16456 // HTTP requests over a SPDY session should have a different connection
16457 // socket_log_id than requests over a tunnel.
16458 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0416459}
16460
[email protected]2d88e7d2012-07-19 17:55:1716461// Test that in the case where we have a SPDY session to a SPDY proxy
16462// that we do not pool other origins that resolve to the same IP when
16463// the certificate does not match the new origin.
16464// http://crbug.com/134690
bncd16676a2016-07-20 16:23:0116465TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2316466 const std::string url1 = "http://www.example.org/";
16467 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1716468 const std::string ip_addr = "1.2.3.4";
16469
rdsmithebb50aa2015-11-12 03:44:3816470 // Second SpdyTestUtil instance for the second socket.
bncd16676a2016-07-20 16:23:0116471 SpdyTestUtil spdy_util_secure;
rdsmithebb50aa2015-11-12 03:44:3816472
[email protected]2d88e7d2012-07-19 17:55:1716473 // SPDY GET for HTTP URL (through SPDY proxy)
Ryan Hamilton0239aac2018-05-19 00:03:1316474 spdy::SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:2316475 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
Ryan Hamilton0239aac2018-05-19 00:03:1316476 spdy::SpdySerializedFrame req1(
bnc42331402016-07-25 13:36:1516477 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
[email protected]2d88e7d2012-07-19 17:55:1716478
16479 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4116480 CreateMockWrite(req1, 0),
[email protected]2d88e7d2012-07-19 17:55:1716481 };
16482
Raul Tambre94493c652019-03-11 17:18:3516483 spdy::SpdySerializedFrame resp1(
16484 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316485 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1716486 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4116487 MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(resp1, 2),
16488 CreateMockRead(body1, 3), MockRead(ASYNC, OK, 4), // EOF
[email protected]2d88e7d2012-07-19 17:55:1716489 };
16490
Ryan Sleevib8d7ea02018-05-07 20:01:0116491 SequencedSocketData data1(reads1, writes1);
martijnfe9636e2016-02-06 14:33:3216492 IPAddress ip;
martijn654c8c42016-02-10 22:10:5916493 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
[email protected]2d88e7d2012-07-19 17:55:1716494 IPEndPoint peer_addr = IPEndPoint(ip, 443);
16495 MockConnect connect_data1(ASYNC, OK, peer_addr);
mmenke666a6fea2015-12-19 04:16:3316496 data1.set_connect_data(connect_data1);
[email protected]2d88e7d2012-07-19 17:55:1716497
16498 // SPDY GET for HTTPS URL (direct)
Ryan Hamilton0239aac2018-05-19 00:03:1316499 spdy::SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4916500 spdy_util_secure.ConstructSpdyGet(url2.c_str(), 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1716501
16502 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4116503 CreateMockWrite(req2, 0),
[email protected]2d88e7d2012-07-19 17:55:1716504 };
16505
Ryan Hamilton0239aac2018-05-19 00:03:1316506 spdy::SpdySerializedFrame resp2(
Raul Tambre94493c652019-03-11 17:18:3516507 spdy_util_secure.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316508 spdy::SpdySerializedFrame body2(
16509 spdy_util_secure.ConstructSpdyDataFrame(1, true));
bncdf80d44fd2016-07-15 20:27:4116510 MockRead reads2[] = {CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
mmenke666a6fea2015-12-19 04:16:3316511 MockRead(ASYNC, OK, 3)};
[email protected]2d88e7d2012-07-19 17:55:1716512
Ryan Sleevib8d7ea02018-05-07 20:01:0116513 SequencedSocketData data2(reads2, writes2);
[email protected]2d88e7d2012-07-19 17:55:1716514 MockConnect connect_data2(ASYNC, OK);
mmenke666a6fea2015-12-19 04:16:3316515 data2.set_connect_data(connect_data2);
[email protected]2d88e7d2012-07-19 17:55:1716516
16517 // Set up a proxy config that sends HTTP requests to a proxy, and
16518 // all others direct.
16519 ProxyConfig proxy_config;
16520 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
Ramin Halavatica8d5252018-03-12 05:33:4916521 session_deps_.proxy_resolution_service =
16522 std::make_unique<ProxyResolutionService>(
16523 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
16524 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
16525 nullptr, nullptr);
[email protected]2d88e7d2012-07-19 17:55:1716526
bncce36dca22015-04-21 22:11:2316527 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3616528 ssl1.next_proto = kProtoHTTP2;
[email protected]2d88e7d2012-07-19 17:55:1716529 // Load a valid cert. Note, that this does not need to
16530 // be valid for proxy because the MockSSLClientSocket does
16531 // not actually verify it. But SpdySession will use this
16532 // to see if it is valid for the new origin
Ryan Sleevi4f832092017-11-21 23:25:4916533 ssl1.ssl_info.cert =
16534 ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
16535 ASSERT_TRUE(ssl1.ssl_info.cert);
mmenke666a6fea2015-12-19 04:16:3316536 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
16537 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d88e7d2012-07-19 17:55:1716538
16539 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3616540 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3316541 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
16542 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d88e7d2012-07-19 17:55:1716543
Jeremy Roman0579ed62017-08-29 15:56:1916544 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
bncce36dca22015-04-21 22:11:2316545 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0716546 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1716547
danakj1fd259a02016-04-16 03:17:0916548 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]2d88e7d2012-07-19 17:55:1716549
16550 // Start the first transaction to set up the SpdySession
16551 HttpRequestInfo request1;
16552 request1.method = "GET";
16553 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1716554 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016555 request1.traffic_annotation =
16556 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016557 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1716558 TestCompletionCallback callback1;
16559 ASSERT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016560 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
mmenke666a6fea2015-12-19 04:16:3316561 // This pause is a hack to avoid running into https://crbug.com/497228.
16562 data1.RunUntilPaused();
16563 base::RunLoop().RunUntilIdle();
16564 data1.Resume();
[email protected]2d88e7d2012-07-19 17:55:1716565
robpercival214763f2016-07-01 23:27:0116566 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1716567 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
16568
16569 // Now, start the HTTP request
16570 HttpRequestInfo request2;
16571 request2.method = "GET";
16572 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1716573 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016574 request2.traffic_annotation =
16575 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016576 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1716577 TestCompletionCallback callback2;
16578 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016579 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5516580 base::RunLoop().RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1716581
16582 ASSERT_TRUE(callback2.have_result());
robpercival214763f2016-07-01 23:27:0116583 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1716584 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
16585}
16586
[email protected]85f97342013-04-17 06:12:2416587// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
16588// error) in SPDY session, removes the socket from pool and closes the SPDY
16589// session. Verify that new url's from the same HttpNetworkSession (and a new
16590// SpdySession) do work. http://crbug.com/224701
bncd16676a2016-07-20 16:23:0116591TEST_F(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2316592 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2416593
16594 MockRead reads1[] = {
16595 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
16596 };
16597
Ryan Sleevib8d7ea02018-05-07 20:01:0116598 SequencedSocketData data1(reads1, base::span<MockWrite>());
[email protected]85f97342013-04-17 06:12:2416599
Ryan Hamilton0239aac2018-05-19 00:03:1316600 spdy::SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4916601 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2416602 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4116603 CreateMockWrite(req2, 0),
[email protected]85f97342013-04-17 06:12:2416604 };
16605
Raul Tambre94493c652019-03-11 17:18:3516606 spdy::SpdySerializedFrame resp2(
16607 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316608 spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]85f97342013-04-17 06:12:2416609 MockRead reads2[] = {
bncdf80d44fd2016-07-15 20:27:4116610 CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
16611 MockRead(ASYNC, OK, 3) // EOF
[email protected]85f97342013-04-17 06:12:2416612 };
16613
Ryan Sleevib8d7ea02018-05-07 20:01:0116614 SequencedSocketData data2(reads2, writes2);
[email protected]85f97342013-04-17 06:12:2416615
[email protected]85f97342013-04-17 06:12:2416616 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616617 ssl1.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5016618 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
16619 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]85f97342013-04-17 06:12:2416620
16621 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616622 ssl2.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5016623 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
16624 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]85f97342013-04-17 06:12:2416625
danakj1fd259a02016-04-16 03:17:0916626 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:5016627 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]85f97342013-04-17 06:12:2416628
16629 // Start the first transaction to set up the SpdySession and verify that
16630 // connection was closed.
16631 HttpRequestInfo request1;
16632 request1.method = "GET";
16633 request1.url = GURL(https_url);
16634 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016635 request1.traffic_annotation =
16636 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016637 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2416638 TestCompletionCallback callback1;
16639 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016640 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0116641 EXPECT_THAT(callback1.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]85f97342013-04-17 06:12:2416642
16643 // Now, start the second request and make sure it succeeds.
16644 HttpRequestInfo request2;
16645 request2.method = "GET";
16646 request2.url = GURL(https_url);
16647 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016648 request2.traffic_annotation =
16649 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016650 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2416651 TestCompletionCallback callback2;
16652 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016653 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
[email protected]85f97342013-04-17 06:12:2416654
robpercival214763f2016-07-01 23:27:0116655 ASSERT_THAT(callback2.WaitForResult(), IsOk());
[email protected]85f97342013-04-17 06:12:2416656 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
16657}
16658
bncd16676a2016-07-20 16:23:0116659TEST_F(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]483fa202013-05-14 01:07:0316660 ClientSocketPoolManager::set_max_sockets_per_group(
16661 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16662 ClientSocketPoolManager::set_max_sockets_per_pool(
16663 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16664
16665 // Use two different hosts with different IPs so they don't get pooled.
16666 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
16667 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
danakj1fd259a02016-04-16 03:17:0916668 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]483fa202013-05-14 01:07:0316669
16670 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616671 ssl1.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0316672 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616673 ssl2.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0316674 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
16675 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
16676
Ryan Hamilton0239aac2018-05-19 00:03:1316677 spdy::SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4916678 spdy_util_.ConstructSpdyGet("https://www.a.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0316679 MockWrite spdy1_writes[] = {
bncdf80d44fd2016-07-15 20:27:4116680 CreateMockWrite(host1_req, 0),
[email protected]483fa202013-05-14 01:07:0316681 };
Ryan Hamilton0239aac2018-05-19 00:03:1316682 spdy::SpdySerializedFrame host1_resp(
Raul Tambre94493c652019-03-11 17:18:3516683 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316684 spdy::SpdySerializedFrame host1_resp_body(
bncdf80d44fd2016-07-15 20:27:4116685 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0316686 MockRead spdy1_reads[] = {
bncdf80d44fd2016-07-15 20:27:4116687 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
mmenkee24011922015-12-17 22:12:5916688 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0316689 };
16690
rdsmithebb50aa2015-11-12 03:44:3816691 // Use a separate test instance for the separate SpdySession that will be
16692 // created.
bncd16676a2016-07-20 16:23:0116693 SpdyTestUtil spdy_util_2;
Ryan Sleevib8d7ea02018-05-07 20:01:0116694 SequencedSocketData spdy1_data(spdy1_reads, spdy1_writes);
Bence Béky53a5aef2018-03-29 21:54:1216695 session_deps_.socket_factory->AddSocketDataProvider(&spdy1_data);
[email protected]483fa202013-05-14 01:07:0316696
Ryan Hamilton0239aac2018-05-19 00:03:1316697 spdy::SpdySerializedFrame host2_req(
bnc38dcd392016-02-09 23:19:4916698 spdy_util_2.ConstructSpdyGet("https://www.b.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0316699 MockWrite spdy2_writes[] = {
bncdf80d44fd2016-07-15 20:27:4116700 CreateMockWrite(host2_req, 0),
[email protected]483fa202013-05-14 01:07:0316701 };
Ryan Hamilton0239aac2018-05-19 00:03:1316702 spdy::SpdySerializedFrame host2_resp(
Raul Tambre94493c652019-03-11 17:18:3516703 spdy_util_2.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316704 spdy::SpdySerializedFrame host2_resp_body(
bncdf80d44fd2016-07-15 20:27:4116705 spdy_util_2.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0316706 MockRead spdy2_reads[] = {
bncdf80d44fd2016-07-15 20:27:4116707 CreateMockRead(host2_resp, 1), CreateMockRead(host2_resp_body, 2),
mmenkee24011922015-12-17 22:12:5916708 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0316709 };
16710
Ryan Sleevib8d7ea02018-05-07 20:01:0116711 SequencedSocketData spdy2_data(spdy2_reads, spdy2_writes);
Bence Béky53a5aef2018-03-29 21:54:1216712 session_deps_.socket_factory->AddSocketDataProvider(&spdy2_data);
[email protected]483fa202013-05-14 01:07:0316713
16714 MockWrite http_write[] = {
16715 MockWrite("GET / HTTP/1.1\r\n"
16716 "Host: www.a.com\r\n"
16717 "Connection: keep-alive\r\n\r\n"),
16718 };
16719
16720 MockRead http_read[] = {
16721 MockRead("HTTP/1.1 200 OK\r\n"),
16722 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
16723 MockRead("Content-Length: 6\r\n\r\n"),
16724 MockRead("hello!"),
16725 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116726 StaticSocketDataProvider http_data(http_read, http_write);
[email protected]483fa202013-05-14 01:07:0316727 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16728
16729 HostPortPair host_port_pair_a("www.a.com", 443);
Matt Menke2436b2f2018-12-11 18:07:1116730 SpdySessionKey spdy_session_key_a(
16731 host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
16732 SpdySessionKey::IsProxySession::kFalse, SocketTag());
[email protected]483fa202013-05-14 01:07:0316733 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616734 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0316735
16736 TestCompletionCallback callback;
16737 HttpRequestInfo request1;
16738 request1.method = "GET";
16739 request1.url = GURL("https://www.a.com/");
16740 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016741 request1.traffic_annotation =
16742 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5816743 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1916744 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0316745
tfarina42834112016-09-22 13:38:2016746 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116747 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16748 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0316749
16750 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5216751 ASSERT_TRUE(response);
16752 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0216753 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0316754 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5216755 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]483fa202013-05-14 01:07:0316756
16757 std::string response_data;
robpercival214763f2016-07-01 23:27:0116758 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0316759 EXPECT_EQ("hello!", response_data);
16760 trans.reset();
16761 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2616762 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0316763
16764 HostPortPair host_port_pair_b("www.b.com", 443);
Matt Menke2436b2f2018-12-11 18:07:1116765 SpdySessionKey spdy_session_key_b(
16766 host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
16767 SpdySessionKey::IsProxySession::kFalse, SocketTag());
[email protected]483fa202013-05-14 01:07:0316768 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616769 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0316770 HttpRequestInfo request2;
16771 request2.method = "GET";
16772 request2.url = GURL("https://www.b.com/");
16773 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016774 request2.traffic_annotation =
16775 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5816776 trans =
Jeremy Roman0579ed62017-08-29 15:56:1916777 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0316778
tfarina42834112016-09-22 13:38:2016779 rv = trans->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116780 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16781 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0316782
16783 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5216784 ASSERT_TRUE(response);
16785 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0216786 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0316787 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5216788 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0116789 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0316790 EXPECT_EQ("hello!", response_data);
16791 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616792 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0316793 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2616794 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0316795
16796 HostPortPair host_port_pair_a1("www.a.com", 80);
Matt Menke2436b2f2018-12-11 18:07:1116797 SpdySessionKey spdy_session_key_a1(
16798 host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
16799 SpdySessionKey::IsProxySession::kFalse, SocketTag());
[email protected]483fa202013-05-14 01:07:0316800 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616801 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0316802 HttpRequestInfo request3;
16803 request3.method = "GET";
16804 request3.url = GURL("http://www.a.com/");
16805 request3.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016806 request3.traffic_annotation =
16807 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5816808 trans =
Jeremy Roman0579ed62017-08-29 15:56:1916809 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0316810
tfarina42834112016-09-22 13:38:2016811 rv = trans->Start(&request3, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116812 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16813 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0316814
16815 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5216816 ASSERT_TRUE(response);
16817 ASSERT_TRUE(response->headers);
[email protected]483fa202013-05-14 01:07:0316818 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
16819 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5216820 EXPECT_FALSE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0116821 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0316822 EXPECT_EQ("hello!", response_data);
16823 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616824 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0316825 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616826 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0316827}
16828
bncd16676a2016-07-20 16:23:0116829TEST_F(HttpNetworkTransactionTest, HttpSyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0416830 HttpRequestInfo request;
16831 request.method = "GET";
bncce36dca22015-04-21 22:11:2316832 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016833 request.traffic_annotation =
16834 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416835
danakj1fd259a02016-04-16 03:17:0916836 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616837 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416838
ttuttled9dbc652015-09-29 20:00:5916839 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0416840 StaticSocketDataProvider data;
16841 data.set_connect_data(mock_connect);
16842 session_deps_.socket_factory->AddSocketDataProvider(&data);
16843
16844 TestCompletionCallback callback;
16845
tfarina42834112016-09-22 13:38:2016846 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116847 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416848
16849 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116850 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0416851
[email protected]79e1fd62013-06-20 06:50:0416852 // We don't care whether this succeeds or fails, but it shouldn't crash.
16853 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616854 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4716855
16856 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1616857 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4716858 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0116859 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5916860
16861 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1616862 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5916863 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0416864}
16865
bncd16676a2016-07-20 16:23:0116866TEST_F(HttpNetworkTransactionTest, HttpAsyncConnectError) {
[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 Halavatib5e433e2018-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
ttuttled9dbc652015-09-29 20:00:5916876 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0416877 StaticSocketDataProvider data;
16878 data.set_connect_data(mock_connect);
16879 session_deps_.socket_factory->AddSocketDataProvider(&data);
16880
16881 TestCompletionCallback callback;
16882
tfarina42834112016-09-22 13:38:2016883 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116884 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416885
16886 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116887 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0416888
[email protected]79e1fd62013-06-20 06:50:0416889 // We don't care whether this succeeds or fails, but it shouldn't crash.
16890 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616891 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4716892
16893 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1616894 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4716895 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0116896 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5916897
16898 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1616899 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5916900 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0416901}
16902
bncd16676a2016-07-20 16:23:0116903TEST_F(HttpNetworkTransactionTest, HttpSyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0416904 HttpRequestInfo request;
16905 request.method = "GET";
bncce36dca22015-04-21 22:11:2316906 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016907 request.traffic_annotation =
16908 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416909
danakj1fd259a02016-04-16 03:17:0916910 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616911 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416912
16913 MockWrite data_writes[] = {
16914 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16915 };
16916 MockRead data_reads[] = {
16917 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
16918 };
16919
Ryan Sleevib8d7ea02018-05-07 20:01:0116920 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0416921 session_deps_.socket_factory->AddSocketDataProvider(&data);
16922
16923 TestCompletionCallback callback;
16924
tfarina42834112016-09-22 13:38:2016925 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116926 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416927
16928 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116929 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416930
[email protected]79e1fd62013-06-20 06:50:0416931 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616932 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416933 EXPECT_TRUE(request_headers.HasHeader("Host"));
16934}
16935
bncd16676a2016-07-20 16:23:0116936TEST_F(HttpNetworkTransactionTest, HttpAsyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0416937 HttpRequestInfo request;
16938 request.method = "GET";
bncce36dca22015-04-21 22:11:2316939 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016940 request.traffic_annotation =
16941 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416942
danakj1fd259a02016-04-16 03:17:0916943 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616944 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416945
16946 MockWrite data_writes[] = {
16947 MockWrite(ASYNC, ERR_CONNECTION_RESET),
16948 };
16949 MockRead data_reads[] = {
16950 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
16951 };
16952
Ryan Sleevib8d7ea02018-05-07 20:01:0116953 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0416954 session_deps_.socket_factory->AddSocketDataProvider(&data);
16955
16956 TestCompletionCallback callback;
16957
tfarina42834112016-09-22 13:38:2016958 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116959 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416960
16961 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116962 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416963
[email protected]79e1fd62013-06-20 06:50:0416964 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616965 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416966 EXPECT_TRUE(request_headers.HasHeader("Host"));
16967}
16968
bncd16676a2016-07-20 16:23:0116969TEST_F(HttpNetworkTransactionTest, HttpSyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0416970 HttpRequestInfo request;
16971 request.method = "GET";
bncce36dca22015-04-21 22:11:2316972 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016973 request.traffic_annotation =
16974 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416975
danakj1fd259a02016-04-16 03:17:0916976 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616977 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416978
16979 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2316980 MockWrite(
16981 "GET / HTTP/1.1\r\n"
16982 "Host: www.example.org\r\n"
16983 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0416984 };
16985 MockRead data_reads[] = {
16986 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
16987 };
16988
Ryan Sleevib8d7ea02018-05-07 20:01:0116989 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0416990 session_deps_.socket_factory->AddSocketDataProvider(&data);
16991
16992 TestCompletionCallback callback;
16993
tfarina42834112016-09-22 13:38:2016994 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116995 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416996
16997 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116998 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416999
[email protected]79e1fd62013-06-20 06:50:0417000 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1617001 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0417002 EXPECT_TRUE(request_headers.HasHeader("Host"));
17003}
17004
bncd16676a2016-07-20 16:23:0117005TEST_F(HttpNetworkTransactionTest, HttpAsyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0417006 HttpRequestInfo request;
17007 request.method = "GET";
bncce36dca22015-04-21 22:11:2317008 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017009 request.traffic_annotation =
17010 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0417011
danakj1fd259a02016-04-16 03:17:0917012 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617013 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0417014
17015 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2317016 MockWrite(
17017 "GET / HTTP/1.1\r\n"
17018 "Host: www.example.org\r\n"
17019 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0417020 };
17021 MockRead data_reads[] = {
17022 MockRead(ASYNC, ERR_CONNECTION_RESET),
17023 };
17024
Ryan Sleevib8d7ea02018-05-07 20:01:0117025 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0417026 session_deps_.socket_factory->AddSocketDataProvider(&data);
17027
17028 TestCompletionCallback callback;
17029
tfarina42834112016-09-22 13:38:2017030 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117031 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0417032
17033 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117034 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0417035
[email protected]79e1fd62013-06-20 06:50:0417036 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1617037 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0417038 EXPECT_TRUE(request_headers.HasHeader("Host"));
17039}
17040
bncd16676a2016-07-20 16:23:0117041TEST_F(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
[email protected]79e1fd62013-06-20 06:50:0417042 HttpRequestInfo request;
17043 request.method = "GET";
bncce36dca22015-04-21 22:11:2317044 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0417045 request.extra_headers.SetHeader("X-Foo", "bar");
Ramin Halavatib5e433e2018-02-07 07:41:1017046 request.traffic_annotation =
17047 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0417048
danakj1fd259a02016-04-16 03:17:0917049 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617050 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0417051
17052 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2317053 MockWrite(
17054 "GET / HTTP/1.1\r\n"
17055 "Host: www.example.org\r\n"
17056 "Connection: keep-alive\r\n"
17057 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0417058 };
17059 MockRead data_reads[] = {
17060 MockRead("HTTP/1.1 200 OK\r\n"
17061 "Content-Length: 5\r\n\r\n"
17062 "hello"),
17063 MockRead(ASYNC, ERR_UNEXPECTED),
17064 };
17065
Ryan Sleevib8d7ea02018-05-07 20:01:0117066 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0417067 session_deps_.socket_factory->AddSocketDataProvider(&data);
17068
17069 TestCompletionCallback callback;
17070
tfarina42834112016-09-22 13:38:2017071 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117072 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0417073
17074 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117075 EXPECT_THAT(rv, IsOk());
[email protected]79e1fd62013-06-20 06:50:0417076
17077 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1617078 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0417079 std::string foo;
17080 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
17081 EXPECT_EQ("bar", foo);
17082}
17083
[email protected]043b68c82013-08-22 23:41:5217084// Tests that when a used socket is returned to the SSL socket pool, it's closed
17085// if the transport socket pool is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0117086TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
[email protected]043b68c82013-08-22 23:41:5217087 ClientSocketPoolManager::set_max_sockets_per_group(
17088 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
17089 ClientSocketPoolManager::set_max_sockets_per_pool(
17090 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
17091
17092 // Set up SSL request.
17093
17094 HttpRequestInfo ssl_request;
17095 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2317096 ssl_request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017097 ssl_request.traffic_annotation =
17098 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5217099
17100 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2317101 MockWrite(
17102 "GET / HTTP/1.1\r\n"
17103 "Host: www.example.org\r\n"
17104 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5217105 };
17106 MockRead ssl_reads[] = {
17107 MockRead("HTTP/1.1 200 OK\r\n"),
17108 MockRead("Content-Length: 11\r\n\r\n"),
17109 MockRead("hello world"),
17110 MockRead(SYNCHRONOUS, OK),
17111 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117112 StaticSocketDataProvider ssl_data(ssl_reads, ssl_writes);
[email protected]043b68c82013-08-22 23:41:5217113 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
17114
17115 SSLSocketDataProvider ssl(ASYNC, OK);
17116 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
17117
17118 // Set up HTTP request.
17119
17120 HttpRequestInfo http_request;
17121 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2317122 http_request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017123 http_request.traffic_annotation =
17124 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5217125
17126 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2317127 MockWrite(
17128 "GET / HTTP/1.1\r\n"
17129 "Host: www.example.org\r\n"
17130 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5217131 };
17132 MockRead http_reads[] = {
17133 MockRead("HTTP/1.1 200 OK\r\n"),
17134 MockRead("Content-Length: 7\r\n\r\n"),
17135 MockRead("falafel"),
17136 MockRead(SYNCHRONOUS, OK),
17137 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117138 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]043b68c82013-08-22 23:41:5217139 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
17140
danakj1fd259a02016-04-16 03:17:0917141 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5217142
17143 // Start the SSL request.
17144 TestCompletionCallback ssl_callback;
bnc691fda62016-08-12 00:43:1617145 HttpNetworkTransaction ssl_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2017146 ASSERT_EQ(ERR_IO_PENDING,
17147 ssl_trans.Start(&ssl_request, ssl_callback.callback(),
17148 NetLogWithSource()));
[email protected]043b68c82013-08-22 23:41:5217149
17150 // Start the HTTP request. Pool should stall.
17151 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1617152 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2017153 ASSERT_EQ(ERR_IO_PENDING,
17154 http_trans.Start(&http_request, http_callback.callback(),
17155 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4117156 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5217157
17158 // Wait for response from SSL request.
robpercival214763f2016-07-01 23:27:0117159 ASSERT_THAT(ssl_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5217160 std::string response_data;
bnc691fda62016-08-12 00:43:1617161 ASSERT_THAT(ReadTransaction(&ssl_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5217162 EXPECT_EQ("hello world", response_data);
17163
17164 // The SSL socket should automatically be closed, so the HTTP request can
17165 // start.
Matt Menke9d5e2c92019-02-05 01:42:2317166 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
dcheng48459ac22014-08-26 00:46:4117167 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5217168
17169 // The HTTP request can now complete.
robpercival214763f2016-07-01 23:27:0117170 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
bnc691fda62016-08-12 00:43:1617171 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5217172 EXPECT_EQ("falafel", response_data);
17173
dcheng48459ac22014-08-26 00:46:4117174 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5217175}
17176
17177// Tests that when a SSL connection is established but there's no corresponding
17178// request that needs it, the new socket is closed if the transport socket pool
17179// is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0117180TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
[email protected]043b68c82013-08-22 23:41:5217181 ClientSocketPoolManager::set_max_sockets_per_group(
17182 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
17183 ClientSocketPoolManager::set_max_sockets_per_pool(
17184 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
17185
17186 // Set up an ssl request.
17187
17188 HttpRequestInfo ssl_request;
17189 ssl_request.method = "GET";
17190 ssl_request.url = GURL("https://www.foopy.com/");
Ramin Halavatib5e433e2018-02-07 07:41:1017191 ssl_request.traffic_annotation =
17192 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5217193
17194 // No data will be sent on the SSL socket.
17195 StaticSocketDataProvider ssl_data;
17196 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
17197
17198 SSLSocketDataProvider ssl(ASYNC, OK);
17199 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
17200
17201 // Set up HTTP request.
17202
17203 HttpRequestInfo http_request;
17204 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2317205 http_request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017206 http_request.traffic_annotation =
17207 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5217208
17209 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2317210 MockWrite(
17211 "GET / HTTP/1.1\r\n"
17212 "Host: www.example.org\r\n"
17213 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5217214 };
17215 MockRead http_reads[] = {
17216 MockRead("HTTP/1.1 200 OK\r\n"),
17217 MockRead("Content-Length: 7\r\n\r\n"),
17218 MockRead("falafel"),
17219 MockRead(SYNCHRONOUS, OK),
17220 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117221 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]043b68c82013-08-22 23:41:5217222 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
17223
danakj1fd259a02016-04-16 03:17:0917224 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5217225
17226 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
17227 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2917228 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
nharper8cdb0fb2016-04-22 21:34:5917229 http_stream_factory->PreconnectStreams(1, ssl_request);
Matt Menke9d5e2c92019-02-05 01:42:2317230 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5217231
17232 // Start the HTTP request. Pool should stall.
17233 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1617234 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2017235 ASSERT_EQ(ERR_IO_PENDING,
17236 http_trans.Start(&http_request, http_callback.callback(),
17237 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4117238 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5217239
17240 // The SSL connection will automatically be closed once the connection is
17241 // established, to let the HTTP request start.
robpercival214763f2016-07-01 23:27:0117242 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5217243 std::string response_data;
bnc691fda62016-08-12 00:43:1617244 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5217245 EXPECT_EQ("falafel", response_data);
17246
dcheng48459ac22014-08-26 00:46:4117247 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5217248}
17249
bncd16676a2016-07-20 16:23:0117250TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0917251 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217252 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917253 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217254 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417255
17256 HttpRequestInfo request;
17257 request.method = "POST";
17258 request.url = GURL("http://www.foo.com/");
17259 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017260 request.traffic_annotation =
17261 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417262
danakj1fd259a02016-04-16 03:17:0917263 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617264 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417265 // Send headers successfully, but get an error while sending the body.
17266 MockWrite data_writes[] = {
17267 MockWrite("POST / HTTP/1.1\r\n"
17268 "Host: www.foo.com\r\n"
17269 "Connection: keep-alive\r\n"
17270 "Content-Length: 3\r\n\r\n"),
17271 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17272 };
17273
17274 MockRead data_reads[] = {
17275 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
17276 MockRead("hello world"),
17277 MockRead(SYNCHRONOUS, OK),
17278 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117279 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417280 session_deps_.socket_factory->AddSocketDataProvider(&data);
17281
17282 TestCompletionCallback callback;
17283
tfarina42834112016-09-22 13:38:2017284 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117285 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417286
17287 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117288 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417289
bnc691fda62016-08-12 00:43:1617290 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5217291 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5417292
wezca1070932016-05-26 20:30:5217293 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5417294 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
17295
17296 std::string response_data;
bnc691fda62016-08-12 00:43:1617297 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0117298 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417299 EXPECT_EQ("hello world", response_data);
17300}
17301
17302// This test makes sure the retry logic doesn't trigger when reading an error
17303// response from a server that rejected a POST with a CONNECTION_RESET.
bncd16676a2016-07-20 16:23:0117304TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5417305 PostReadsErrorResponseAfterResetOnReusedSocket) {
danakj1fd259a02016-04-16 03:17:0917306 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5417307 MockWrite data_writes[] = {
17308 MockWrite("GET / HTTP/1.1\r\n"
17309 "Host: www.foo.com\r\n"
17310 "Connection: keep-alive\r\n\r\n"),
17311 MockWrite("POST / HTTP/1.1\r\n"
17312 "Host: www.foo.com\r\n"
17313 "Connection: keep-alive\r\n"
17314 "Content-Length: 3\r\n\r\n"),
17315 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17316 };
17317
17318 MockRead data_reads[] = {
17319 MockRead("HTTP/1.1 200 Peachy\r\n"
17320 "Content-Length: 14\r\n\r\n"),
17321 MockRead("first response"),
17322 MockRead("HTTP/1.1 400 Not OK\r\n"
17323 "Content-Length: 15\r\n\r\n"),
17324 MockRead("second response"),
17325 MockRead(SYNCHRONOUS, OK),
17326 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117327 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417328 session_deps_.socket_factory->AddSocketDataProvider(&data);
17329
17330 TestCompletionCallback callback;
17331 HttpRequestInfo request1;
17332 request1.method = "GET";
17333 request1.url = GURL("http://www.foo.com/");
17334 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1017335 request1.traffic_annotation =
17336 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417337
bnc87dcefc2017-05-25 12:47:5817338 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:1917339 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2017340 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117341 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417342
17343 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117344 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417345
17346 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:5217347 ASSERT_TRUE(response1);
[email protected]02d74a02014-04-23 18:10:5417348
wezca1070932016-05-26 20:30:5217349 EXPECT_TRUE(response1->headers);
[email protected]02d74a02014-04-23 18:10:5417350 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
17351
17352 std::string response_data1;
17353 rv = ReadTransaction(trans1.get(), &response_data1);
robpercival214763f2016-07-01 23:27:0117354 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417355 EXPECT_EQ("first response", response_data1);
17356 // Delete the transaction to release the socket back into the socket pool.
17357 trans1.reset();
17358
danakj1fd259a02016-04-16 03:17:0917359 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217360 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917361 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217362 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417363
17364 HttpRequestInfo request2;
17365 request2.method = "POST";
17366 request2.url = GURL("http://www.foo.com/");
17367 request2.upload_data_stream = &upload_data_stream;
17368 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1017369 request2.traffic_annotation =
17370 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417371
bnc691fda62016-08-12 00:43:1617372 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2017373 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117374 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417375
17376 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117377 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417378
bnc691fda62016-08-12 00:43:1617379 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5217380 ASSERT_TRUE(response2);
[email protected]02d74a02014-04-23 18:10:5417381
wezca1070932016-05-26 20:30:5217382 EXPECT_TRUE(response2->headers);
[email protected]02d74a02014-04-23 18:10:5417383 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
17384
17385 std::string response_data2;
bnc691fda62016-08-12 00:43:1617386 rv = ReadTransaction(&trans2, &response_data2);
robpercival214763f2016-07-01 23:27:0117387 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417388 EXPECT_EQ("second response", response_data2);
17389}
17390
bncd16676a2016-07-20 16:23:0117391TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5417392 PostReadsErrorResponseAfterResetPartialBodySent) {
danakj1fd259a02016-04-16 03:17:0917393 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217394 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917395 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217396 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417397
17398 HttpRequestInfo request;
17399 request.method = "POST";
17400 request.url = GURL("http://www.foo.com/");
17401 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017402 request.traffic_annotation =
17403 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417404
danakj1fd259a02016-04-16 03:17:0917405 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617406 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417407 // Send headers successfully, but get an error while sending the body.
17408 MockWrite data_writes[] = {
17409 MockWrite("POST / HTTP/1.1\r\n"
17410 "Host: www.foo.com\r\n"
17411 "Connection: keep-alive\r\n"
17412 "Content-Length: 3\r\n\r\n"
17413 "fo"),
17414 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17415 };
17416
17417 MockRead data_reads[] = {
17418 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
17419 MockRead("hello world"),
17420 MockRead(SYNCHRONOUS, OK),
17421 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117422 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417423 session_deps_.socket_factory->AddSocketDataProvider(&data);
17424
17425 TestCompletionCallback callback;
17426
tfarina42834112016-09-22 13:38:2017427 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117428 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417429
17430 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117431 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417432
bnc691fda62016-08-12 00:43:1617433 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5217434 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5417435
wezca1070932016-05-26 20:30:5217436 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5417437 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
17438
17439 std::string response_data;
bnc691fda62016-08-12 00:43:1617440 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0117441 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417442 EXPECT_EQ("hello world", response_data);
17443}
17444
17445// This tests the more common case than the previous test, where headers and
17446// body are not merged into a single request.
bncd16676a2016-07-20 16:23:0117447TEST_F(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
mmenkecbc2b712014-10-09 20:29:0717448 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5417449
17450 HttpRequestInfo request;
17451 request.method = "POST";
17452 request.url = GURL("http://www.foo.com/");
17453 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017454 request.traffic_annotation =
17455 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417456
danakj1fd259a02016-04-16 03:17:0917457 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617458 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417459 // Send headers successfully, but get an error while sending the body.
17460 MockWrite data_writes[] = {
17461 MockWrite("POST / HTTP/1.1\r\n"
17462 "Host: www.foo.com\r\n"
17463 "Connection: keep-alive\r\n"
17464 "Transfer-Encoding: chunked\r\n\r\n"),
17465 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17466 };
17467
17468 MockRead data_reads[] = {
17469 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
17470 MockRead("hello world"),
17471 MockRead(SYNCHRONOUS, OK),
17472 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117473 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417474 session_deps_.socket_factory->AddSocketDataProvider(&data);
17475
17476 TestCompletionCallback callback;
17477
tfarina42834112016-09-22 13:38:2017478 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117479 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417480 // Make sure the headers are sent before adding a chunk. This ensures that
17481 // they can't be merged with the body in a single send. Not currently
17482 // necessary since a chunked body is never merged with headers, but this makes
17483 // the test more future proof.
17484 base::RunLoop().RunUntilIdle();
17485
mmenkecbc2b712014-10-09 20:29:0717486 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5417487
17488 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117489 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417490
bnc691fda62016-08-12 00:43:1617491 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5217492 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5417493
wezca1070932016-05-26 20:30:5217494 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5417495 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
17496
17497 std::string response_data;
bnc691fda62016-08-12 00:43:1617498 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0117499 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417500 EXPECT_EQ("hello world", response_data);
17501}
17502
bncd16676a2016-07-20 16:23:0117503TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0917504 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217505 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917506 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217507 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417508
17509 HttpRequestInfo request;
17510 request.method = "POST";
17511 request.url = GURL("http://www.foo.com/");
17512 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017513 request.traffic_annotation =
17514 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417515
danakj1fd259a02016-04-16 03:17:0917516 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617517 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417518
17519 MockWrite data_writes[] = {
17520 MockWrite("POST / HTTP/1.1\r\n"
17521 "Host: www.foo.com\r\n"
17522 "Connection: keep-alive\r\n"
17523 "Content-Length: 3\r\n\r\n"),
17524 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17525 };
17526
17527 MockRead data_reads[] = {
17528 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
17529 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
17530 MockRead("hello world"),
17531 MockRead(SYNCHRONOUS, OK),
17532 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117533 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417534 session_deps_.socket_factory->AddSocketDataProvider(&data);
17535
17536 TestCompletionCallback callback;
17537
tfarina42834112016-09-22 13:38:2017538 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117539 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417540
17541 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117542 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417543
bnc691fda62016-08-12 00:43:1617544 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5217545 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5417546
wezca1070932016-05-26 20:30:5217547 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5417548 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
17549
17550 std::string response_data;
bnc691fda62016-08-12 00:43:1617551 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0117552 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417553 EXPECT_EQ("hello world", response_data);
17554}
17555
bncd16676a2016-07-20 16:23:0117556TEST_F(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0917557 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217558 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917559 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217560 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417561
17562 HttpRequestInfo request;
17563 request.method = "POST";
17564 request.url = GURL("http://www.foo.com/");
17565 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017566 request.traffic_annotation =
17567 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417568
danakj1fd259a02016-04-16 03:17:0917569 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617570 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417571 // Send headers successfully, but get an error while sending the body.
17572 MockWrite data_writes[] = {
17573 MockWrite("POST / HTTP/1.1\r\n"
17574 "Host: www.foo.com\r\n"
17575 "Connection: keep-alive\r\n"
17576 "Content-Length: 3\r\n\r\n"),
17577 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17578 };
17579
17580 MockRead data_reads[] = {
17581 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
17582 MockRead("hello world"),
17583 MockRead(SYNCHRONOUS, OK),
17584 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117585 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417586 session_deps_.socket_factory->AddSocketDataProvider(&data);
17587
17588 TestCompletionCallback callback;
17589
tfarina42834112016-09-22 13:38:2017590 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117591 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417592
17593 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117594 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417595}
17596
bncd16676a2016-07-20 16:23:0117597TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5417598 PostIgnoresNonErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0917599 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217600 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917601 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217602 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417603
17604 HttpRequestInfo request;
17605 request.method = "POST";
17606 request.url = GURL("http://www.foo.com/");
17607 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017608 request.traffic_annotation =
17609 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417610
danakj1fd259a02016-04-16 03:17:0917611 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617612 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417613 // Send headers successfully, but get an error while sending the body.
17614 MockWrite data_writes[] = {
17615 MockWrite("POST / HTTP/1.1\r\n"
17616 "Host: www.foo.com\r\n"
17617 "Connection: keep-alive\r\n"
17618 "Content-Length: 3\r\n\r\n"),
17619 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17620 };
17621
17622 MockRead data_reads[] = {
17623 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
17624 MockRead("HTTP/1.0 302 Redirect\r\n"),
17625 MockRead("Location: http://somewhere-else.com/\r\n"),
17626 MockRead("Content-Length: 0\r\n\r\n"),
17627 MockRead(SYNCHRONOUS, OK),
17628 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117629 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417630 session_deps_.socket_factory->AddSocketDataProvider(&data);
17631
17632 TestCompletionCallback callback;
17633
tfarina42834112016-09-22 13:38:2017634 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117635 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417636
17637 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117638 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417639}
17640
bncd16676a2016-07-20 16:23:0117641TEST_F(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0917642 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217643 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917644 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217645 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417646
17647 HttpRequestInfo request;
17648 request.method = "POST";
17649 request.url = GURL("http://www.foo.com/");
17650 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017651 request.traffic_annotation =
17652 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417653
danakj1fd259a02016-04-16 03:17:0917654 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617655 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417656 // Send headers successfully, but get an error while sending the body.
17657 MockWrite data_writes[] = {
17658 MockWrite("POST / HTTP/1.1\r\n"
17659 "Host: www.foo.com\r\n"
17660 "Connection: keep-alive\r\n"
17661 "Content-Length: 3\r\n\r\n"),
17662 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17663 };
17664
17665 MockRead data_reads[] = {
17666 MockRead("HTTP 0.9 rocks!"),
17667 MockRead(SYNCHRONOUS, OK),
17668 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117669 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417670 session_deps_.socket_factory->AddSocketDataProvider(&data);
17671
17672 TestCompletionCallback callback;
17673
tfarina42834112016-09-22 13:38:2017674 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117675 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417676
17677 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117678 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417679}
17680
bncd16676a2016-07-20 16:23:0117681TEST_F(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
danakj1fd259a02016-04-16 03:17:0917682 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217683 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917684 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217685 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417686
17687 HttpRequestInfo request;
17688 request.method = "POST";
17689 request.url = GURL("http://www.foo.com/");
17690 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017691 request.traffic_annotation =
17692 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417693
danakj1fd259a02016-04-16 03:17:0917694 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617695 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417696 // Send headers successfully, but get an error while sending the body.
17697 MockWrite data_writes[] = {
17698 MockWrite("POST / HTTP/1.1\r\n"
17699 "Host: www.foo.com\r\n"
17700 "Connection: keep-alive\r\n"
17701 "Content-Length: 3\r\n\r\n"),
17702 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17703 };
17704
17705 MockRead data_reads[] = {
17706 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
17707 MockRead(SYNCHRONOUS, OK),
17708 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117709 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417710 session_deps_.socket_factory->AddSocketDataProvider(&data);
17711
17712 TestCompletionCallback callback;
17713
tfarina42834112016-09-22 13:38:2017714 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117715 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417716
17717 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117718 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417719}
17720
Bence Békydca6bd92018-01-30 13:43:0617721#if BUILDFLAG(ENABLE_WEBSOCKETS)
17722
17723namespace {
17724
17725void AddWebSocketHeaders(HttpRequestHeaders* headers) {
17726 headers->SetHeader("Connection", "Upgrade");
17727 headers->SetHeader("Upgrade", "websocket");
17728 headers->SetHeader("Origin", "http://www.example.org");
17729 headers->SetHeader("Sec-WebSocket-Version", "13");
Bence Békydca6bd92018-01-30 13:43:0617730}
17731
17732} // namespace
17733
17734TEST_F(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
Bence Béky2fcf4fa2018-04-06 20:06:0117735 for (bool secure : {true, false}) {
17736 MockWrite data_writes[] = {
17737 MockWrite("GET / HTTP/1.1\r\n"
17738 "Host: www.example.org\r\n"
17739 "Connection: Upgrade\r\n"
17740 "Upgrade: websocket\r\n"
17741 "Origin: http://www.example.org\r\n"
17742 "Sec-WebSocket-Version: 13\r\n"
17743 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
17744 "Sec-WebSocket-Extensions: permessage-deflate; "
17745 "client_max_window_bits\r\n\r\n")};
17746
17747 MockRead data_reads[] = {
17748 MockRead("HTTP/1.1 101 Switching Protocols\r\n"
17749 "Upgrade: websocket\r\n"
17750 "Connection: Upgrade\r\n"
17751 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
17752
Ryan Sleevib8d7ea02018-05-07 20:01:0117753 StaticSocketDataProvider data(data_reads, data_writes);
Bence Béky2fcf4fa2018-04-06 20:06:0117754 session_deps_.socket_factory->AddSocketDataProvider(&data);
17755 SSLSocketDataProvider ssl(ASYNC, OK);
17756 if (secure)
17757 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
Bence Békydca6bd92018-01-30 13:43:0617758
17759 HttpRequestInfo request;
17760 request.method = "GET";
Bence Béky2fcf4fa2018-04-06 20:06:0117761 request.url =
17762 GURL(secure ? "ws://www.example.org/" : "wss://www.example.org/");
17763 AddWebSocketHeaders(&request.extra_headers);
Ramin Halavatib5e433e2018-02-07 07:41:1017764 request.traffic_annotation =
17765 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Békydca6bd92018-01-30 13:43:0617766
Bence Béky2fcf4fa2018-04-06 20:06:0117767 TestWebSocketHandshakeStreamCreateHelper
17768 websocket_handshake_stream_create_helper;
Bence Béky8d1c6052018-02-07 12:48:1517769
Bence Béky2fcf4fa2018-04-06 20:06:0117770 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Bence Békydca6bd92018-01-30 13:43:0617771 HttpNetworkTransaction trans(LOW, session.get());
17772 trans.SetWebSocketHandshakeStreamCreateHelper(
Bence Béky2fcf4fa2018-04-06 20:06:0117773 &websocket_handshake_stream_create_helper);
Bence Békydca6bd92018-01-30 13:43:0617774
17775 TestCompletionCallback callback;
Bence Béky2fcf4fa2018-04-06 20:06:0117776 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17777 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Bence Békydca6bd92018-01-30 13:43:0617778
Bence Béky2fcf4fa2018-04-06 20:06:0117779 const HttpStreamRequest* stream_request = trans.stream_request_.get();
17780 ASSERT_TRUE(stream_request);
17781 EXPECT_EQ(&websocket_handshake_stream_create_helper,
17782 stream_request->websocket_handshake_stream_create_helper());
17783
17784 rv = callback.WaitForResult();
17785 EXPECT_THAT(rv, IsOk());
17786
17787 EXPECT_TRUE(data.AllReadDataConsumed());
17788 EXPECT_TRUE(data.AllWriteDataConsumed());
Bence Békydca6bd92018-01-30 13:43:0617789 }
17790}
17791
Adam Rice425cf122015-01-19 06:18:2417792// Verify that proxy headers are not sent to the destination server when
17793// establishing a tunnel for a secure WebSocket connection.
bncd16676a2016-07-20 16:23:0117794TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
Adam Rice425cf122015-01-19 06:18:2417795 HttpRequestInfo request;
17796 request.method = "GET";
bncce36dca22015-04-21 22:11:2317797 request.url = GURL("wss://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017798 request.traffic_annotation =
17799 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417800 AddWebSocketHeaders(&request.extra_headers);
17801
17802 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:5917803 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4917804 ProxyResolutionService::CreateFixedFromPacResult(
17805 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417806
danakj1fd259a02016-04-16 03:17:0917807 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2417808
17809 // Since a proxy is configured, try to establish a tunnel.
17810 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1717811 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
17812 "Host: www.example.org:443\r\n"
17813 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417814
17815 // After calling trans->RestartWithAuth(), this is the request we should
17816 // be issuing -- the final header line contains the credentials.
rsleevidb16bb02015-11-12 23:47:1717817 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
17818 "Host: www.example.org:443\r\n"
17819 "Proxy-Connection: keep-alive\r\n"
17820 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417821
rsleevidb16bb02015-11-12 23:47:1717822 MockWrite("GET / HTTP/1.1\r\n"
17823 "Host: www.example.org\r\n"
17824 "Connection: Upgrade\r\n"
17825 "Upgrade: websocket\r\n"
17826 "Origin: http://www.example.org\r\n"
17827 "Sec-WebSocket-Version: 13\r\n"
Bence Béky8d1c6052018-02-07 12:48:1517828 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
17829 "Sec-WebSocket-Extensions: permessage-deflate; "
17830 "client_max_window_bits\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417831
17832 // The proxy responds to the connect with a 407, using a persistent
17833 // connection.
17834 MockRead data_reads[] = {
17835 // No credentials.
Bence Béky8d1c6052018-02-07 12:48:1517836 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"
17837 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
17838 "Content-Length: 0\r\n"
17839 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417840
17841 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
17842
Bence Béky8d1c6052018-02-07 12:48:1517843 MockRead("HTTP/1.1 101 Switching Protocols\r\n"
17844 "Upgrade: websocket\r\n"
17845 "Connection: Upgrade\r\n"
17846 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417847
Ryan Sleevib8d7ea02018-05-07 20:01:0117848 StaticSocketDataProvider data(data_reads, data_writes);
Adam Rice425cf122015-01-19 06:18:2417849 session_deps_.socket_factory->AddSocketDataProvider(&data);
17850 SSLSocketDataProvider ssl(ASYNC, OK);
17851 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
17852
Bence Béky8d1c6052018-02-07 12:48:1517853 TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
17854
bnc87dcefc2017-05-25 12:47:5817855 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917856 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2417857 trans->SetWebSocketHandshakeStreamCreateHelper(
17858 &websocket_stream_create_helper);
17859
17860 {
17861 TestCompletionCallback callback;
17862
tfarina42834112016-09-22 13:38:2017863 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117864 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2417865
17866 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117867 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2417868 }
17869
17870 const HttpResponseInfo* response = trans->GetResponseInfo();
17871 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5217872 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2417873 EXPECT_EQ(407, response->headers->response_code());
17874
17875 {
17876 TestCompletionCallback callback;
17877
17878 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
17879 callback.callback());
robpercival214763f2016-07-01 23:27:0117880 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2417881
17882 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117883 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2417884 }
17885
17886 response = trans->GetResponseInfo();
17887 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5217888 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2417889
17890 EXPECT_EQ(101, response->headers->response_code());
17891
17892 trans.reset();
17893 session->CloseAllConnections();
17894}
17895
17896// Verify that proxy headers are not sent to the destination server when
17897// establishing a tunnel for an insecure WebSocket connection.
17898// This requires the authentication info to be injected into the auth cache
17899// due to crbug.com/395064
17900// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
bncd16676a2016-07-20 16:23:0117901TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
Adam Rice425cf122015-01-19 06:18:2417902 HttpRequestInfo request;
17903 request.method = "GET";
bncce36dca22015-04-21 22:11:2317904 request.url = GURL("ws://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017905 request.traffic_annotation =
17906 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417907 AddWebSocketHeaders(&request.extra_headers);
17908
17909 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:5917910 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4917911 ProxyResolutionService::CreateFixedFromPacResult(
17912 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417913
danakj1fd259a02016-04-16 03:17:0917914 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2417915
17916 MockWrite data_writes[] = {
17917 // Try to establish a tunnel for the WebSocket connection, with
17918 // credentials. Because WebSockets have a separate set of socket pools,
17919 // they cannot and will not use the same TCP/IP connection as the
17920 // preflight HTTP request.
Bence Béky8d1c6052018-02-07 12:48:1517921 MockWrite("CONNECT www.example.org:80 HTTP/1.1\r\n"
17922 "Host: www.example.org:80\r\n"
17923 "Proxy-Connection: keep-alive\r\n"
17924 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417925
Bence Béky8d1c6052018-02-07 12:48:1517926 MockWrite("GET / HTTP/1.1\r\n"
17927 "Host: www.example.org\r\n"
17928 "Connection: Upgrade\r\n"
17929 "Upgrade: websocket\r\n"
17930 "Origin: http://www.example.org\r\n"
17931 "Sec-WebSocket-Version: 13\r\n"
17932 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
17933 "Sec-WebSocket-Extensions: permessage-deflate; "
17934 "client_max_window_bits\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417935
17936 MockRead data_reads[] = {
17937 // HTTP CONNECT with credentials.
17938 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
17939
17940 // WebSocket connection established inside tunnel.
Bence Béky8d1c6052018-02-07 12:48:1517941 MockRead("HTTP/1.1 101 Switching Protocols\r\n"
17942 "Upgrade: websocket\r\n"
17943 "Connection: Upgrade\r\n"
17944 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417945
Ryan Sleevib8d7ea02018-05-07 20:01:0117946 StaticSocketDataProvider data(data_reads, data_writes);
Adam Rice425cf122015-01-19 06:18:2417947 session_deps_.socket_factory->AddSocketDataProvider(&data);
17948
17949 session->http_auth_cache()->Add(
17950 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
17951 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
17952
Bence Béky8d1c6052018-02-07 12:48:1517953 TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
17954
bnc87dcefc2017-05-25 12:47:5817955 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917956 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2417957 trans->SetWebSocketHandshakeStreamCreateHelper(
17958 &websocket_stream_create_helper);
17959
17960 TestCompletionCallback callback;
17961
tfarina42834112016-09-22 13:38:2017962 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117963 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2417964
17965 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117966 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2417967
17968 const HttpResponseInfo* response = trans->GetResponseInfo();
17969 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5217970 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2417971
17972 EXPECT_EQ(101, response->headers->response_code());
17973
17974 trans.reset();
17975 session->CloseAllConnections();
17976}
17977
Matt Menke1d6093e32019-03-22 17:33:4317978// WebSockets over QUIC is not supported, including over QUIC proxies.
17979TEST_F(HttpNetworkTransactionTest, WebSocketNotSentOverQuicProxy) {
17980 for (bool secure : {true, false}) {
17981 SCOPED_TRACE(secure);
17982 session_deps_.proxy_resolution_service =
17983 ProxyResolutionService::CreateFixedFromPacResult(
17984 "QUIC myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
17985 session_deps_.enable_quic = true;
17986
17987 HttpRequestInfo request;
17988 request.url =
17989 GURL(secure ? "ws://www.example.org/" : "wss://www.example.org/");
17990 AddWebSocketHeaders(&request.extra_headers);
17991 request.traffic_annotation =
17992 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
17993
17994 TestWebSocketHandshakeStreamCreateHelper
17995 websocket_handshake_stream_create_helper;
17996
17997 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17998 HttpNetworkTransaction trans(LOW, session.get());
17999 trans.SetWebSocketHandshakeStreamCreateHelper(
18000 &websocket_handshake_stream_create_helper);
18001
18002 TestCompletionCallback callback;
18003 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18004 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18005
18006 rv = callback.WaitForResult();
18007 EXPECT_THAT(rv, IsError(ERR_NO_SUPPORTED_PROXIES));
18008 }
18009}
18010
Bence Békydca6bd92018-01-30 13:43:0618011#endif // BUILDFLAG(ENABLE_WEBSOCKETS)
18012
bncd16676a2016-07-20 16:23:0118013TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost) {
danakj1fd259a02016-04-16 03:17:0918014 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2218015 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1918016 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2218017 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2218018
18019 HttpRequestInfo request;
18020 request.method = "POST";
18021 request.url = GURL("http://www.foo.com/");
18022 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1018023 request.traffic_annotation =
18024 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2218025
danakj1fd259a02016-04-16 03:17:0918026 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1618027 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2218028 MockWrite data_writes[] = {
18029 MockWrite("POST / HTTP/1.1\r\n"
18030 "Host: www.foo.com\r\n"
18031 "Connection: keep-alive\r\n"
18032 "Content-Length: 3\r\n\r\n"),
18033 MockWrite("foo"),
18034 };
18035
18036 MockRead data_reads[] = {
18037 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
18038 MockRead(SYNCHRONOUS, OK),
18039 };
Ryan Sleevib8d7ea02018-05-07 20:01:0118040 StaticSocketDataProvider data(data_reads, data_writes);
sclittlefb249892015-09-10 21:33:2218041 session_deps_.socket_factory->AddSocketDataProvider(&data);
18042
18043 TestCompletionCallback callback;
18044
18045 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2018046 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0118047 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2218048
18049 std::string response_data;
bnc691fda62016-08-12 00:43:1618050 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2218051
Ryan Sleevib8d7ea02018-05-07 20:01:0118052 EXPECT_EQ(CountWriteBytes(data_writes), trans.GetTotalSentBytes());
18053 EXPECT_EQ(CountReadBytes(data_reads), trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2218054}
18055
bncd16676a2016-07-20 16:23:0118056TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost100Continue) {
danakj1fd259a02016-04-16 03:17:0918057 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2218058 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1918059 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2218060 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2218061
18062 HttpRequestInfo request;
18063 request.method = "POST";
18064 request.url = GURL("http://www.foo.com/");
18065 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1018066 request.traffic_annotation =
18067 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2218068
danakj1fd259a02016-04-16 03:17:0918069 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1618070 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2218071 MockWrite data_writes[] = {
18072 MockWrite("POST / HTTP/1.1\r\n"
18073 "Host: www.foo.com\r\n"
18074 "Connection: keep-alive\r\n"
18075 "Content-Length: 3\r\n\r\n"),
18076 MockWrite("foo"),
18077 };
18078
18079 MockRead data_reads[] = {
18080 MockRead("HTTP/1.1 100 Continue\r\n\r\n"),
18081 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
18082 MockRead(SYNCHRONOUS, OK),
18083 };
Ryan Sleevib8d7ea02018-05-07 20:01:0118084 StaticSocketDataProvider data(data_reads, data_writes);
sclittlefb249892015-09-10 21:33:2218085 session_deps_.socket_factory->AddSocketDataProvider(&data);
18086
18087 TestCompletionCallback callback;
18088
18089 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2018090 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0118091 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2218092
18093 std::string response_data;
bnc691fda62016-08-12 00:43:1618094 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2218095
Ryan Sleevib8d7ea02018-05-07 20:01:0118096 EXPECT_EQ(CountWriteBytes(data_writes), trans.GetTotalSentBytes());
18097 EXPECT_EQ(CountReadBytes(data_reads), trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2218098}
18099
bncd16676a2016-07-20 16:23:0118100TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) {
sclittlefb249892015-09-10 21:33:2218101 ChunkedUploadDataStream upload_data_stream(0);
18102
18103 HttpRequestInfo request;
18104 request.method = "POST";
18105 request.url = GURL("http://www.foo.com/");
18106 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1018107 request.traffic_annotation =
18108 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2218109
danakj1fd259a02016-04-16 03:17:0918110 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1618111 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2218112 // Send headers successfully, but get an error while sending the body.
18113 MockWrite data_writes[] = {
18114 MockWrite("POST / HTTP/1.1\r\n"
18115 "Host: www.foo.com\r\n"
18116 "Connection: keep-alive\r\n"
18117 "Transfer-Encoding: chunked\r\n\r\n"),
18118 MockWrite("1\r\nf\r\n"), MockWrite("2\r\noo\r\n"), MockWrite("0\r\n\r\n"),
18119 };
18120
18121 MockRead data_reads[] = {
18122 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
18123 MockRead(SYNCHRONOUS, OK),
18124 };
Ryan Sleevib8d7ea02018-05-07 20:01:0118125 StaticSocketDataProvider data(data_reads, data_writes);
sclittlefb249892015-09-10 21:33:2218126 session_deps_.socket_factory->AddSocketDataProvider(&data);
18127
18128 TestCompletionCallback callback;
18129
18130 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2018131 trans.Start(&request, callback.callback(), NetLogWithSource()));
sclittlefb249892015-09-10 21:33:2218132
18133 base::RunLoop().RunUntilIdle();
18134 upload_data_stream.AppendData("f", 1, false);
18135
18136 base::RunLoop().RunUntilIdle();
18137 upload_data_stream.AppendData("oo", 2, true);
18138
robpercival214763f2016-07-01 23:27:0118139 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2218140
18141 std::string response_data;
bnc691fda62016-08-12 00:43:1618142 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2218143
Ryan Sleevib8d7ea02018-05-07 20:01:0118144 EXPECT_EQ(CountWriteBytes(data_writes), trans.GetTotalSentBytes());
18145 EXPECT_EQ(CountReadBytes(data_reads), trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2218146}
18147
eustasc7d27da2017-04-06 10:33:2018148void CheckContentEncodingMatching(SpdySessionDependencies* session_deps,
18149 const std::string& accept_encoding,
18150 const std::string& content_encoding,
sky50576f32017-05-01 19:28:0318151 const std::string& location,
eustasc7d27da2017-04-06 10:33:2018152 bool should_match) {
18153 HttpRequestInfo request;
18154 request.method = "GET";
18155 request.url = GURL("http://www.foo.com/");
18156 request.extra_headers.SetHeader(HttpRequestHeaders::kAcceptEncoding,
18157 accept_encoding);
Ramin Halavatib5e433e2018-02-07 07:41:1018158 request.traffic_annotation =
18159 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
eustasc7d27da2017-04-06 10:33:2018160
18161 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps));
18162 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18163 // Send headers successfully, but get an error while sending the body.
18164 MockWrite data_writes[] = {
18165 MockWrite("GET / HTTP/1.1\r\n"
18166 "Host: www.foo.com\r\n"
18167 "Connection: keep-alive\r\n"
18168 "Accept-Encoding: "),
18169 MockWrite(accept_encoding.data()), MockWrite("\r\n\r\n"),
18170 };
18171
sky50576f32017-05-01 19:28:0318172 std::string response_code = "200 OK";
18173 std::string extra;
18174 if (!location.empty()) {
18175 response_code = "301 Redirect\r\nLocation: ";
18176 response_code.append(location);
18177 }
18178
eustasc7d27da2017-04-06 10:33:2018179 MockRead data_reads[] = {
sky50576f32017-05-01 19:28:0318180 MockRead("HTTP/1.0 "),
18181 MockRead(response_code.data()),
18182 MockRead("\r\nContent-Encoding: "),
18183 MockRead(content_encoding.data()),
18184 MockRead("\r\n\r\n"),
eustasc7d27da2017-04-06 10:33:2018185 MockRead(SYNCHRONOUS, OK),
18186 };
Ryan Sleevib8d7ea02018-05-07 20:01:0118187 StaticSocketDataProvider data(data_reads, data_writes);
eustasc7d27da2017-04-06 10:33:2018188 session_deps->socket_factory->AddSocketDataProvider(&data);
18189
18190 TestCompletionCallback callback;
18191
18192 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18193 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18194
18195 rv = callback.WaitForResult();
18196 if (should_match) {
18197 EXPECT_THAT(rv, IsOk());
18198 } else {
18199 EXPECT_THAT(rv, IsError(ERR_CONTENT_DECODING_FAILED));
18200 }
18201}
18202
18203TEST_F(HttpNetworkTransactionTest, MatchContentEncoding1) {
sky50576f32017-05-01 19:28:0318204 CheckContentEncodingMatching(&session_deps_, "gzip,sdch", "br", "", false);
eustasc7d27da2017-04-06 10:33:2018205}
18206
18207TEST_F(HttpNetworkTransactionTest, MatchContentEncoding2) {
sky50576f32017-05-01 19:28:0318208 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "", "",
18209 true);
eustasc7d27da2017-04-06 10:33:2018210}
18211
18212TEST_F(HttpNetworkTransactionTest, MatchContentEncoding3) {
18213 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
sky50576f32017-05-01 19:28:0318214 "", false);
18215}
18216
18217TEST_F(HttpNetworkTransactionTest, MatchContentEncoding4) {
18218 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
18219 "www.foo.com/other", true);
eustasc7d27da2017-04-06 10:33:2018220}
18221
xunjieli96f2a402017-06-05 17:24:2718222TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsSync) {
18223 ProxyConfig proxy_config;
18224 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
18225 proxy_config.set_pac_mandatory(true);
18226 MockAsyncProxyResolver resolver;
Lily Houghton8c2f97d2018-01-22 05:06:5918227 session_deps_.proxy_resolution_service.reset(new ProxyResolutionService(
Ramin Halavatica8d5252018-03-12 05:33:4918228 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
18229 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
Bence Béky8f9d7d3952017-10-09 19:58:0418230 std::make_unique<FailingProxyResolverFactory>(), nullptr));
xunjieli96f2a402017-06-05 17:24:2718231
18232 HttpRequestInfo request;
18233 request.method = "GET";
18234 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1018235 request.traffic_annotation =
18236 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2718237
18238 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18239 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18240
18241 TestCompletionCallback callback;
18242
18243 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18244 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18245 EXPECT_THAT(callback.WaitForResult(),
18246 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
18247}
18248
18249TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsAsync) {
18250 ProxyConfig proxy_config;
18251 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
18252 proxy_config.set_pac_mandatory(true);
18253 MockAsyncProxyResolverFactory* proxy_resolver_factory =
18254 new MockAsyncProxyResolverFactory(false);
18255 MockAsyncProxyResolver resolver;
Lily Houghton8c2f97d2018-01-22 05:06:5918256 session_deps_.proxy_resolution_service.reset(new ProxyResolutionService(
Ramin Halavatica8d5252018-03-12 05:33:4918257 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
18258 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
Lily Houghton8c2f97d2018-01-22 05:06:5918259 base::WrapUnique(proxy_resolver_factory), nullptr));
xunjieli96f2a402017-06-05 17:24:2718260 HttpRequestInfo request;
18261 request.method = "GET";
18262 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1018263 request.traffic_annotation =
18264 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2718265
18266 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18267 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18268
18269 TestCompletionCallback callback;
18270 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18271 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18272
18273 proxy_resolver_factory->pending_requests()[0]->CompleteNowWithForwarder(
18274 ERR_FAILED, &resolver);
18275 EXPECT_THAT(callback.WaitForResult(),
18276 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
18277}
18278
18279TEST_F(HttpNetworkTransactionTest, NoSupportedProxies) {
Lily Houghton8c2f97d2018-01-22 05:06:5918280 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4918281 ProxyResolutionService::CreateFixedFromPacResult(
18282 "QUIC myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2718283 session_deps_.enable_quic = false;
18284 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18285
18286 HttpRequestInfo request;
18287 request.method = "GET";
18288 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1018289 request.traffic_annotation =
18290 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2718291
18292 TestCompletionCallback callback;
18293 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18294 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18295 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18296
18297 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NO_SUPPORTED_PROXIES));
18298}
18299
Douglas Creager3cb042052018-11-06 23:08:5218300//-----------------------------------------------------------------------------
Douglas Creager134b52e2018-11-09 18:00:1418301// Reporting tests
18302
18303#if BUILDFLAG(ENABLE_REPORTING)
18304class HttpNetworkTransactionReportingTest : public HttpNetworkTransactionTest {
18305 protected:
18306 void SetUp() override {
Douglas Creageref5eecdc2018-11-09 20:50:3618307 HttpNetworkTransactionTest::SetUp();
Douglas Creager134b52e2018-11-09 18:00:1418308 auto test_reporting_context = std::make_unique<TestReportingContext>(
18309 &clock_, &tick_clock_, ReportingPolicy());
18310 test_reporting_context_ = test_reporting_context.get();
18311 session_deps_.reporting_service =
18312 ReportingService::CreateForTesting(std::move(test_reporting_context));
18313 }
18314
18315 TestReportingContext* reporting_context() const {
18316 return test_reporting_context_;
18317 }
18318
18319 void clear_reporting_service() {
18320 session_deps_.reporting_service.reset();
18321 test_reporting_context_ = nullptr;
18322 }
18323
18324 // Makes an HTTPS request that should install a valid Reporting policy.
Lily Chenfec60d92019-01-24 01:16:4218325 void RequestPolicy(CertStatus cert_status = 0) {
18326 HttpRequestInfo request;
18327 request.method = "GET";
18328 request.url = GURL(url_);
18329 request.traffic_annotation =
18330 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
18331
Lily Chend3930e72019-03-01 19:31:1118332 MockWrite data_writes[] = {
18333 MockWrite("GET / HTTP/1.1\r\n"
18334 "Host: www.example.org\r\n"
18335 "Connection: keep-alive\r\n\r\n"),
18336 };
Douglas Creager134b52e2018-11-09 18:00:1418337 MockRead data_reads[] = {
18338 MockRead("HTTP/1.0 200 OK\r\n"),
18339 MockRead("Report-To: {\"group\": \"nel\", \"max_age\": 86400, "
18340 "\"endpoints\": [{\"url\": "
18341 "\"https://www.example.org/upload/\"}]}\r\n"),
18342 MockRead("\r\n"),
18343 MockRead("hello world"),
18344 MockRead(SYNCHRONOUS, OK),
18345 };
Douglas Creager134b52e2018-11-09 18:00:1418346
Lily Chenfec60d92019-01-24 01:16:4218347 StaticSocketDataProvider reads(data_reads, data_writes);
18348 session_deps_.socket_factory->AddSocketDataProvider(&reads);
Douglas Creager134b52e2018-11-09 18:00:1418349
18350 SSLSocketDataProvider ssl(ASYNC, OK);
18351 if (request.url.SchemeIsCryptographic()) {
18352 ssl.ssl_info.cert =
18353 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
18354 ASSERT_TRUE(ssl.ssl_info.cert);
Lily Chenfec60d92019-01-24 01:16:4218355 ssl.ssl_info.cert_status = cert_status;
Douglas Creager134b52e2018-11-09 18:00:1418356 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
18357 }
18358
Douglas Creager134b52e2018-11-09 18:00:1418359 TestCompletionCallback callback;
18360 auto session = CreateSession(&session_deps_);
18361 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18362 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
Lily Chenfec60d92019-01-24 01:16:4218363 EXPECT_THAT(callback.GetResult(rv), IsOk());
Douglas Creager134b52e2018-11-09 18:00:1418364 }
18365
18366 protected:
18367 std::string url_ = "https://www.example.org/";
Douglas Creager134b52e2018-11-09 18:00:1418368
18369 private:
18370 TestReportingContext* test_reporting_context_;
18371};
18372
18373TEST_F(HttpNetworkTransactionReportingTest,
18374 DontProcessReportToHeaderNoService) {
18375 base::HistogramTester histograms;
18376 clear_reporting_service();
18377 RequestPolicy();
18378 histograms.ExpectBucketCount(
18379 ReportingHeaderParser::kHeaderOutcomeHistogram,
18380 ReportingHeaderParser::HeaderOutcome::DISCARDED_NO_REPORTING_SERVICE, 1);
18381}
18382
18383TEST_F(HttpNetworkTransactionReportingTest, DontProcessReportToHeaderHttp) {
18384 base::HistogramTester histograms;
18385 url_ = "http://www.example.org/";
18386 RequestPolicy();
18387 histograms.ExpectBucketCount(
18388 ReportingHeaderParser::kHeaderOutcomeHistogram,
18389 ReportingHeaderParser::HeaderOutcome::DISCARDED_INVALID_SSL_INFO, 1);
18390}
18391
18392TEST_F(HttpNetworkTransactionReportingTest, ProcessReportToHeaderHttps) {
18393 RequestPolicy();
18394 std::vector<const ReportingClient*> clients;
18395 reporting_context()->cache()->GetClients(&clients);
18396 ASSERT_EQ(1u, clients.size());
18397 const auto* client = clients[0];
18398 EXPECT_EQ(url::Origin::Create(GURL("https://www.example.org/")),
18399 client->origin);
18400 EXPECT_EQ(GURL("https://www.example.org/upload/"), client->endpoint);
18401 EXPECT_EQ("nel", client->group);
18402}
18403
18404TEST_F(HttpNetworkTransactionReportingTest,
18405 DontProcessReportToHeaderInvalidHttps) {
18406 base::HistogramTester histograms;
Lily Chenfec60d92019-01-24 01:16:4218407 CertStatus cert_status = CERT_STATUS_COMMON_NAME_INVALID;
18408 RequestPolicy(cert_status);
Douglas Creager134b52e2018-11-09 18:00:1418409 histograms.ExpectBucketCount(
18410 ReportingHeaderParser::kHeaderOutcomeHistogram,
18411 ReportingHeaderParser::HeaderOutcome::DISCARDED_CERT_STATUS_ERROR, 1);
18412}
18413#endif // BUILDFLAG(ENABLE_REPORTING)
18414
18415//-----------------------------------------------------------------------------
Douglas Creager3cb042052018-11-06 23:08:5218416// Network Error Logging tests
18417
18418#if BUILDFLAG(ENABLE_REPORTING)
Lily Chenfec60d92019-01-24 01:16:4218419namespace {
18420
18421const char kUserAgent[] = "Mozilla/1.0";
18422const char kReferrer[] = "https://www.referrer.org/";
18423
18424} // namespace
18425
Douglas Creager3cb042052018-11-06 23:08:5218426class HttpNetworkTransactionNetworkErrorLoggingTest
18427 : public HttpNetworkTransactionTest {
18428 protected:
18429 void SetUp() override {
Douglas Creageref5eecdc2018-11-09 20:50:3618430 HttpNetworkTransactionTest::SetUp();
Douglas Creager3cb042052018-11-06 23:08:5218431 auto network_error_logging_service =
18432 std::make_unique<TestNetworkErrorLoggingService>();
18433 test_network_error_logging_service_ = network_error_logging_service.get();
18434 session_deps_.network_error_logging_service =
18435 std::move(network_error_logging_service);
Lily Chenfec60d92019-01-24 01:16:4218436
18437 extra_headers_.SetHeader("User-Agent", kUserAgent);
18438 extra_headers_.SetHeader("Referer", kReferrer);
18439
18440 request_.method = "GET";
18441 request_.url = GURL(url_);
18442 request_.extra_headers = extra_headers_;
18443 request_.reporting_upload_depth = reporting_upload_depth_;
18444 request_.traffic_annotation =
18445 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Douglas Creager3cb042052018-11-06 23:08:5218446 }
18447
18448 TestNetworkErrorLoggingService* network_error_logging_service() const {
18449 return test_network_error_logging_service_;
18450 }
18451
18452 void clear_network_error_logging_service() {
18453 session_deps_.network_error_logging_service.reset();
18454 test_network_error_logging_service_ = nullptr;
18455 }
18456
18457 // Makes an HTTPS request that should install a valid NEL policy.
Lily Chenfec60d92019-01-24 01:16:4218458 void RequestPolicy(CertStatus cert_status = 0) {
Douglas Creageref5eecdc2018-11-09 20:50:3618459 std::string extra_header_string = extra_headers_.ToString();
Lily Chen29c04032019-02-25 21:50:5318460 MockWrite data_writes[] = {
18461 MockWrite("GET / HTTP/1.1\r\n"
18462 "Host: www.example.org\r\n"
18463 "Connection: keep-alive\r\n"),
18464 MockWrite(ASYNC, extra_header_string.data(),
18465 extra_header_string.size()),
18466 };
Lily Chend3930e72019-03-01 19:31:1118467 MockRead data_reads[] = {
18468 MockRead("HTTP/1.0 200 OK\r\n"),
18469 MockRead("NEL: {\"report_to\": \"nel\", \"max_age\": 86400}\r\n"),
18470 MockRead("\r\n"),
18471 MockRead("hello world"),
18472 MockRead(SYNCHRONOUS, OK),
18473 };
Douglas Creager3cb042052018-11-06 23:08:5218474
Lily Chenfec60d92019-01-24 01:16:4218475 StaticSocketDataProvider reads(data_reads, data_writes);
18476 session_deps_.socket_factory->AddSocketDataProvider(&reads);
Douglas Creager3cb042052018-11-06 23:08:5218477
18478 SSLSocketDataProvider ssl(ASYNC, OK);
Lily Chenfec60d92019-01-24 01:16:4218479 if (request_.url.SchemeIsCryptographic()) {
Douglas Creager3cb042052018-11-06 23:08:5218480 ssl.ssl_info.cert =
18481 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
18482 ASSERT_TRUE(ssl.ssl_info.cert);
Lily Chenfec60d92019-01-24 01:16:4218483 ssl.ssl_info.cert_status = cert_status;
Douglas Creager3cb042052018-11-06 23:08:5218484 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
18485 }
18486
Douglas Creager3cb042052018-11-06 23:08:5218487 TestCompletionCallback callback;
18488 auto session = CreateSession(&session_deps_);
18489 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
Lily Chenfec60d92019-01-24 01:16:4218490 int rv = trans.Start(&request_, callback.callback(), NetLogWithSource());
18491 EXPECT_THAT(callback.GetResult(rv), IsOk());
18492
18493 std::string response_data;
18494 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
18495 EXPECT_EQ("hello world", response_data);
18496 }
18497
18498 void CheckReport(size_t index,
18499 int status_code,
18500 int error_type,
18501 IPAddress server_ip = IPAddress::IPv4Localhost()) {
18502 ASSERT_LT(index, network_error_logging_service()->errors().size());
18503
18504 const NetworkErrorLoggingService::RequestDetails& error =
18505 network_error_logging_service()->errors()[index];
18506 EXPECT_EQ(url_, error.uri);
18507 EXPECT_EQ(kReferrer, error.referrer);
18508 EXPECT_EQ(kUserAgent, error.user_agent);
18509 EXPECT_EQ(server_ip, error.server_ip);
18510 EXPECT_EQ("http/1.1", error.protocol);
18511 EXPECT_EQ("GET", error.method);
18512 EXPECT_EQ(status_code, error.status_code);
18513 EXPECT_EQ(error_type, error.type);
18514 EXPECT_EQ(0, error.reporting_upload_depth);
Douglas Creager3cb042052018-11-06 23:08:5218515 }
18516
18517 protected:
18518 std::string url_ = "https://www.example.org/";
18519 CertStatus cert_status_ = 0;
Lily Chenfec60d92019-01-24 01:16:4218520 HttpRequestInfo request_;
Douglas Creageref5eecdc2018-11-09 20:50:3618521 HttpRequestHeaders extra_headers_;
18522 int reporting_upload_depth_ = 0;
Douglas Creager3cb042052018-11-06 23:08:5218523
18524 private:
18525 TestNetworkErrorLoggingService* test_network_error_logging_service_;
18526};
18527
18528TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18529 DontProcessNelHeaderNoService) {
18530 base::HistogramTester histograms;
18531 clear_network_error_logging_service();
18532 RequestPolicy();
18533 histograms.ExpectBucketCount(
18534 NetworkErrorLoggingService::kHeaderOutcomeHistogram,
18535 NetworkErrorLoggingService::HeaderOutcome::
18536 DISCARDED_NO_NETWORK_ERROR_LOGGING_SERVICE,
18537 1);
18538}
18539
18540TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18541 DontProcessNelHeaderHttp) {
18542 base::HistogramTester histograms;
18543 url_ = "http://www.example.org/";
Lily Chenfec60d92019-01-24 01:16:4218544 request_.url = GURL(url_);
Douglas Creager3cb042052018-11-06 23:08:5218545 RequestPolicy();
18546 histograms.ExpectBucketCount(
18547 NetworkErrorLoggingService::kHeaderOutcomeHistogram,
18548 NetworkErrorLoggingService::HeaderOutcome::DISCARDED_INVALID_SSL_INFO, 1);
18549}
18550
Lily Chen90ae93cc2019-02-14 01:15:3918551// Don't set NEL policies received on a proxied connection.
18552TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18553 DontProcessNelHeaderProxy) {
18554 session_deps_.proxy_resolution_service =
18555 ProxyResolutionService::CreateFixedFromPacResult(
18556 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
18557 BoundTestNetLog log;
18558 session_deps_.net_log = log.bound().net_log();
18559 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18560
18561 HttpRequestInfo request;
18562 request.method = "GET";
18563 request.url = GURL("https://www.example.org/");
18564 request.traffic_annotation =
18565 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
18566
18567 // Since we have proxy, should try to establish tunnel.
18568 MockWrite data_writes1[] = {
18569 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
18570 "Host: www.example.org:443\r\n"
18571 "Proxy-Connection: keep-alive\r\n\r\n"),
18572
18573 MockWrite("GET / HTTP/1.1\r\n"
18574 "Host: www.example.org\r\n"
18575 "Connection: keep-alive\r\n\r\n"),
18576 };
18577
18578 MockRead data_reads1[] = {
18579 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
18580
18581 MockRead("HTTP/1.1 200 OK\r\n"),
18582 MockRead("NEL: {\"report_to\": \"nel\", \"max_age\": 86400}\r\n"),
18583 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
18584 MockRead("Content-Length: 100\r\n\r\n"),
18585 MockRead(SYNCHRONOUS, OK),
18586 };
18587
18588 StaticSocketDataProvider data1(data_reads1, data_writes1);
18589 session_deps_.socket_factory->AddSocketDataProvider(&data1);
18590 SSLSocketDataProvider ssl(ASYNC, OK);
18591 ssl.ssl_info.cert =
18592 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
18593 ASSERT_TRUE(ssl.ssl_info.cert);
18594 ssl.ssl_info.cert_status = 0;
18595 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
18596
18597 TestCompletionCallback callback1;
18598 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18599
18600 int rv = trans.Start(&request, callback1.callback(), log.bound());
18601 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18602
18603 rv = callback1.WaitForResult();
18604 EXPECT_THAT(rv, IsOk());
18605
18606 const HttpResponseInfo* response = trans.GetResponseInfo();
18607 ASSERT_TRUE(response);
18608 EXPECT_EQ(200, response->headers->response_code());
18609 EXPECT_TRUE(response->was_fetched_via_proxy);
18610
18611 // No NEL header was set.
18612 EXPECT_EQ(0u, network_error_logging_service()->headers().size());
18613}
18614
Douglas Creager3cb042052018-11-06 23:08:5218615TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, ProcessNelHeaderHttps) {
18616 RequestPolicy();
18617 ASSERT_EQ(1u, network_error_logging_service()->headers().size());
18618 const auto& header = network_error_logging_service()->headers()[0];
18619 EXPECT_EQ(url::Origin::Create(GURL("https://www.example.org/")),
18620 header.origin);
18621 EXPECT_EQ(IPAddress::IPv4Localhost(), header.received_ip_address);
18622 EXPECT_EQ("{\"report_to\": \"nel\", \"max_age\": 86400}", header.value);
18623}
18624
18625TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18626 DontProcessNelHeaderInvalidHttps) {
18627 base::HistogramTester histograms;
Lily Chenfec60d92019-01-24 01:16:4218628 CertStatus cert_status = CERT_STATUS_COMMON_NAME_INVALID;
18629 RequestPolicy(cert_status);
Douglas Creager3cb042052018-11-06 23:08:5218630 histograms.ExpectBucketCount(
18631 NetworkErrorLoggingService::kHeaderOutcomeHistogram,
18632 NetworkErrorLoggingService::HeaderOutcome::DISCARDED_CERT_STATUS_ERROR,
18633 1);
18634}
Douglas Creageref5eecdc2018-11-09 20:50:3618635
Lily Chenfec60d92019-01-24 01:16:4218636TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, CreateReportSuccess) {
Douglas Creageref5eecdc2018-11-09 20:50:3618637 RequestPolicy();
18638 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
Lily Chenfec60d92019-01-24 01:16:4218639 CheckReport(0 /* index */, 200 /* status_code */, OK);
18640}
18641
18642TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18643 CreateReportErrorAfterStart) {
18644 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18645 auto trans =
18646 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18647
18648 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
18649 StaticSocketDataProvider data;
18650 data.set_connect_data(mock_connect);
18651 session_deps_.socket_factory->AddSocketDataProvider(&data);
18652
18653 TestCompletionCallback callback;
18654
18655 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
18656 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_NAME_NOT_RESOLVED));
18657
18658 trans.reset();
18659
18660 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18661 CheckReport(0 /* index */, 0 /* status_code */, ERR_NAME_NOT_RESOLVED,
18662 IPAddress() /* server_ip */);
18663}
18664
18665// Same as above except the error is ASYNC
18666TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18667 CreateReportErrorAfterStartAsync) {
18668 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18669 auto trans =
18670 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18671
18672 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
18673 StaticSocketDataProvider data;
18674 data.set_connect_data(mock_connect);
18675 session_deps_.socket_factory->AddSocketDataProvider(&data);
18676
18677 TestCompletionCallback callback;
18678
18679 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
18680 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_NAME_NOT_RESOLVED));
18681
18682 trans.reset();
18683
18684 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18685 CheckReport(0 /* index */, 0 /* status_code */, ERR_NAME_NOT_RESOLVED,
18686 IPAddress() /* server_ip */);
18687}
18688
18689TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18690 CreateReportReadBodyError) {
18691 std::string extra_header_string = extra_headers_.ToString();
Lily Chen29c04032019-02-25 21:50:5318692 MockWrite data_writes[] = {
18693 MockWrite("GET / HTTP/1.1\r\n"
18694 "Host: www.example.org\r\n"
18695 "Connection: keep-alive\r\n"),
18696 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18697 };
Lily Chend3930e72019-03-01 19:31:1118698 MockRead data_reads[] = {
18699 MockRead("HTTP/1.0 200 OK\r\n"),
18700 MockRead("Content-Length: 100\r\n\r\n"), // wrong content length
18701 MockRead("hello world"),
18702 MockRead(SYNCHRONOUS, OK),
18703 };
Lily Chenfec60d92019-01-24 01:16:4218704
18705 StaticSocketDataProvider reads(data_reads, data_writes);
18706 session_deps_.socket_factory->AddSocketDataProvider(&reads);
18707
18708 SSLSocketDataProvider ssl(ASYNC, OK);
18709 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
18710
18711 // Log start time
18712 base::TimeTicks start_time = base::TimeTicks::Now();
18713
18714 TestCompletionCallback callback;
18715 auto session = CreateSession(&session_deps_);
18716 auto trans =
18717 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18718 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
18719 EXPECT_THAT(callback.GetResult(rv), IsOk());
18720
18721 const HttpResponseInfo* response = trans->GetResponseInfo();
18722 ASSERT_TRUE(response);
18723
18724 EXPECT_TRUE(response->headers);
18725 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
18726
18727 std::string response_data;
18728 rv = ReadTransaction(trans.get(), &response_data);
18729 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
18730
18731 trans.reset();
18732
18733 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18734
18735 CheckReport(0 /* index */, 200 /* status_code */,
18736 ERR_CONTENT_LENGTH_MISMATCH);
18737 const NetworkErrorLoggingService::RequestDetails& error =
18738 network_error_logging_service()->errors()[0];
18739 EXPECT_LE(error.elapsed_time, base::TimeTicks::Now() - start_time);
18740}
18741
18742// Same as above except the final read is ASYNC.
18743TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18744 CreateReportReadBodyErrorAsync) {
18745 std::string extra_header_string = extra_headers_.ToString();
Lily Chen29c04032019-02-25 21:50:5318746 MockWrite data_writes[] = {
18747 MockWrite("GET / HTTP/1.1\r\n"
18748 "Host: www.example.org\r\n"
18749 "Connection: keep-alive\r\n"),
18750 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18751 };
Lily Chend3930e72019-03-01 19:31:1118752 MockRead data_reads[] = {
18753 MockRead("HTTP/1.0 200 OK\r\n"),
18754 MockRead("Content-Length: 100\r\n\r\n"), // wrong content length
18755 MockRead("hello world"),
18756 MockRead(ASYNC, OK),
18757 };
Lily Chenfec60d92019-01-24 01:16:4218758
18759 StaticSocketDataProvider reads(data_reads, data_writes);
18760 session_deps_.socket_factory->AddSocketDataProvider(&reads);
18761
18762 SSLSocketDataProvider ssl(ASYNC, OK);
18763 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
18764
18765 // Log start time
18766 base::TimeTicks start_time = base::TimeTicks::Now();
18767
18768 TestCompletionCallback callback;
18769 auto session = CreateSession(&session_deps_);
18770 auto trans =
18771 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18772 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
18773 EXPECT_THAT(callback.GetResult(rv), IsOk());
18774
18775 const HttpResponseInfo* response = trans->GetResponseInfo();
18776 ASSERT_TRUE(response);
18777
18778 EXPECT_TRUE(response->headers);
18779 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
18780
18781 std::string response_data;
18782 rv = ReadTransaction(trans.get(), &response_data);
18783 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
18784
18785 trans.reset();
18786
18787 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18788
18789 CheckReport(0 /* index */, 200 /* status_code */,
18790 ERR_CONTENT_LENGTH_MISMATCH);
18791 const NetworkErrorLoggingService::RequestDetails& error =
18792 network_error_logging_service()->errors()[0];
18793 EXPECT_LE(error.elapsed_time, base::TimeTicks::Now() - start_time);
18794}
18795
18796TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18797 CreateReportRestartWithAuth) {
18798 std::string extra_header_string = extra_headers_.ToString();
18799 static const base::TimeDelta kSleepDuration =
18800 base::TimeDelta::FromMilliseconds(10);
18801
18802 MockWrite data_writes1[] = {
18803 MockWrite("GET / HTTP/1.1\r\n"
18804 "Host: www.example.org\r\n"
18805 "Connection: keep-alive\r\n"),
18806 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18807 };
18808
18809 MockRead data_reads1[] = {
18810 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
18811 // Give a couple authenticate options (only the middle one is actually
18812 // supported).
18813 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
18814 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
18815 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
18816 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
18817 // Large content-length -- won't matter, as connection will be reset.
18818 MockRead("Content-Length: 10000\r\n\r\n"),
18819 MockRead(SYNCHRONOUS, ERR_FAILED),
18820 };
18821
18822 // After calling trans->RestartWithAuth(), this is the request we should
18823 // be issuing -- the final header line contains the credentials.
18824 MockWrite data_writes2[] = {
18825 MockWrite("GET / HTTP/1.1\r\n"
18826 "Host: www.example.org\r\n"
18827 "Connection: keep-alive\r\n"
18828 "Authorization: Basic Zm9vOmJhcg==\r\n"),
18829 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18830 };
18831
18832 // Lastly, the server responds with the actual content.
18833 MockRead data_reads2[] = {
18834 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
18835 MockRead("hello world"),
18836 MockRead(SYNCHRONOUS, OK),
18837 };
18838
18839 StaticSocketDataProvider data1(data_reads1, data_writes1);
18840 StaticSocketDataProvider data2(data_reads2, data_writes2);
18841 session_deps_.socket_factory->AddSocketDataProvider(&data1);
18842 session_deps_.socket_factory->AddSocketDataProvider(&data2);
18843
18844 SSLSocketDataProvider ssl1(ASYNC, OK);
18845 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
18846 SSLSocketDataProvider ssl2(ASYNC, OK);
18847 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
18848
18849 base::TimeTicks start_time = base::TimeTicks::Now();
18850 base::TimeTicks restart_time;
18851
18852 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18853 auto trans =
18854 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18855
18856 TestCompletionCallback callback1;
18857
18858 int rv = trans->Start(&request_, callback1.callback(), NetLogWithSource());
18859 EXPECT_THAT(callback1.GetResult(rv), IsOk());
18860
18861 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18862
18863 TestCompletionCallback callback2;
18864
18865 // Wait 10 ms then restart with auth
18866 FastForwardBy(kSleepDuration);
18867 restart_time = base::TimeTicks::Now();
18868 rv =
18869 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
18870 EXPECT_THAT(callback2.GetResult(rv), IsOk());
18871
18872 std::string response_data;
18873 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
18874 EXPECT_EQ("hello world", response_data);
18875
18876 trans.reset();
18877
18878 // One 401 report for the auth challenge, then a 200 report for the successful
18879 // retry. Note that we don't report the error draining the body, as the first
18880 // request already generated a report for the auth challenge.
18881 ASSERT_EQ(2u, network_error_logging_service()->errors().size());
18882
18883 // Check error report contents
18884 CheckReport(0 /* index */, 401 /* status_code */, OK);
18885 CheckReport(1 /* index */, 200 /* status_code */, OK);
18886
18887 const NetworkErrorLoggingService::RequestDetails& error1 =
18888 network_error_logging_service()->errors()[0];
18889 const NetworkErrorLoggingService::RequestDetails& error2 =
18890 network_error_logging_service()->errors()[1];
18891
18892 // Sanity-check elapsed time values
18893 EXPECT_EQ(error1.elapsed_time, restart_time - start_time - kSleepDuration);
18894 // Check that the start time is refreshed when restarting with auth.
18895 EXPECT_EQ(error2.elapsed_time, base::TimeTicks::Now() - restart_time);
18896}
18897
18898// Same as above, except draining the body before restarting fails
18899// asynchronously.
18900TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18901 CreateReportRestartWithAuthAsync) {
18902 std::string extra_header_string = extra_headers_.ToString();
18903 static const base::TimeDelta kSleepDuration =
18904 base::TimeDelta::FromMilliseconds(10);
18905
18906 MockWrite data_writes1[] = {
18907 MockWrite("GET / HTTP/1.1\r\n"
18908 "Host: www.example.org\r\n"
18909 "Connection: keep-alive\r\n"),
18910 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18911 };
18912
18913 MockRead data_reads1[] = {
18914 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
18915 // Give a couple authenticate options (only the middle one is actually
18916 // supported).
18917 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
18918 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
18919 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
18920 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
18921 // Large content-length -- won't matter, as connection will be reset.
18922 MockRead("Content-Length: 10000\r\n\r\n"),
18923 MockRead(ASYNC, ERR_FAILED),
18924 };
18925
18926 // After calling trans->RestartWithAuth(), this is the request we should
18927 // be issuing -- the final header line contains the credentials.
18928 MockWrite data_writes2[] = {
18929 MockWrite("GET / HTTP/1.1\r\n"
18930 "Host: www.example.org\r\n"
18931 "Connection: keep-alive\r\n"
18932 "Authorization: Basic Zm9vOmJhcg==\r\n"),
18933 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18934 };
18935
18936 // Lastly, the server responds with the actual content.
18937 MockRead data_reads2[] = {
18938 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
18939 MockRead("hello world"),
18940 MockRead(SYNCHRONOUS, OK),
18941 };
18942
18943 StaticSocketDataProvider data1(data_reads1, data_writes1);
18944 StaticSocketDataProvider data2(data_reads2, data_writes2);
18945 session_deps_.socket_factory->AddSocketDataProvider(&data1);
18946 session_deps_.socket_factory->AddSocketDataProvider(&data2);
18947
18948 SSLSocketDataProvider ssl1(ASYNC, OK);
18949 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
18950 SSLSocketDataProvider ssl2(ASYNC, OK);
18951 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
18952
18953 base::TimeTicks start_time = base::TimeTicks::Now();
18954 base::TimeTicks restart_time;
18955
18956 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18957 auto trans =
18958 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18959
18960 TestCompletionCallback callback1;
18961
18962 int rv = trans->Start(&request_, callback1.callback(), NetLogWithSource());
18963 EXPECT_THAT(callback1.GetResult(rv), IsOk());
18964
18965 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18966
18967 TestCompletionCallback callback2;
18968
18969 // Wait 10 ms then restart with auth
18970 FastForwardBy(kSleepDuration);
18971 restart_time = base::TimeTicks::Now();
18972 rv =
18973 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
18974 EXPECT_THAT(callback2.GetResult(rv), IsOk());
18975
18976 std::string response_data;
18977 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
18978 EXPECT_EQ("hello world", response_data);
18979
18980 trans.reset();
18981
18982 // One 401 report for the auth challenge, then a 200 report for the successful
18983 // retry. Note that we don't report the error draining the body, as the first
18984 // request already generated a report for the auth challenge.
18985 ASSERT_EQ(2u, network_error_logging_service()->errors().size());
18986
18987 // Check error report contents
18988 CheckReport(0 /* index */, 401 /* status_code */, OK);
18989 CheckReport(1 /* index */, 200 /* status_code */, OK);
18990
18991 const NetworkErrorLoggingService::RequestDetails& error1 =
18992 network_error_logging_service()->errors()[0];
18993 const NetworkErrorLoggingService::RequestDetails& error2 =
18994 network_error_logging_service()->errors()[1];
18995
18996 // Sanity-check elapsed time values
18997 EXPECT_EQ(error1.elapsed_time, restart_time - start_time - kSleepDuration);
18998 // Check that the start time is refreshed when restarting with auth.
18999 EXPECT_EQ(error2.elapsed_time, base::TimeTicks::Now() - restart_time);
19000}
19001
19002TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
19003 CreateReportRetryKeepAliveConnectionReset) {
19004 std::string extra_header_string = extra_headers_.ToString();
19005 MockWrite data_writes1[] = {
19006 MockWrite("GET / HTTP/1.1\r\n"
19007 "Host: www.example.org\r\n"
19008 "Connection: keep-alive\r\n"),
19009 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
19010 MockWrite("GET / HTTP/1.1\r\n"
19011 "Host: www.example.org\r\n"
19012 "Connection: keep-alive\r\n"),
19013 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
19014 };
19015
19016 MockRead data_reads1[] = {
19017 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
19018 MockRead("hello"),
19019 // Connection is reset
19020 MockRead(ASYNC, ERR_CONNECTION_RESET),
19021 };
19022
19023 // Successful retry
19024 MockRead data_reads2[] = {
19025 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
19026 MockRead("world"),
19027 MockRead(ASYNC, OK),
19028 };
19029
19030 StaticSocketDataProvider data1(data_reads1, data_writes1);
19031 StaticSocketDataProvider data2(data_reads2, base::span<MockWrite>());
19032 session_deps_.socket_factory->AddSocketDataProvider(&data1);
19033 session_deps_.socket_factory->AddSocketDataProvider(&data2);
19034
19035 SSLSocketDataProvider ssl1(ASYNC, OK);
19036 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
19037 SSLSocketDataProvider ssl2(ASYNC, OK);
19038 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
19039
19040 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19041 auto trans1 =
19042 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19043
19044 TestCompletionCallback callback1;
19045
19046 int rv = trans1->Start(&request_, callback1.callback(), NetLogWithSource());
19047 EXPECT_THAT(callback1.GetResult(rv), IsOk());
19048
19049 std::string response_data;
19050 ASSERT_THAT(ReadTransaction(trans1.get(), &response_data), IsOk());
19051 EXPECT_EQ("hello", response_data);
19052
19053 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
19054
19055 auto trans2 =
19056 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19057
19058 TestCompletionCallback callback2;
19059
19060 rv = trans2->Start(&request_, callback2.callback(), NetLogWithSource());
19061 EXPECT_THAT(callback2.GetResult(rv), IsOk());
19062
19063 ASSERT_THAT(ReadTransaction(trans2.get(), &response_data), IsOk());
19064 EXPECT_EQ("world", response_data);
19065
19066 trans1.reset();
19067 trans2.reset();
19068
19069 // One OK report from first request, then a ERR_CONNECTION_RESET report from
19070 // the second request, then an OK report from the successful retry.
19071 ASSERT_EQ(3u, network_error_logging_service()->errors().size());
19072
19073 // Check error report contents
19074 CheckReport(0 /* index */, 200 /* status_code */, OK);
19075 CheckReport(1 /* index */, 0 /* status_code */, ERR_CONNECTION_RESET);
19076 CheckReport(2 /* index */, 200 /* status_code */, OK);
19077}
19078
19079TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
19080 CreateReportRetryKeepAlive408) {
19081 std::string extra_header_string = extra_headers_.ToString();
19082 MockWrite data_writes1[] = {
19083 MockWrite("GET / HTTP/1.1\r\n"
19084 "Host: www.example.org\r\n"
19085 "Connection: keep-alive\r\n"),
19086 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
19087 MockWrite("GET / HTTP/1.1\r\n"
19088 "Host: www.example.org\r\n"
19089 "Connection: keep-alive\r\n"),
19090 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
19091 };
19092
19093 MockRead data_reads1[] = {
19094 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
19095 MockRead("hello"),
19096 // 408 Request Timeout
19097 MockRead(SYNCHRONOUS,
19098 "HTTP/1.1 408 Request Timeout\r\n"
19099 "Connection: Keep-Alive\r\n"
19100 "Content-Length: 6\r\n\r\n"
19101 "Pickle"),
19102 };
19103
19104 // Successful retry
19105 MockRead data_reads2[] = {
19106 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
19107 MockRead("world"),
19108 MockRead(ASYNC, OK),
19109 };
19110
19111 StaticSocketDataProvider data1(data_reads1, data_writes1);
19112 StaticSocketDataProvider data2(data_reads2, base::span<MockWrite>());
19113 session_deps_.socket_factory->AddSocketDataProvider(&data1);
19114 session_deps_.socket_factory->AddSocketDataProvider(&data2);
19115
19116 SSLSocketDataProvider ssl1(ASYNC, OK);
19117 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
19118 SSLSocketDataProvider ssl2(ASYNC, OK);
19119 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
19120
19121 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19122 auto trans1 =
19123 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19124
19125 TestCompletionCallback callback1;
19126
19127 int rv = trans1->Start(&request_, callback1.callback(), NetLogWithSource());
19128 EXPECT_THAT(callback1.GetResult(rv), IsOk());
19129
19130 std::string response_data;
19131 ASSERT_THAT(ReadTransaction(trans1.get(), &response_data), IsOk());
19132 EXPECT_EQ("hello", response_data);
19133
19134 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
19135
19136 auto trans2 =
19137 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19138
19139 TestCompletionCallback callback2;
19140
19141 rv = trans2->Start(&request_, callback2.callback(), NetLogWithSource());
19142 EXPECT_THAT(callback2.GetResult(rv), IsOk());
19143
19144 ASSERT_THAT(ReadTransaction(trans2.get(), &response_data), IsOk());
19145 EXPECT_EQ("world", response_data);
19146
19147 trans1.reset();
19148 trans2.reset();
19149
19150 // One 200 report from first request, then a 408 report from
19151 // the second request, then a 200 report from the successful retry.
19152 ASSERT_EQ(3u, network_error_logging_service()->errors().size());
19153
19154 // Check error report contents
19155 CheckReport(0 /* index */, 200 /* status_code */, OK);
19156 CheckReport(1 /* index */, 408 /* status_code */, OK);
19157 CheckReport(2 /* index */, 200 /* status_code */, OK);
19158}
19159
19160TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
19161 CreateReportRetry421WithoutConnectionPooling) {
19162 // Two hosts resolve to the same IP address.
19163 const std::string ip_addr = "1.2.3.4";
19164 IPAddress ip;
19165 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
19166 IPEndPoint peer_addr = IPEndPoint(ip, 443);
19167
19168 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
19169 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
19170 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
19171
19172 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19173
19174 // Two requests on the first connection.
19175 spdy::SpdySerializedFrame req1(
19176 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
19177 spdy_util_.UpdateWithStreamDestruction(1);
19178 spdy::SpdySerializedFrame req2(
19179 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
19180 spdy::SpdySerializedFrame rst(
19181 spdy_util_.ConstructSpdyRstStream(3, spdy::ERROR_CODE_CANCEL));
19182 MockWrite writes1[] = {
19183 CreateMockWrite(req1, 0),
19184 CreateMockWrite(req2, 3),
19185 CreateMockWrite(rst, 6),
19186 };
19187
19188 // The first one succeeds, the second gets error 421 Misdirected Request.
19189 spdy::SpdySerializedFrame resp1(
19190 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
19191 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
19192 spdy::SpdyHeaderBlock response_headers;
19193 response_headers[spdy::kHttp2StatusHeader] = "421";
19194 spdy::SpdySerializedFrame resp2(
19195 spdy_util_.ConstructSpdyReply(3, std::move(response_headers)));
19196 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
19197 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
19198
19199 MockConnect connect1(ASYNC, OK, peer_addr);
19200 SequencedSocketData data1(connect1, reads1, writes1);
19201 session_deps_.socket_factory->AddSocketDataProvider(&data1);
19202
19203 AddSSLSocketData();
19204
19205 // Retry the second request on a second connection.
19206 SpdyTestUtil spdy_util2;
19207 spdy::SpdySerializedFrame req3(
19208 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
19209 MockWrite writes2[] = {
19210 CreateMockWrite(req3, 0),
19211 };
19212
19213 spdy::SpdySerializedFrame resp3(
19214 spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
19215 spdy::SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
19216 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
19217 MockRead(ASYNC, 0, 3)};
19218
19219 MockConnect connect2(ASYNC, OK, peer_addr);
19220 SequencedSocketData data2(connect2, reads2, writes2);
19221 session_deps_.socket_factory->AddSocketDataProvider(&data2);
19222
19223 AddSSLSocketData();
19224
19225 // Preload mail.example.org into HostCache.
Eric Orthf4db66a2019-02-19 21:35:3319226 int rv = session_deps_.host_resolver->LoadIntoCache(
19227 HostPortPair("mail.example.com", 443), base::nullopt);
19228 EXPECT_THAT(rv, IsOk());
Lily Chenfec60d92019-01-24 01:16:4219229
19230 HttpRequestInfo request1;
19231 request1.method = "GET";
19232 request1.url = GURL("https://www.example.org/");
19233 request1.load_flags = 0;
19234 request1.traffic_annotation =
19235 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19236 auto trans1 =
19237 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19238
Eric Orthf4db66a2019-02-19 21:35:3319239 TestCompletionCallback callback;
Lily Chenfec60d92019-01-24 01:16:4219240 rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
19241 EXPECT_THAT(callback.GetResult(rv), IsOk());
19242
19243 const HttpResponseInfo* response = trans1->GetResponseInfo();
19244 ASSERT_TRUE(response);
19245 ASSERT_TRUE(response->headers);
19246 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
19247 EXPECT_TRUE(response->was_fetched_via_spdy);
19248 EXPECT_TRUE(response->was_alpn_negotiated);
19249 std::string response_data;
19250 ASSERT_THAT(ReadTransaction(trans1.get(), &response_data), IsOk());
19251 EXPECT_EQ("hello!", response_data);
19252
19253 trans1.reset();
19254
19255 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
19256
19257 HttpRequestInfo request2;
19258 request2.method = "GET";
19259 request2.url = GURL("https://mail.example.org/");
19260 request2.load_flags = 0;
19261 request2.traffic_annotation =
19262 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19263 auto trans2 =
19264 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19265
19266 BoundTestNetLog log;
19267 rv = trans2->Start(&request2, callback.callback(), log.bound());
19268 EXPECT_THAT(callback.GetResult(rv), IsOk());
19269
19270 response = trans2->GetResponseInfo();
19271 ASSERT_TRUE(response);
19272 ASSERT_TRUE(response->headers);
19273 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
19274 EXPECT_TRUE(response->was_fetched_via_spdy);
19275 EXPECT_TRUE(response->was_alpn_negotiated);
19276 ASSERT_THAT(ReadTransaction(trans2.get(), &response_data), IsOk());
19277 EXPECT_EQ("hello!", response_data);
19278
19279 trans2.reset();
19280
19281 // One 200 report from the first request, then a 421 report from the
19282 // second request, then a 200 report from the successful retry.
19283 ASSERT_EQ(3u, network_error_logging_service()->errors().size());
19284
19285 // Check error report contents
19286 const NetworkErrorLoggingService::RequestDetails& error1 =
19287 network_error_logging_service()->errors()[0];
19288 EXPECT_EQ(GURL("https://www.example.org/"), error1.uri);
19289 EXPECT_TRUE(error1.referrer.is_empty());
19290 EXPECT_EQ("", error1.user_agent);
19291 EXPECT_EQ(ip, error1.server_ip);
19292 EXPECT_EQ("h2", error1.protocol);
19293 EXPECT_EQ("GET", error1.method);
19294 EXPECT_EQ(200, error1.status_code);
19295 EXPECT_EQ(OK, error1.type);
19296 EXPECT_EQ(0, error1.reporting_upload_depth);
19297
19298 const NetworkErrorLoggingService::RequestDetails& error2 =
19299 network_error_logging_service()->errors()[1];
19300 EXPECT_EQ(GURL("https://mail.example.org/"), error2.uri);
19301 EXPECT_TRUE(error2.referrer.is_empty());
19302 EXPECT_EQ("", error2.user_agent);
19303 EXPECT_EQ(ip, error2.server_ip);
19304 EXPECT_EQ("h2", error2.protocol);
19305 EXPECT_EQ("GET", error2.method);
19306 EXPECT_EQ(421, error2.status_code);
19307 EXPECT_EQ(OK, error2.type);
19308 EXPECT_EQ(0, error2.reporting_upload_depth);
19309
19310 const NetworkErrorLoggingService::RequestDetails& error3 =
19311 network_error_logging_service()->errors()[2];
19312 EXPECT_EQ(GURL("https://mail.example.org/"), error3.uri);
19313 EXPECT_TRUE(error3.referrer.is_empty());
19314 EXPECT_EQ("", error3.user_agent);
19315 EXPECT_EQ(ip, error3.server_ip);
19316 EXPECT_EQ("h2", error3.protocol);
19317 EXPECT_EQ("GET", error3.method);
19318 EXPECT_EQ(200, error3.status_code);
19319 EXPECT_EQ(OK, error3.type);
19320 EXPECT_EQ(0, error3.reporting_upload_depth);
Douglas Creageref5eecdc2018-11-09 20:50:3619321}
19322
Lily Chend3930e72019-03-01 19:31:1119323TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
19324 CreateReportCancelAfterStart) {
19325 StaticSocketDataProvider data;
19326 data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_IO_PENDING));
19327 session_deps_.socket_factory->AddSocketDataProvider(&data);
19328
19329 TestCompletionCallback callback;
19330 auto session = CreateSession(&session_deps_);
19331 auto trans =
19332 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19333 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
19334 EXPECT_EQ(rv, ERR_IO_PENDING);
19335
19336 // Cancel after start.
19337 trans.reset();
19338
19339 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
19340 CheckReport(0 /* index */, 0 /* status_code */, ERR_ABORTED,
19341 IPAddress() /* server_ip */);
19342}
19343
19344TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
19345 CreateReportCancelBeforeReadingBody) {
19346 std::string extra_header_string = extra_headers_.ToString();
19347 MockWrite data_writes[] = {
19348 MockWrite("GET / HTTP/1.1\r\n"
19349 "Host: www.example.org\r\n"
19350 "Connection: keep-alive\r\n"),
19351 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
19352 };
19353 MockRead data_reads[] = {
19354 MockRead("HTTP/1.0 200 OK\r\n"),
19355 MockRead("Content-Length: 100\r\n\r\n"), // Body is never read.
19356 };
19357
19358 StaticSocketDataProvider data(data_reads, data_writes);
19359 session_deps_.socket_factory->AddSocketDataProvider(&data);
19360
19361 SSLSocketDataProvider ssl(ASYNC, OK);
19362 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
19363
19364 TestCompletionCallback callback;
19365 auto session = CreateSession(&session_deps_);
19366 auto trans =
19367 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19368 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
19369 EXPECT_THAT(callback.GetResult(rv), IsOk());
19370
19371 const HttpResponseInfo* response = trans->GetResponseInfo();
19372 ASSERT_TRUE(response);
19373
19374 EXPECT_TRUE(response->headers);
19375 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
19376
19377 // Cancel before reading the body.
19378 trans.reset();
19379
19380 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
19381 CheckReport(0 /* index */, 200 /* status_code */, ERR_ABORTED);
19382}
19383
Lily Chen00196ab62018-12-04 19:52:2919384TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, DontCreateReportHttp) {
19385 base::HistogramTester histograms;
19386 RequestPolicy();
19387 EXPECT_EQ(1u, network_error_logging_service()->headers().size());
19388 EXPECT_EQ(1u, network_error_logging_service()->errors().size());
19389
19390 // Make HTTP request
19391 std::string extra_header_string = extra_headers_.ToString();
19392 MockRead data_reads[] = {
19393 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
19394 MockRead("hello world"),
19395 MockRead(SYNCHRONOUS, OK),
19396 };
19397 MockWrite data_writes[] = {
19398 MockWrite("GET / HTTP/1.1\r\n"
19399 "Host: www.example.org\r\n"
19400 "Connection: keep-alive\r\n"),
19401 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
19402 };
19403
Lily Chend3930e72019-03-01 19:31:1119404 StaticSocketDataProvider data(data_reads, data_writes);
19405 session_deps_.socket_factory->AddSocketDataProvider(&data);
Lily Chen00196ab62018-12-04 19:52:2919406
Lily Chenfec60d92019-01-24 01:16:4219407 // Insecure url
19408 url_ = "http://www.example.org/";
19409 request_.url = GURL(url_);
19410
Lily Chen00196ab62018-12-04 19:52:2919411 TestCompletionCallback callback;
19412 auto session = CreateSession(&session_deps_);
Lily Chenfec60d92019-01-24 01:16:4219413 auto trans =
19414 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19415 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
19416 EXPECT_THAT(callback.GetResult(rv), IsOk());
19417
19418 std::string response_data;
19419 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
19420 EXPECT_EQ("hello world", response_data);
Lily Chen00196ab62018-12-04 19:52:2919421
19422 // Insecure request does not generate a report
19423 histograms.ExpectBucketCount(
19424 NetworkErrorLoggingService::kRequestOutcomeHistogram,
Tsuyoshi Horo0b042232019-03-06 01:11:0519425 NetworkErrorLoggingService::RequestOutcome::kDiscardedInsecureOrigin, 1);
Lily Chen00196ab62018-12-04 19:52:2919426
19427 EXPECT_EQ(1u, network_error_logging_service()->errors().size());
19428}
19429
19430TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
19431 DontCreateReportHttpError) {
19432 base::HistogramTester histograms;
19433 RequestPolicy();
19434 EXPECT_EQ(1u, network_error_logging_service()->headers().size());
19435 EXPECT_EQ(1u, network_error_logging_service()->errors().size());
19436
19437 // Make HTTP request that fails
19438 MockRead data_reads[] = {
19439 MockRead("hello world"),
19440 MockRead(SYNCHRONOUS, OK),
19441 };
19442
19443 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
19444 session_deps_.socket_factory->AddSocketDataProvider(&data);
19445
Lily Chenfec60d92019-01-24 01:16:4219446 url_ = "http://www.originwithoutpolicy.com:2000/";
19447 request_.url = GURL(url_);
19448
Lily Chen00196ab62018-12-04 19:52:2919449 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19450
Lily Chen00196ab62018-12-04 19:52:2919451 auto trans =
19452 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Lily Chen00196ab62018-12-04 19:52:2919453 TestCompletionCallback callback;
Lily Chenfec60d92019-01-24 01:16:4219454 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
Lily Chen00196ab62018-12-04 19:52:2919455 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_INVALID_HTTP_RESPONSE));
19456
19457 // Insecure request does not generate a report, regardless of existence of a
19458 // policy for the origin.
19459 histograms.ExpectBucketCount(
19460 NetworkErrorLoggingService::kRequestOutcomeHistogram,
Tsuyoshi Horo0b042232019-03-06 01:11:0519461 NetworkErrorLoggingService::RequestOutcome::kDiscardedInsecureOrigin, 1);
Lily Chen00196ab62018-12-04 19:52:2919462
19463 EXPECT_EQ(1u, network_error_logging_service()->errors().size());
19464}
19465
Lily Chen90ae93cc2019-02-14 01:15:3919466// Don't report on proxy auth challenges, don't report if connecting through a
19467// proxy.
19468TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, DontCreateReportProxy) {
19469 HttpRequestInfo request;
19470 request.method = "GET";
19471 request.url = GURL("https://www.example.org/");
19472 request.traffic_annotation =
19473 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19474
19475 // Configure against proxy server "myproxy:70".
19476 session_deps_.proxy_resolution_service =
19477 ProxyResolutionService::CreateFixedFromPacResult(
19478 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
19479 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19480
19481 // Since we have proxy, should try to establish tunnel.
19482 MockWrite data_writes1[] = {
19483 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
19484 "Host: www.example.org:443\r\n"
19485 "Proxy-Connection: keep-alive\r\n\r\n"),
19486 };
19487
19488 // The proxy responds to the connect with a 407, using a non-persistent
19489 // connection.
19490 MockRead data_reads1[] = {
19491 // No credentials.
19492 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
19493 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
19494 MockRead("Proxy-Connection: close\r\n\r\n"),
19495 };
19496
19497 MockWrite data_writes2[] = {
19498 // After calling trans->RestartWithAuth(), this is the request we should
19499 // be issuing -- the final header line contains the credentials.
19500 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
19501 "Host: www.example.org:443\r\n"
19502 "Proxy-Connection: keep-alive\r\n"
19503 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
19504
19505 MockWrite("GET / HTTP/1.1\r\n"
19506 "Host: www.example.org\r\n"
19507 "Connection: keep-alive\r\n\r\n"),
19508 };
19509
19510 MockRead data_reads2[] = {
19511 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
19512
19513 MockRead("HTTP/1.1 200 OK\r\n"),
19514 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
19515 MockRead("Content-Length: 5\r\n\r\n"),
19516 MockRead(SYNCHRONOUS, "hello"),
19517 };
19518
19519 StaticSocketDataProvider data1(data_reads1, data_writes1);
19520 session_deps_.socket_factory->AddSocketDataProvider(&data1);
19521 StaticSocketDataProvider data2(data_reads2, data_writes2);
19522 session_deps_.socket_factory->AddSocketDataProvider(&data2);
19523 SSLSocketDataProvider ssl(ASYNC, OK);
19524 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
19525
19526 TestCompletionCallback callback1;
19527
19528 auto trans =
19529 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19530
19531 int rv = trans->Start(&request, callback1.callback(), NetLogWithSource());
19532 EXPECT_THAT(callback1.GetResult(rv), IsOk());
19533
19534 const HttpResponseInfo* response = trans->GetResponseInfo();
19535 EXPECT_EQ(407, response->headers->response_code());
19536
19537 std::string response_data;
19538 rv = ReadTransaction(trans.get(), &response_data);
19539 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
19540
19541 // No NEL report is generated for the 407.
19542 EXPECT_EQ(0u, network_error_logging_service()->errors().size());
19543
19544 TestCompletionCallback callback2;
19545
19546 rv =
19547 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
19548 EXPECT_THAT(callback2.GetResult(rv), IsOk());
19549
19550 response = trans->GetResponseInfo();
19551 EXPECT_EQ(200, response->headers->response_code());
19552
19553 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
19554 EXPECT_EQ("hello", response_data);
19555
19556 trans.reset();
19557
19558 // No NEL report is generated because we are behind a proxy.
19559 EXPECT_EQ(0u, network_error_logging_service()->errors().size());
19560}
19561
Douglas Creageref5eecdc2018-11-09 20:50:3619562TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
19563 ReportContainsUploadDepth) {
19564 reporting_upload_depth_ = 7;
Lily Chenfec60d92019-01-24 01:16:4219565 request_.reporting_upload_depth = reporting_upload_depth_;
Douglas Creageref5eecdc2018-11-09 20:50:3619566 RequestPolicy();
19567 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
Lily Chenfec60d92019-01-24 01:16:4219568 const NetworkErrorLoggingService::RequestDetails& error =
19569 network_error_logging_service()->errors()[0];
Douglas Creageref5eecdc2018-11-09 20:50:3619570 EXPECT_EQ(7, error.reporting_upload_depth);
19571}
19572
Lily Chenfec60d92019-01-24 01:16:4219573TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, ReportElapsedTime) {
19574 std::string extra_header_string = extra_headers_.ToString();
19575 static const base::TimeDelta kSleepDuration =
19576 base::TimeDelta::FromMilliseconds(10);
19577
19578 std::vector<MockWrite> data_writes = {
19579 MockWrite(ASYNC, 0,
19580 "GET / HTTP/1.1\r\n"
19581 "Host: www.example.org\r\n"
19582 "Connection: keep-alive\r\n"),
19583 MockWrite(ASYNC, 1, extra_header_string.data()),
19584 };
19585
19586 std::vector<MockRead> data_reads = {
19587 // Write one byte of the status line, followed by a pause.
19588 MockRead(ASYNC, 2, "H"),
19589 MockRead(ASYNC, ERR_IO_PENDING, 3),
19590 MockRead(ASYNC, 4, "TTP/1.1 200 OK\r\n\r\n"),
19591 MockRead(ASYNC, 5, "hello world"),
19592 MockRead(SYNCHRONOUS, OK, 6),
19593 };
19594
19595 SequencedSocketData data(data_reads, data_writes);
19596 session_deps_.socket_factory->AddSocketDataProvider(&data);
19597
19598 SSLSocketDataProvider ssl(ASYNC, OK);
19599 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
19600
19601 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19602
19603 auto trans =
19604 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19605
19606 TestCompletionCallback callback;
19607
19608 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
19609 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
19610
19611 data.RunUntilPaused();
19612 ASSERT_TRUE(data.IsPaused());
19613 FastForwardBy(kSleepDuration);
19614 data.Resume();
19615
19616 EXPECT_THAT(callback.GetResult(rv), IsOk());
19617
19618 std::string response_data;
19619 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
19620 EXPECT_EQ("hello world", response_data);
19621
19622 trans.reset();
19623
Douglas Creageref5eecdc2018-11-09 20:50:3619624 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
Lily Chenfec60d92019-01-24 01:16:4219625
19626 CheckReport(0 /* index */, 200 /* status_code */, OK);
19627
19628 const NetworkErrorLoggingService::RequestDetails& error =
19629 network_error_logging_service()->errors()[0];
19630
19631 // Sanity-check elapsed time in error report
19632 EXPECT_EQ(kSleepDuration, error.elapsed_time);
Douglas Creageref5eecdc2018-11-09 20:50:3619633}
Lily Chenfec60d92019-01-24 01:16:4219634
Douglas Creager3cb042052018-11-06 23:08:5219635#endif // BUILDFLAG(ENABLE_REPORTING)
19636
[email protected]89ceba9a2009-03-21 03:46:0619637} // namespace net