blob: 816e546d32a119a70f0e46cf2c2f7fa2aa068e3b [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"
Adam Rice425cf122015-01-19 06:18:2465#include "net/http/http_request_headers.h"
mmenke5f94fda2016-06-02 20:54:1366#include "net/http/http_response_info.h"
[email protected]17291a022011-10-10 07:32:5367#include "net/http/http_server_properties_impl.h"
[email protected]0877e3d2009-10-17 22:29:5768#include "net/http/http_stream.h"
[email protected]8e6441ca2010-08-19 05:56:3869#include "net/http/http_stream_factory.h"
[email protected]c41737d2014-05-14 07:47:1970#include "net/http/http_transaction_test_util.h"
eroman87c53d62015-04-02 06:51:0771#include "net/log/net_log.h"
mikecirone8b85c432016-09-08 19:11:0072#include "net/log/net_log_event_type.h"
mikecironef22f9812016-10-04 03:40:1973#include "net/log/net_log_source.h"
vishal.b62985ca92015-04-17 08:45:5174#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4675#include "net/log/test_net_log_entry.h"
76#include "net/log/test_net_log_util.h"
Lily Houghton582d4622018-01-22 22:43:4077#include "net/proxy_resolution/mock_proxy_resolver.h"
78#include "net/proxy_resolution/proxy_config_service_fixed.h"
79#include "net/proxy_resolution/proxy_info.h"
Lily Houghtonffe89daa02018-03-09 18:30:0380#include "net/proxy_resolution/proxy_resolution_service.h"
Lily Houghton582d4622018-01-22 22:43:4081#include "net/proxy_resolution/proxy_resolver.h"
82#include "net/proxy_resolution/proxy_resolver_factory.h"
[email protected]f7984fc62009-06-22 23:26:4483#include "net/socket/client_socket_factory.h"
mmenked3641e12016-01-28 16:06:1584#include "net/socket/client_socket_pool.h"
[email protected]483fa202013-05-14 01:07:0385#include "net/socket/client_socket_pool_manager.h"
ttuttle1f2d7e92015-04-28 16:17:4786#include "net/socket/connection_attempts.h"
[email protected]a42dbd142011-11-17 16:42:0287#include "net/socket/mock_client_socket_pool_manager.h"
[email protected]bb88e1d32013-05-03 23:11:0788#include "net/socket/next_proto.h"
Paul Jensena457017a2018-01-19 23:52:0489#include "net/socket/socket_tag.h"
[email protected]f7984fc62009-06-22 23:26:4490#include "net/socket/socket_test_util.h"
Matt Menke4b412da2019-01-25 19:31:1291#include "net/socket/socks_connect_job.h"
[email protected]f7984fc62009-06-22 23:26:4492#include "net/socket/ssl_client_socket.h"
Bence Béky94658bf2018-05-11 19:22:5893#include "net/spdy/spdy_session.h"
94#include "net/spdy/spdy_session_pool.h"
95#include "net/spdy/spdy_test_util_common.h"
nharperb7441ef2016-01-25 23:54:1496#include "net/ssl/default_channel_id_store.h"
[email protected]536fd0b2013-03-14 17:41:5797#include "net/ssl/ssl_cert_request_info.h"
[email protected]e86839fd2013-08-14 18:29:0398#include "net/ssl/ssl_config_service.h"
[email protected]536fd0b2013-03-14 17:41:5799#include "net/ssl/ssl_info.h"
svaldez7872fd02015-11-19 21:10:54100#include "net/ssl/ssl_private_key.h"
[email protected]6e7845ae2013-03-29 21:48:11101#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:01102#include "net/test/gtest_util.h"
rsleevia69c79a2016-06-22 03:28:43103#include "net/test/test_data_directory.h"
Bence Béky98447b12018-05-08 03:14:01104#include "net/test/test_with_scoped_task_environment.h"
Victor Vasiliev27cc7712019-01-24 11:50:14105#include "net/third_party/quiche/src/spdy/core/spdy_framer.h"
[email protected]baee31a2018-01-18 06:10:23106#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
Matt Menked732ea42019-03-08 12:05:00107#include "net/url_request/static_http_user_agent_settings.h"
[email protected]831e4a32013-11-14 02:14:44108#include "net/websockets/websocket_handshake_stream_base.h"
Bence Békydca6bd92018-01-30 13:43:06109#include "net/websockets/websocket_test_util.h"
bncf4588402015-11-24 13:33:18110#include "testing/gmock/include/gmock/gmock.h"
initial.commit586acc5fe2008-07-26 22:42:52111#include "testing/gtest/include/gtest/gtest.h"
[email protected]23887f04f2008-12-02 19:20:15112#include "testing/platform_test.h"
[email protected]795cbf82013-07-22 09:37:27113#include "url/gurl.h"
initial.commit586acc5fe2008-07-26 22:42:52114
Zentaro Kavanagh5b27a6e22017-09-25 23:00:37115#if defined(NTLM_PORTABLE)
116#include "base/base64.h"
117#include "net/ntlm/ntlm_test_data.h"
118#endif
119
Douglas Creager3cb042052018-11-06 23:08:52120#if BUILDFLAG(ENABLE_REPORTING)
121#include "net/network_error_logging/network_error_logging_service.h"
122#include "net/network_error_logging/network_error_logging_test_util.h"
Douglas Creager134b52e2018-11-09 18:00:14123#include "net/reporting/reporting_cache.h"
124#include "net/reporting/reporting_client.h"
125#include "net/reporting/reporting_header_parser.h"
126#include "net/reporting/reporting_service.h"
127#include "net/reporting/reporting_test_util.h"
Douglas Creager3cb042052018-11-06 23:08:52128#endif // BUILDFLAG(ENABLE_REPORTING)
129
robpercival214763f2016-07-01 23:27:01130using net::test::IsError;
131using net::test::IsOk;
132
[email protected]ad65a3e2013-12-25 18:18:01133using base::ASCIIToUTF16;
134
initial.commit586acc5fe2008-07-26 22:42:52135//-----------------------------------------------------------------------------
136
ttuttle859dc7a2015-04-23 19:42:29137namespace net {
138
[email protected]13c8a092010-07-29 06:15:44139namespace {
140
[email protected]42cba2fb2013-03-29 19:58:57141const base::string16 kBar(ASCIIToUTF16("bar"));
142const base::string16 kBar2(ASCIIToUTF16("bar2"));
143const base::string16 kBar3(ASCIIToUTF16("bar3"));
144const base::string16 kBaz(ASCIIToUTF16("baz"));
145const base::string16 kFirst(ASCIIToUTF16("first"));
146const base::string16 kFoo(ASCIIToUTF16("foo"));
147const base::string16 kFoo2(ASCIIToUTF16("foo2"));
148const base::string16 kFoo3(ASCIIToUTF16("foo3"));
149const base::string16 kFou(ASCIIToUTF16("fou"));
150const base::string16 kSecond(ASCIIToUTF16("second"));
[email protected]42cba2fb2013-03-29 19:58:57151const base::string16 kWrongPassword(ASCIIToUTF16("wrongpassword"));
[email protected]13c8a092010-07-29 06:15:44152
bnc2df4b522016-07-08 18:17:43153const char kAlternativeServiceHttpHeader[] =
154 "Alt-Svc: h2=\"mail.example.org:443\"\r\n";
155
ttuttle859dc7a2015-04-23 19:42:29156int GetIdleSocketCountInTransportSocketPool(HttpNetworkSession* session) {
Matt Menked23ab952019-03-06 00:24:40157 return session
158 ->GetSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL,
159 ProxyServer::Direct())
ttuttle859dc7a2015-04-23 19:42:29160 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02161}
162
ttuttle859dc7a2015-04-23 19:42:29163bool IsTransportSocketPoolStalled(HttpNetworkSession* session) {
Matt Menked23ab952019-03-06 00:24:40164 return session
165 ->GetSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL,
166 ProxyServer::Direct())
ttuttle859dc7a2015-04-23 19:42:29167 ->IsStalled();
[email protected]043b68c82013-08-22 23:41:52168}
169
[email protected]f3da152d2012-06-02 01:00:57170// Takes in a Value created from a NetLogHttpResponseParameter, and returns
171// a JSONified list of headers as a single string. Uses single quotes instead
172// of double quotes for easier comparison. Returns false on failure.
[email protected]ea5ef4c2013-06-13 22:50:27173bool GetHeaders(base::DictionaryValue* params, std::string* headers) {
[email protected]f3da152d2012-06-02 01:00:57174 if (!params)
175 return false;
[email protected]ea5ef4c2013-06-13 22:50:27176 base::ListValue* header_list;
[email protected]f3da152d2012-06-02 01:00:57177 if (!params->GetList("headers", &header_list))
178 return false;
179 std::string double_quote_headers;
estade8d046462015-05-16 01:02:34180 base::JSONWriter::Write(*header_list, &double_quote_headers);
[email protected]466c9862013-12-03 22:05:28181 base::ReplaceChars(double_quote_headers, "\"", "'", headers);
[email protected]f3da152d2012-06-02 01:00:57182 return true;
183}
184
[email protected]029c83b62013-01-24 05:28:20185// Tests LoadTimingInfo in the case a socket is reused and no PAC script is
186// used.
ttuttle859dc7a2015-04-23 19:42:29187void TestLoadTimingReused(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20188 EXPECT_TRUE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19189 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]58e32bb2013-01-21 18:23:25190
[email protected]029c83b62013-01-24 05:28:20191 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
192 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
193
ttuttle859dc7a2015-04-23 19:42:29194 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20195 EXPECT_FALSE(load_timing_info.send_start.is_null());
[email protected]58e32bb2013-01-21 18:23:25196
197 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]58e32bb2013-01-21 18:23:25198
[email protected]3b23a222013-05-15 21:33:25199 // Set at a higher level.
[email protected]58e32bb2013-01-21 18:23:25200 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
201 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25202 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25203}
204
[email protected]029c83b62013-01-24 05:28:20205// Tests LoadTimingInfo in the case a new socket is used and no PAC script is
206// used.
ttuttle859dc7a2015-04-23 19:42:29207void TestLoadTimingNotReused(const LoadTimingInfo& load_timing_info,
[email protected]58e32bb2013-01-21 18:23:25208 int connect_timing_flags) {
[email protected]029c83b62013-01-24 05:28:20209 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19210 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20211
212 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
213 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
214
ttuttle859dc7a2015-04-23 19:42:29215 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
216 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20217 EXPECT_LE(load_timing_info.connect_timing.connect_end,
218 load_timing_info.send_start);
219
220 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20221
[email protected]3b23a222013-05-15 21:33:25222 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20223 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
224 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25225 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20226}
227
228// Tests LoadTimingInfo in the case a socket is reused and a PAC script is
229// used.
ttuttle859dc7a2015-04-23 19:42:29230void TestLoadTimingReusedWithPac(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20231 EXPECT_TRUE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19232 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20233
ttuttle859dc7a2015-04-23 19:42:29234 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20235
236 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
237 EXPECT_LE(load_timing_info.proxy_resolve_start,
238 load_timing_info.proxy_resolve_end);
239 EXPECT_LE(load_timing_info.proxy_resolve_end,
240 load_timing_info.send_start);
241 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20242
[email protected]3b23a222013-05-15 21:33:25243 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20244 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
245 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25246 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20247}
248
249// Tests LoadTimingInfo in the case a new socket is used and a PAC script is
250// used.
ttuttle859dc7a2015-04-23 19:42:29251void TestLoadTimingNotReusedWithPac(const LoadTimingInfo& load_timing_info,
[email protected]029c83b62013-01-24 05:28:20252 int connect_timing_flags) {
253 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19254 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20255
256 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
257 EXPECT_LE(load_timing_info.proxy_resolve_start,
258 load_timing_info.proxy_resolve_end);
259 EXPECT_LE(load_timing_info.proxy_resolve_end,
260 load_timing_info.connect_timing.connect_start);
ttuttle859dc7a2015-04-23 19:42:29261 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
262 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20263 EXPECT_LE(load_timing_info.connect_timing.connect_end,
264 load_timing_info.send_start);
265
266 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20267
[email protected]3b23a222013-05-15 21:33:25268 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20269 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
270 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25271 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25272}
273
Matt Menke2436b2f2018-12-11 18:07:11274// ProxyResolver that records URLs passed to it, and that can be told what
275// result to return.
276class CapturingProxyResolver : public ProxyResolver {
277 public:
278 CapturingProxyResolver()
279 : proxy_server_(ProxyServer::SCHEME_HTTP, HostPortPair("myproxy", 80)) {}
280 ~CapturingProxyResolver() override = default;
281
282 int GetProxyForURL(const GURL& url,
283 ProxyInfo* results,
284 CompletionOnceCallback callback,
285 std::unique_ptr<Request>* request,
286 const NetLogWithSource& net_log) override {
287 results->UseProxyServer(proxy_server_);
288 resolved_.push_back(url);
289 return OK;
290 }
291
292 // Sets whether the resolver should use direct connections, instead of a
293 // proxy.
294 void set_proxy_server(ProxyServer proxy_server) {
295 proxy_server_ = proxy_server;
296 }
297
298 const std::vector<GURL>& resolved() const { return resolved_; }
299
300 private:
301 std::vector<GURL> resolved_;
302
303 ProxyServer proxy_server_;
304
305 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
306};
307
308class CapturingProxyResolverFactory : public ProxyResolverFactory {
309 public:
310 explicit CapturingProxyResolverFactory(CapturingProxyResolver* resolver)
311 : ProxyResolverFactory(false), resolver_(resolver) {}
312
313 int CreateProxyResolver(const scoped_refptr<PacFileData>& pac_script,
314 std::unique_ptr<ProxyResolver>* resolver,
315 CompletionOnceCallback callback,
316 std::unique_ptr<Request>* request) override {
317 *resolver = std::make_unique<ForwardingProxyResolver>(resolver_);
318 return OK;
319 }
320
321 private:
322 ProxyResolver* resolver_;
323};
324
danakj1fd259a02016-04-16 03:17:09325std::unique_ptr<HttpNetworkSession> CreateSession(
mmenkee65e7af2015-10-13 17:16:42326 SpdySessionDependencies* session_deps) {
[email protected]c6bf8152012-12-02 07:43:34327 return SpdySessionDependencies::SpdyCreateSession(session_deps);
[email protected]e8d536192008-10-17 22:21:14328}
329
xunjieli96f2a402017-06-05 17:24:27330class FailingProxyResolverFactory : public ProxyResolverFactory {
331 public:
332 FailingProxyResolverFactory() : ProxyResolverFactory(false) {}
333
334 // ProxyResolverFactory override.
Lily Houghton99597862018-03-07 16:40:42335 int CreateProxyResolver(const scoped_refptr<PacFileData>& script_data,
336 std::unique_ptr<ProxyResolver>* result,
Bence Békycc5b88a2018-05-25 20:24:17337 CompletionOnceCallback callback,
Lily Houghton99597862018-03-07 16:40:42338 std::unique_ptr<Request>* request) override {
xunjieli96f2a402017-06-05 17:24:27339 return ERR_PAC_SCRIPT_FAILED;
340 }
341};
342
David Benjamin5cb91132018-04-06 05:54:49343class TestSSLConfigService : public SSLConfigService {
344 public:
345 explicit TestSSLConfigService(const SSLConfig& config) : config_(config) {}
Ryan Sleevib8449e02018-07-15 04:31:07346 ~TestSSLConfigService() override = default;
David Benjamin5cb91132018-04-06 05:54:49347
348 void GetSSLConfig(SSLConfig* config) override { *config = config_; }
349
Nick Harper89bc7212018-07-31 19:07:57350 bool CanShareConnectionWithClientCerts(
351 const std::string& hostname) const override {
352 return false;
353 }
354
David Benjamin5cb91132018-04-06 05:54:49355 private:
David Benjamin5cb91132018-04-06 05:54:49356 SSLConfig config_;
357};
358
[email protected]448d4ca52012-03-04 04:12:23359} // namespace
360
Bence Béky98447b12018-05-08 03:14:01361class HttpNetworkTransactionTest : public PlatformTest,
362 public WithScopedTaskEnvironment {
[email protected]483fa202013-05-14 01:07:03363 public:
bncd16676a2016-07-20 16:23:01364 ~HttpNetworkTransactionTest() override {
[email protected]483fa202013-05-14 01:07:03365 // Important to restore the per-pool limit first, since the pool limit must
366 // always be greater than group limit, and the tests reduce both limits.
367 ClientSocketPoolManager::set_max_sockets_per_pool(
368 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
369 ClientSocketPoolManager::set_max_sockets_per_group(
370 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
371 }
372
[email protected]e3ceb682011-06-28 23:55:46373 protected:
[email protected]23e482282013-06-14 16:08:02374 HttpNetworkTransactionTest()
Andrew Comminos517a92c2019-01-14 17:49:56375 : WithScopedTaskEnvironment(
376 base::test::ScopedTaskEnvironment::MainThreadType::IO_MOCK_TIME,
377 base::test::ScopedTaskEnvironment::NowSource::
378 MAIN_THREAD_MOCK_TIME),
379 ssl_(ASYNC, OK),
bnc032658ba2016-09-26 18:17:15380 old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
[email protected]483fa202013-05-14 01:07:03381 HttpNetworkSession::NORMAL_SOCKET_POOL)),
382 old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
383 HttpNetworkSession::NORMAL_SOCKET_POOL)) {
bnca86731e2017-04-17 12:31:28384 session_deps_.enable_http2_alternative_service = true;
[email protected]483fa202013-05-14 01:07:03385 }
[email protected]bb88e1d32013-05-03 23:11:07386
[email protected]e3ceb682011-06-28 23:55:46387 struct SimpleGetHelperResult {
388 int rv;
389 std::string status_line;
390 std::string response_data;
sclittlefb249892015-09-10 21:33:22391 int64_t total_received_bytes;
392 int64_t total_sent_bytes;
[email protected]58e32bb2013-01-21 18:23:25393 LoadTimingInfo load_timing_info;
ttuttle1f2d7e92015-04-28 16:17:47394 ConnectionAttempts connection_attempts;
ttuttled9dbc652015-09-29 20:00:59395 IPEndPoint remote_endpoint_after_start;
[email protected]e3ceb682011-06-28 23:55:46396 };
397
dcheng67be2b1f2014-10-27 21:47:29398 void SetUp() override {
[email protected]0b0bf032010-09-21 18:08:50399 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55400 base::RunLoop().RunUntilIdle();
Andrew Comminos517a92c2019-01-14 17:49:56401 // Set an initial delay to ensure that the first call to TimeTicks::Now()
402 // before incrementing the counter does not return a null value.
403 FastForwardBy(TimeDelta::FromSeconds(1));
[email protected]2ff8b312010-04-26 22:20:54404 }
405
dcheng67be2b1f2014-10-27 21:47:29406 void TearDown() override {
[email protected]0b0bf032010-09-21 18:08:50407 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55408 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09409 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:55410 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09411 PlatformTest::TearDown();
[email protected]0b0bf032010-09-21 18:08:50412 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55413 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09414 }
415
Andrew Comminos1f2ff1cc2018-12-14 05:22:38416 void Check100ResponseTiming(bool use_spdy);
417
[email protected]202965992011-12-07 23:04:51418 // Either |write_failure| specifies a write failure or |read_failure|
419 // specifies a read failure when using a reused socket. In either case, the
420 // failure should cause the network transaction to resend the request, and the
421 // other argument should be NULL.
422 void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
423 const MockRead* read_failure);
initial.commit586acc5fe2008-07-26 22:42:52424
[email protected]a34f61ee2014-03-18 20:59:49425 // Either |write_failure| specifies a write failure or |read_failure|
426 // specifies a read failure when using a reused socket. In either case, the
427 // failure should cause the network transaction to resend the request, and the
428 // other argument should be NULL.
429 void PreconnectErrorResendRequestTest(const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:10430 const MockRead* read_failure,
431 bool use_spdy);
[email protected]a34f61ee2014-03-18 20:59:49432
Ryan Sleevib8d7ea02018-05-07 20:01:01433 SimpleGetHelperResult SimpleGetHelperForData(
434 base::span<StaticSocketDataProvider*> providers) {
[email protected]ff007e162009-05-23 09:13:15435 SimpleGetHelperResult out;
initial.commit586acc5fe2008-07-26 22:42:52436
[email protected]ff007e162009-05-23 09:13:15437 HttpRequestInfo request;
438 request.method = "GET";
bncce36dca22015-04-21 22:11:23439 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:10440 request.traffic_annotation =
441 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:52442
vishal.b62985ca92015-04-17 08:45:51443 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:07444 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:09445 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16446 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:27447
Ryan Sleevib8d7ea02018-05-07 20:01:01448 for (auto* provider : providers) {
449 session_deps_.socket_factory->AddSocketDataProvider(provider);
[email protected]5a60c8b2011-10-19 20:14:29450 }
initial.commit586acc5fe2008-07-26 22:42:52451
[email protected]49639fa2011-12-20 23:22:41452 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52453
eroman24bc6a12015-05-06 19:55:48454 EXPECT_TRUE(log.bound().IsCapturing());
bnc691fda62016-08-12 00:43:16455 int rv = trans.Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:01456 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:52457
[email protected]ff007e162009-05-23 09:13:15458 out.rv = callback.WaitForResult();
bnc691fda62016-08-12 00:43:16459 out.total_received_bytes = trans.GetTotalReceivedBytes();
460 out.total_sent_bytes = trans.GetTotalSentBytes();
[email protected]58e32bb2013-01-21 18:23:25461
462 // Even in the failure cases that use this function, connections are always
463 // successfully established before the error.
bnc691fda62016-08-12 00:43:16464 EXPECT_TRUE(trans.GetLoadTimingInfo(&out.load_timing_info));
[email protected]58e32bb2013-01-21 18:23:25465 TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
466
[email protected]ff007e162009-05-23 09:13:15467 if (out.rv != OK)
468 return out;
469
bnc691fda62016-08-12 00:43:16470 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50471 // Can't use ASSERT_* inside helper functions like this, so
472 // return an error.
wezca1070932016-05-26 20:30:52473 if (!response || !response->headers) {
[email protected]fe2255a2011-09-20 19:37:50474 out.rv = ERR_UNEXPECTED;
475 return out;
476 }
[email protected]ff007e162009-05-23 09:13:15477 out.status_line = response->headers->GetStatusLine();
478
Tsuyoshi Horo01faed62019-02-20 22:11:37479 EXPECT_EQ("127.0.0.1", response->remote_endpoint.ToStringWithoutPort());
480 EXPECT_EQ(80, response->remote_endpoint.port());
[email protected]6d81b482011-02-22 19:47:19481
ttuttled9dbc652015-09-29 20:00:59482 bool got_endpoint =
bnc691fda62016-08-12 00:43:16483 trans.GetRemoteEndpoint(&out.remote_endpoint_after_start);
ttuttled9dbc652015-09-29 20:00:59484 EXPECT_EQ(got_endpoint,
485 out.remote_endpoint_after_start.address().size() > 0);
486
bnc691fda62016-08-12 00:43:16487 rv = ReadTransaction(&trans, &out.response_data);
robpercival214763f2016-07-01 23:27:01488 EXPECT_THAT(rv, IsOk());
[email protected]b2fcd0e2010-12-01 15:19:40489
mmenke43758e62015-05-04 21:09:46490 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40491 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:39492 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00493 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
494 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:39495 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00496 entries, pos, NetLogEventType::HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
497 NetLogEventPhase::NONE);
[email protected]ff007e162009-05-23 09:13:15498
[email protected]f3da152d2012-06-02 01:00:57499 std::string line;
500 EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
501 EXPECT_EQ("GET / HTTP/1.1\r\n", line);
502
[email protected]79e1fd62013-06-20 06:50:04503 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:16504 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:04505 std::string value;
506 EXPECT_TRUE(request_headers.GetHeader("Host", &value));
bncce36dca22015-04-21 22:11:23507 EXPECT_EQ("www.example.org", value);
[email protected]79e1fd62013-06-20 06:50:04508 EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
509 EXPECT_EQ("keep-alive", value);
510
511 std::string response_headers;
512 EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
bncce36dca22015-04-21 22:11:23513 EXPECT_EQ("['Host: www.example.org','Connection: keep-alive']",
[email protected]79e1fd62013-06-20 06:50:04514 response_headers);
[email protected]3deb9a52010-11-11 00:24:40515
bnc691fda62016-08-12 00:43:16516 out.total_received_bytes = trans.GetTotalReceivedBytes();
sclittlefb249892015-09-10 21:33:22517 // The total number of sent bytes should not have changed.
bnc691fda62016-08-12 00:43:16518 EXPECT_EQ(out.total_sent_bytes, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:22519
bnc691fda62016-08-12 00:43:16520 trans.GetConnectionAttempts(&out.connection_attempts);
[email protected]aecfbf22008-10-16 02:02:47521 return out;
[email protected]ff007e162009-05-23 09:13:15522 }
initial.commit586acc5fe2008-07-26 22:42:52523
Ryan Sleevib8d7ea02018-05-07 20:01:01524 SimpleGetHelperResult SimpleGetHelper(base::span<const MockRead> data_reads) {
sclittlefb249892015-09-10 21:33:22525 MockWrite data_writes[] = {
526 MockWrite("GET / HTTP/1.1\r\n"
527 "Host: www.example.org\r\n"
528 "Connection: keep-alive\r\n\r\n"),
529 };
[email protected]5a60c8b2011-10-19 20:14:29530
Ryan Sleevib8d7ea02018-05-07 20:01:01531 StaticSocketDataProvider reads(data_reads, data_writes);
sclittlefb249892015-09-10 21:33:22532 StaticSocketDataProvider* data[] = {&reads};
Ryan Sleevib8d7ea02018-05-07 20:01:01533 SimpleGetHelperResult out = SimpleGetHelperForData(data);
sclittlefb249892015-09-10 21:33:22534
Ryan Sleevib8d7ea02018-05-07 20:01:01535 EXPECT_EQ(CountWriteBytes(data_writes), out.total_sent_bytes);
sclittlefb249892015-09-10 21:33:22536 return out;
[email protected]b8015c42013-12-24 15:18:19537 }
538
bnc032658ba2016-09-26 18:17:15539 void AddSSLSocketData() {
540 ssl_.next_proto = kProtoHTTP2;
Ryan Sleevi4f832092017-11-21 23:25:49541 ssl_.ssl_info.cert =
542 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
543 ASSERT_TRUE(ssl_.ssl_info.cert);
bnc032658ba2016-09-26 18:17:15544 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_);
545 }
546
[email protected]ff007e162009-05-23 09:13:15547 void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
548 int expected_status);
initial.commit586acc5fe2008-07-26 22:42:52549
[email protected]ff007e162009-05-23 09:13:15550 void ConnectStatusHelper(const MockRead& status);
[email protected]bb88e1d32013-05-03 23:11:07551
[email protected]bb88e1d32013-05-03 23:11:07552 void CheckErrorIsPassedBack(int error, IoMode mode);
553
Douglas Creager134b52e2018-11-09 18:00:14554 // These clocks are defined here, even though they're only used in the
555 // Reporting tests below, since they need to be destroyed after
556 // |session_deps_|.
557 base::SimpleTestClock clock_;
558 base::SimpleTestTickClock tick_clock_;
559
[email protected]4bd46222013-05-14 19:32:23560 SpdyTestUtil spdy_util_;
[email protected]bb88e1d32013-05-03 23:11:07561 SpdySessionDependencies session_deps_;
bnc032658ba2016-09-26 18:17:15562 SSLSocketDataProvider ssl_;
[email protected]483fa202013-05-14 01:07:03563
564 // Original socket limits. Some tests set these. Safest to always restore
565 // them once each test has been run.
566 int old_max_group_sockets_;
567 int old_max_pool_sockets_;
[email protected]ff007e162009-05-23 09:13:15568};
[email protected]231d5a32008-09-13 00:45:27569
[email protected]448d4ca52012-03-04 04:12:23570namespace {
571
ryansturm49a8cb12016-06-15 16:51:09572class BeforeHeadersSentHandler {
[email protected]597a1ab2014-06-26 08:12:27573 public:
ryansturm49a8cb12016-06-15 16:51:09574 BeforeHeadersSentHandler()
575 : observed_before_headers_sent_with_proxy_(false),
576 observed_before_headers_sent_(false) {}
[email protected]597a1ab2014-06-26 08:12:27577
ryansturm49a8cb12016-06-15 16:51:09578 void OnBeforeHeadersSent(const ProxyInfo& proxy_info,
579 HttpRequestHeaders* request_headers) {
580 observed_before_headers_sent_ = true;
581 if (!proxy_info.is_http() && !proxy_info.is_https() &&
582 !proxy_info.is_quic()) {
583 return;
584 }
585 observed_before_headers_sent_with_proxy_ = true;
[email protected]597a1ab2014-06-26 08:12:27586 observed_proxy_server_uri_ = proxy_info.proxy_server().ToURI();
587 }
588
ryansturm49a8cb12016-06-15 16:51:09589 bool observed_before_headers_sent_with_proxy() const {
590 return observed_before_headers_sent_with_proxy_;
591 }
592
593 bool observed_before_headers_sent() const {
594 return observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27595 }
596
597 std::string observed_proxy_server_uri() const {
598 return observed_proxy_server_uri_;
599 }
600
601 private:
ryansturm49a8cb12016-06-15 16:51:09602 bool observed_before_headers_sent_with_proxy_;
603 bool observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27604 std::string observed_proxy_server_uri_;
605
ryansturm49a8cb12016-06-15 16:51:09606 DISALLOW_COPY_AND_ASSIGN(BeforeHeadersSentHandler);
[email protected]597a1ab2014-06-26 08:12:27607};
608
[email protected]15a5ccf82008-10-23 19:57:43609// Fill |str| with a long header list that consumes >= |size| bytes.
610void FillLargeHeadersString(std::string* str, int size) {
thestig9d3bb0c2015-01-24 00:49:51611 const char row[] =
[email protected]4ddaf2502008-10-23 18:26:19612 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
613 const int sizeof_row = strlen(row);
614 const int num_rows = static_cast<int>(
615 ceil(static_cast<float>(size) / sizeof_row));
616 const int sizeof_data = num_rows * sizeof_row;
617 DCHECK(sizeof_data >= size);
[email protected]15a5ccf82008-10-23 19:57:43618 str->reserve(sizeof_data);
[email protected]372d34a2008-11-05 21:30:51619
[email protected]4ddaf2502008-10-23 18:26:19620 for (int i = 0; i < num_rows; ++i)
[email protected]15a5ccf82008-10-23 19:57:43621 str->append(row, sizeof_row);
[email protected]4ddaf2502008-10-23 18:26:19622}
623
thakis84dff942015-07-28 20:47:38624#if defined(NTLM_PORTABLE)
Zentaro Kavanagh6ccee512017-09-28 18:34:09625uint64_t MockGetMSTime() {
626 // Tue, 23 May 2017 20:13:07 +0000
627 return 131400439870000000;
628}
629
[email protected]385a4672009-03-11 22:21:29630// Alternative functions that eliminate randomness and dependency on the local
631// host name so that the generated NTLM messages are reproducible.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:37632void MockGenerateRandom(uint8_t* output, size_t n) {
633 // This is set to 0xaa because the client challenge for testing in
634 // [MS-NLMP] Section 4.2.1 is 8 bytes of 0xaa.
635 memset(output, 0xaa, n);
[email protected]385a4672009-03-11 22:21:29636}
637
[email protected]fe2bc6a2009-03-23 16:52:20638std::string MockGetHostName() {
Zentaro Kavanagh5b27a6e22017-09-25 23:00:37639 return ntlm::test::kHostnameAscii;
[email protected]385a4672009-03-11 22:21:29640}
thakis84dff942015-07-28 20:47:38641#endif // defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29642
[email protected]e60e47a2010-07-14 03:37:18643template<typename ParentPool>
644class CaptureGroupNameSocketPool : public ParentPool {
[email protected]04e5be32009-06-26 20:00:31645 public:
[email protected]9e1bdd32011-02-03 21:48:34646 CaptureGroupNameSocketPool(HostResolver* host_resolver,
647 CertVerifier* cert_verifier);
[email protected]e60e47a2010-07-14 03:37:18648
[email protected]d80a4322009-08-14 07:07:49649 const std::string last_group_name_received() const {
650 return last_group_name_;
651 }
652
Tarun Bansal162eabe52018-01-20 01:16:39653 bool socket_requested() const { return socket_requested_; }
654
Matt Menke28ac03e2019-02-25 22:25:50655 int RequestSocket(
656 const std::string& group_name,
657 const void* socket_params,
658 RequestPriority priority,
659 const SocketTag& socket_tag,
660 ClientSocketPool::RespectLimits respect_limits,
661 ClientSocketHandle* handle,
662 CompletionOnceCallback callback,
663 const ClientSocketPool::ProxyAuthCallback& proxy_auth_callback,
664 const NetLogWithSource& net_log) override {
[email protected]04e5be32009-06-26 20:00:31665 last_group_name_ = group_name;
Tarun Bansal162eabe52018-01-20 01:16:39666 socket_requested_ = true;
[email protected]04e5be32009-06-26 20:00:31667 return ERR_IO_PENDING;
668 }
dmichaeld6e570d2014-12-18 22:30:57669 void CancelRequest(const std::string& group_name,
670 ClientSocketHandle* handle) override {}
671 void ReleaseSocket(const std::string& group_name,
danakj1fd259a02016-04-16 03:17:09672 std::unique_ptr<StreamSocket> socket,
dmichaeld6e570d2014-12-18 22:30:57673 int id) override {}
674 void CloseIdleSockets() override {}
xunjieli92feb332017-03-03 17:19:23675 void CloseIdleSocketsInGroup(const std::string& group_name) override {}
dmichaeld6e570d2014-12-18 22:30:57676 int IdleSocketCount() const override { return 0; }
Raul Tambre8335a6d2019-02-21 16:57:43677 size_t IdleSocketCountInGroup(const std::string& group_name) const override {
[email protected]04e5be32009-06-26 20:00:31678 return 0;
679 }
dmichaeld6e570d2014-12-18 22:30:57680 LoadState GetLoadState(const std::string& group_name,
681 const ClientSocketHandle* handle) const override {
[email protected]04e5be32009-06-26 20:00:31682 return LOAD_STATE_IDLE;
683 }
[email protected]d80a4322009-08-14 07:07:49684
685 private:
[email protected]04e5be32009-06-26 20:00:31686 std::string last_group_name_;
Tarun Bansal162eabe52018-01-20 01:16:39687 bool socket_requested_ = false;
[email protected]04e5be32009-06-26 20:00:31688};
689
[email protected]ab739042011-04-07 15:22:28690typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
691CaptureGroupNameTransportSocketPool;
[email protected]e60e47a2010-07-14 03:37:18692
rkaplowd90695c2015-03-25 22:12:41693template <typename ParentPool>
[email protected]e60e47a2010-07-14 03:37:18694CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34695 HostResolver* host_resolver,
696 CertVerifier* /* cert_verifier */)
Matt Menkecb77b5402019-01-28 17:11:23697 : ParentPool(0,
698 0,
Tarun Bansala7635092019-02-20 10:00:59699 base::TimeDelta(),
Raul Tambre94493c652019-03-11 17:18:35700 nullptr,
Matt Menkecb77b5402019-01-28 17:11:23701 host_resolver,
Raul Tambre94493c652019-03-11 17:18:35702 nullptr,
703 nullptr,
704 nullptr,
705 nullptr,
706 nullptr,
707 nullptr,
708 nullptr,
709 nullptr,
710 nullptr,
711 nullptr,
712 nullptr,
713 nullptr,
714 nullptr) {}
[email protected]e60e47a2010-07-14 03:37:18715
[email protected]231d5a32008-09-13 00:45:27716//-----------------------------------------------------------------------------
717
[email protected]79cb5c12011-09-12 13:12:04718// Helper functions for validating that AuthChallengeInfo's are correctly
719// configured for common cases.
720bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
721 if (!auth_challenge)
722 return false;
723 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43724 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04725 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19726 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04727 return true;
728}
729
730bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
731 if (!auth_challenge)
732 return false;
733 EXPECT_TRUE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43734 EXPECT_EQ("http://myproxy:70", auth_challenge->challenger.Serialize());
735 EXPECT_EQ("MyRealm1", auth_challenge->realm);
736 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
737 return true;
738}
739
740bool CheckBasicSecureProxyAuth(const AuthChallengeInfo* auth_challenge) {
741 if (!auth_challenge)
742 return false;
743 EXPECT_TRUE(auth_challenge->is_proxy);
744 EXPECT_EQ("https://myproxy:70", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04745 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19746 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04747 return true;
748}
749
750bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
751 if (!auth_challenge)
752 return false;
753 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43754 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04755 EXPECT_EQ("digestive", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19756 EXPECT_EQ(kDigestAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04757 return true;
758}
759
thakis84dff942015-07-28 20:47:38760#if defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04761bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
762 if (!auth_challenge)
763 return false;
764 EXPECT_FALSE(auth_challenge->is_proxy);
Zentaro Kavanagh1890a3d2018-01-29 19:52:55765 EXPECT_EQ("https://server", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04766 EXPECT_EQ(std::string(), auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19767 EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04768 return true;
769}
David Benjamin5cb91132018-04-06 05:54:49770
771bool CheckNTLMProxyAuth(const AuthChallengeInfo* auth_challenge) {
772 if (!auth_challenge)
773 return false;
774 EXPECT_TRUE(auth_challenge->is_proxy);
775 EXPECT_EQ("http://server", auth_challenge->challenger.Serialize());
776 EXPECT_EQ(std::string(), auth_challenge->realm);
777 EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
778 return true;
779}
thakis84dff942015-07-28 20:47:38780#endif // defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04781
[email protected]448d4ca52012-03-04 04:12:23782} // namespace
783
bncd16676a2016-07-20 16:23:01784TEST_F(HttpNetworkTransactionTest, Basic) {
danakj1fd259a02016-04-16 03:17:09785 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16786 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]231d5a32008-09-13 00:45:27787}
788
bncd16676a2016-07-20 16:23:01789TEST_F(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27790 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35791 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
792 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06793 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27794 };
Ryan Sleevib8d7ea02018-05-07 20:01:01795 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01796 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27797 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
798 EXPECT_EQ("hello world", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01799 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22800 EXPECT_EQ(reads_size, out.total_received_bytes);
ttuttle1f2d7e92015-04-28 16:17:47801 EXPECT_EQ(0u, out.connection_attempts.size());
ttuttled9dbc652015-09-29 20:00:59802
803 EXPECT_FALSE(out.remote_endpoint_after_start.address().empty());
[email protected]231d5a32008-09-13 00:45:27804}
805
806// Response with no status line.
bncd16676a2016-07-20 16:23:01807TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27808 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35809 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06810 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27811 };
Ryan Sleevib8d7ea02018-05-07 20:01:01812 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41813 EXPECT_THAT(out.rv, IsOk());
814 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
815 EXPECT_EQ("hello world", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01816 int64_t reads_size = CountReadBytes(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41817 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27818}
819
mmenkea7da6da2016-09-01 21:56:52820// Response with no status line, and a weird port. Should fail by default.
821TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPort) {
822 MockRead data_reads[] = {
823 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
824 };
825
Ryan Sleevib8d7ea02018-05-07 20:01:01826 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
mmenkea7da6da2016-09-01 21:56:52827 session_deps_.socket_factory->AddSocketDataProvider(&data);
828
829 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
830
krasinc06a72a2016-12-21 03:42:46831 HttpRequestInfo request;
bnc87dcefc2017-05-25 12:47:58832 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:19833 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenkea7da6da2016-09-01 21:56:52834
mmenkea7da6da2016-09-01 21:56:52835 request.method = "GET";
836 request.url = GURL("http://www.example.com:2000/");
Ramin Halavatib5e433e2018-02-07 07:41:10837 request.traffic_annotation =
838 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
839
mmenkea7da6da2016-09-01 21:56:52840 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20841 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52842 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_INVALID_HTTP_RESPONSE));
843}
844
Shivani Sharmafdcaefd2017-11-02 00:12:26845// Tests that request info can be destroyed after the headers phase is complete.
846TEST_F(HttpNetworkTransactionTest, SimpleGETNoReadDestroyRequestInfo) {
847 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
848 auto trans =
849 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
850
851 MockRead data_reads[] = {
852 MockRead("HTTP/1.0 200 OK\r\n"), MockRead("Connection: keep-alive\r\n"),
853 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, 0),
854 };
Ryan Sleevib8d7ea02018-05-07 20:01:01855 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
Shivani Sharmafdcaefd2017-11-02 00:12:26856 session_deps_.socket_factory->AddSocketDataProvider(&data);
857
858 TestCompletionCallback callback;
859
860 {
861 auto request = std::make_unique<HttpRequestInfo>();
862 request->method = "GET";
863 request->url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:10864 request->traffic_annotation =
865 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Shivani Sharmafdcaefd2017-11-02 00:12:26866
867 int rv =
868 trans->Start(request.get(), callback.callback(), NetLogWithSource());
869
870 EXPECT_THAT(callback.GetResult(rv), IsOk());
871 } // Let request info be destroyed.
872
873 trans.reset();
874}
875
mmenkea7da6da2016-09-01 21:56:52876// Response with no status line, and a weird port. Option to allow weird ports
877// enabled.
878TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPortAllowed) {
879 MockRead data_reads[] = {
880 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
881 };
882
Ryan Sleevib8d7ea02018-05-07 20:01:01883 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
mmenkea7da6da2016-09-01 21:56:52884 session_deps_.socket_factory->AddSocketDataProvider(&data);
885 session_deps_.http_09_on_non_default_ports_enabled = true;
886 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
887
krasinc06a72a2016-12-21 03:42:46888 HttpRequestInfo request;
bnc87dcefc2017-05-25 12:47:58889 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:19890 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenkea7da6da2016-09-01 21:56:52891
mmenkea7da6da2016-09-01 21:56:52892 request.method = "GET";
893 request.url = GURL("http://www.example.com:2000/");
Ramin Halavatib5e433e2018-02-07 07:41:10894 request.traffic_annotation =
895 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
896
mmenkea7da6da2016-09-01 21:56:52897 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20898 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52899 EXPECT_THAT(callback.GetResult(rv), IsOk());
900
901 const HttpResponseInfo* info = trans->GetResponseInfo();
902 ASSERT_TRUE(info->headers);
903 EXPECT_EQ("HTTP/0.9 200 OK", info->headers->GetStatusLine());
904
905 // Don't bother to read the body - that's verified elsewhere, important thing
906 // is that the option to allow HTTP/0.9 on non-default ports is respected.
907}
908
[email protected]231d5a32008-09-13 00:45:27909// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01910TEST_F(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27911 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35912 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06913 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27914 };
Ryan Sleevib8d7ea02018-05-07 20:01:01915 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01916 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27917 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
918 EXPECT_EQ("DATA", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01919 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22920 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27921}
922
923// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01924TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27925 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35926 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06927 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27928 };
Ryan Sleevib8d7ea02018-05-07 20:01:01929 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01930 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27931 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
932 EXPECT_EQ("DATA", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01933 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22934 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27935}
936
937// Beyond 4 bytes of slop and it should fail to find a status line.
bncd16676a2016-07-20 16:23:01938TEST_F(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27939 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35940 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06941 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27942 };
Ryan Sleevib8d7ea02018-05-07 20:01:01943 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41944 EXPECT_THAT(out.rv, IsOk());
945 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
946 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01947 int64_t reads_size = CountReadBytes(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41948 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27949}
950
951// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
bncd16676a2016-07-20 16:23:01952TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27953 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35954 MockRead("\n"),
955 MockRead("\n"),
956 MockRead("Q"),
957 MockRead("J"),
958 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06959 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27960 };
Ryan Sleevib8d7ea02018-05-07 20:01:01961 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01962 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27963 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
964 EXPECT_EQ("DATA", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01965 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22966 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27967}
968
969// Close the connection before enough bytes to have a status line.
bncd16676a2016-07-20 16:23:01970TEST_F(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:27971 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35972 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:06973 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27974 };
Ryan Sleevib8d7ea02018-05-07 20:01:01975 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41976 EXPECT_THAT(out.rv, IsOk());
977 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
978 EXPECT_EQ("HTT", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01979 int64_t reads_size = CountReadBytes(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41980 EXPECT_EQ(reads_size, out.total_received_bytes);
initial.commit586acc5fe2008-07-26 22:42:52981}
982
[email protected]f9d44aa2008-09-23 23:57:17983// Simulate a 204 response, lacking a Content-Length header, sent over a
984// persistent connection. The response should still terminate since a 204
985// cannot have a response body.
bncd16676a2016-07-20 16:23:01986TEST_F(HttpNetworkTransactionTest, StopsReading204) {
[email protected]b8015c42013-12-24 15:18:19987 char junk[] = "junk";
[email protected]f9d44aa2008-09-23 23:57:17988 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35989 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
[email protected]b8015c42013-12-24 15:18:19990 MockRead(junk), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:06991 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:17992 };
Ryan Sleevib8d7ea02018-05-07 20:01:01993 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01994 EXPECT_THAT(out.rv, IsOk());
[email protected]f9d44aa2008-09-23 23:57:17995 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
996 EXPECT_EQ("", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01997 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22998 int64_t response_size = reads_size - strlen(junk);
999 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]f9d44aa2008-09-23 23:57:171000}
1001
[email protected]0877e3d2009-10-17 22:29:571002// A simple request using chunked encoding with some extra data after.
bncd16676a2016-07-20 16:23:011003TEST_F(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]b8015c42013-12-24 15:18:191004 std::string final_chunk = "0\r\n\r\n";
1005 std::string extra_data = "HTTP/1.1 200 OK\r\n";
1006 std::string last_read = final_chunk + extra_data;
[email protected]0877e3d2009-10-17 22:29:571007 MockRead data_reads[] = {
1008 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
1009 MockRead("5\r\nHello\r\n"),
1010 MockRead("1\r\n"),
1011 MockRead(" \r\n"),
1012 MockRead("5\r\nworld\r\n"),
[email protected]b8015c42013-12-24 15:18:191013 MockRead(last_read.data()),
[email protected]8ddf8322012-02-23 18:08:061014 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:571015 };
Ryan Sleevib8d7ea02018-05-07 20:01:011016 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011017 EXPECT_THAT(out.rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:571018 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1019 EXPECT_EQ("Hello world", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:011020 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:221021 int64_t response_size = reads_size - extra_data.size();
1022 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]0877e3d2009-10-17 22:29:571023}
1024
[email protected]9fe44f52010-09-23 18:36:001025// Next tests deal with http://crbug.com/56344.
1026
bncd16676a2016-07-20 16:23:011027TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001028 MultipleContentLengthHeadersNoTransferEncoding) {
1029 MockRead data_reads[] = {
1030 MockRead("HTTP/1.1 200 OK\r\n"),
1031 MockRead("Content-Length: 10\r\n"),
1032 MockRead("Content-Length: 5\r\n\r\n"),
1033 };
Ryan Sleevib8d7ea02018-05-07 20:01:011034 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011035 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]9fe44f52010-09-23 18:36:001036}
1037
bncd16676a2016-07-20 16:23:011038TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:041039 DuplicateContentLengthHeadersNoTransferEncoding) {
1040 MockRead data_reads[] = {
1041 MockRead("HTTP/1.1 200 OK\r\n"),
1042 MockRead("Content-Length: 5\r\n"),
1043 MockRead("Content-Length: 5\r\n\r\n"),
1044 MockRead("Hello"),
1045 };
Ryan Sleevib8d7ea02018-05-07 20:01:011046 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011047 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041048 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1049 EXPECT_EQ("Hello", out.response_data);
1050}
1051
bncd16676a2016-07-20 16:23:011052TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:041053 ComplexContentLengthHeadersNoTransferEncoding) {
1054 // More than 2 dupes.
1055 {
1056 MockRead data_reads[] = {
1057 MockRead("HTTP/1.1 200 OK\r\n"),
1058 MockRead("Content-Length: 5\r\n"),
1059 MockRead("Content-Length: 5\r\n"),
1060 MockRead("Content-Length: 5\r\n\r\n"),
1061 MockRead("Hello"),
1062 };
Ryan Sleevib8d7ea02018-05-07 20:01:011063 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011064 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041065 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1066 EXPECT_EQ("Hello", out.response_data);
1067 }
1068 // HTTP/1.0
1069 {
1070 MockRead data_reads[] = {
1071 MockRead("HTTP/1.0 200 OK\r\n"),
1072 MockRead("Content-Length: 5\r\n"),
1073 MockRead("Content-Length: 5\r\n"),
1074 MockRead("Content-Length: 5\r\n\r\n"),
1075 MockRead("Hello"),
1076 };
Ryan Sleevib8d7ea02018-05-07 20:01:011077 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011078 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041079 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
1080 EXPECT_EQ("Hello", out.response_data);
1081 }
1082 // 2 dupes and one mismatched.
1083 {
1084 MockRead data_reads[] = {
1085 MockRead("HTTP/1.1 200 OK\r\n"),
1086 MockRead("Content-Length: 10\r\n"),
1087 MockRead("Content-Length: 10\r\n"),
1088 MockRead("Content-Length: 5\r\n\r\n"),
1089 };
Ryan Sleevib8d7ea02018-05-07 20:01:011090 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011091 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]44b52042010-10-29 22:48:041092 }
1093}
1094
bncd16676a2016-07-20 16:23:011095TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001096 MultipleContentLengthHeadersTransferEncoding) {
1097 MockRead data_reads[] = {
1098 MockRead("HTTP/1.1 200 OK\r\n"),
1099 MockRead("Content-Length: 666\r\n"),
1100 MockRead("Content-Length: 1337\r\n"),
1101 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
1102 MockRead("5\r\nHello\r\n"),
1103 MockRead("1\r\n"),
1104 MockRead(" \r\n"),
1105 MockRead("5\r\nworld\r\n"),
1106 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:061107 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:001108 };
Ryan Sleevib8d7ea02018-05-07 20:01:011109 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011110 EXPECT_THAT(out.rv, IsOk());
[email protected]9fe44f52010-09-23 18:36:001111 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1112 EXPECT_EQ("Hello world", out.response_data);
1113}
1114
[email protected]1628fe92011-10-04 23:04:551115// Next tests deal with http://crbug.com/98895.
1116
1117// Checks that a single Content-Disposition header results in no error.
bncd16676a2016-07-20 16:23:011118TEST_F(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:551119 MockRead data_reads[] = {
1120 MockRead("HTTP/1.1 200 OK\r\n"),
1121 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
1122 MockRead("Content-Length: 5\r\n\r\n"),
1123 MockRead("Hello"),
1124 };
Ryan Sleevib8d7ea02018-05-07 20:01:011125 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011126 EXPECT_THAT(out.rv, IsOk());
[email protected]1628fe92011-10-04 23:04:551127 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1128 EXPECT_EQ("Hello", out.response_data);
1129}
1130
[email protected]54a9c6e52012-03-21 20:10:591131// Checks that two identical Content-Disposition headers result in no error.
bncd16676a2016-07-20 16:23:011132TEST_F(HttpNetworkTransactionTest, TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551133 MockRead data_reads[] = {
1134 MockRead("HTTP/1.1 200 OK\r\n"),
1135 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1136 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1137 MockRead("Content-Length: 5\r\n\r\n"),
1138 MockRead("Hello"),
1139 };
Ryan Sleevib8d7ea02018-05-07 20:01:011140 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011141 EXPECT_THAT(out.rv, IsOk());
[email protected]54a9c6e52012-03-21 20:10:591142 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1143 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:551144}
1145
1146// Checks that two distinct Content-Disposition headers result in an error.
bncd16676a2016-07-20 16:23:011147TEST_F(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551148 MockRead data_reads[] = {
1149 MockRead("HTTP/1.1 200 OK\r\n"),
1150 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1151 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
1152 MockRead("Content-Length: 5\r\n\r\n"),
1153 MockRead("Hello"),
1154 };
Ryan Sleevib8d7ea02018-05-07 20:01:011155 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011156 EXPECT_THAT(out.rv,
1157 IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION));
[email protected]1628fe92011-10-04 23:04:551158}
1159
[email protected]54a9c6e52012-03-21 20:10:591160// Checks that two identical Location headers result in no error.
1161// Also tests Location header behavior.
bncd16676a2016-07-20 16:23:011162TEST_F(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551163 MockRead data_reads[] = {
1164 MockRead("HTTP/1.1 302 Redirect\r\n"),
1165 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:591166 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:551167 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061168 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551169 };
1170
1171 HttpRequestInfo request;
1172 request.method = "GET";
1173 request.url = GURL("http://redirect.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101174 request.traffic_annotation =
1175 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1628fe92011-10-04 23:04:551176
danakj1fd259a02016-04-16 03:17:091177 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161178 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1628fe92011-10-04 23:04:551179
Ryan Sleevib8d7ea02018-05-07 20:01:011180 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071181 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:551182
[email protected]49639fa2011-12-20 23:22:411183 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:551184
tfarina42834112016-09-22 13:38:201185 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011186 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1628fe92011-10-04 23:04:551187
robpercival214763f2016-07-01 23:27:011188 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]1628fe92011-10-04 23:04:551189
bnc691fda62016-08-12 00:43:161190 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521191 ASSERT_TRUE(response);
1192 ASSERT_TRUE(response->headers);
[email protected]1628fe92011-10-04 23:04:551193 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
1194 std::string url;
1195 EXPECT_TRUE(response->headers->IsRedirect(&url));
1196 EXPECT_EQ("http://good.com/", url);
tbansal2ecbbc72016-10-06 17:15:471197 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]1628fe92011-10-04 23:04:551198}
1199
[email protected]1628fe92011-10-04 23:04:551200// Checks that two distinct Location headers result in an error.
bncd16676a2016-07-20 16:23:011201TEST_F(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551202 MockRead data_reads[] = {
1203 MockRead("HTTP/1.1 302 Redirect\r\n"),
1204 MockRead("Location: http://good.com/\r\n"),
1205 MockRead("Location: http://evil.com/\r\n"),
1206 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061207 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551208 };
Ryan Sleevib8d7ea02018-05-07 20:01:011209 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011210 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION));
[email protected]1628fe92011-10-04 23:04:551211}
1212
[email protected]ef0faf2e72009-03-05 23:27:231213// Do a request using the HEAD method. Verify that we don't try to read the
1214// message body (since HEAD has none).
bncd16676a2016-07-20 16:23:011215TEST_F(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:421216 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:231217 request.method = "HEAD";
bncce36dca22015-04-21 22:11:231218 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:101219 request.traffic_annotation =
1220 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ef0faf2e72009-03-05 23:27:231221
danakj1fd259a02016-04-16 03:17:091222 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161223 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:091224 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:161225 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:091226 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
1227 base::Unretained(&headers_handler)));
[email protected]cb9bf6ca2011-01-28 13:15:271228
[email protected]ef0faf2e72009-03-05 23:27:231229 MockWrite data_writes1[] = {
csharrisonf473dd192015-08-18 13:54:131230 MockWrite("HEAD / HTTP/1.1\r\n"
1231 "Host: www.example.org\r\n"
1232 "Connection: keep-alive\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231233 };
1234 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:231235 MockRead("HTTP/1.1 404 Not Found\r\n"), MockRead("Server: Blah\r\n"),
1236 MockRead("Content-Length: 1234\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231237
mmenked39192ee2015-12-09 00:57:231238 // No response body because the test stops reading here.
1239 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]ef0faf2e72009-03-05 23:27:231240 };
1241
Ryan Sleevib8d7ea02018-05-07 20:01:011242 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:071243 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:231244
[email protected]49639fa2011-12-20 23:22:411245 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:231246
tfarina42834112016-09-22 13:38:201247 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011248 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ef0faf2e72009-03-05 23:27:231249
1250 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:011251 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231252
bnc691fda62016-08-12 00:43:161253 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521254 ASSERT_TRUE(response);
[email protected]ef0faf2e72009-03-05 23:27:231255
1256 // Check that the headers got parsed.
wezca1070932016-05-26 20:30:521257 EXPECT_TRUE(response->headers);
[email protected]ef0faf2e72009-03-05 23:27:231258 EXPECT_EQ(1234, response->headers->GetContentLength());
1259 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471260 EXPECT_TRUE(response->proxy_server.is_direct());
ryansturm49a8cb12016-06-15 16:51:091261 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
1262 EXPECT_FALSE(headers_handler.observed_before_headers_sent_with_proxy());
[email protected]ef0faf2e72009-03-05 23:27:231263
1264 std::string server_header;
olli.raulaee489a52016-01-25 08:37:101265 size_t iter = 0;
[email protected]ef0faf2e72009-03-05 23:27:231266 bool has_server_header = response->headers->EnumerateHeader(
1267 &iter, "Server", &server_header);
1268 EXPECT_TRUE(has_server_header);
1269 EXPECT_EQ("Blah", server_header);
1270
1271 // Reading should give EOF right away, since there is no message body
1272 // (despite non-zero content-length).
1273 std::string response_data;
bnc691fda62016-08-12 00:43:161274 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011275 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231276 EXPECT_EQ("", response_data);
1277}
1278
bncd16676a2016-07-20 16:23:011279TEST_F(HttpNetworkTransactionTest, ReuseConnection) {
danakj1fd259a02016-04-16 03:17:091280 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:521281
1282 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351283 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1284 MockRead("hello"),
1285 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1286 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061287 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521288 };
Ryan Sleevib8d7ea02018-05-07 20:01:011289 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071290 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521291
[email protected]0b0bf032010-09-21 18:08:501292 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521293 "hello", "world"
1294 };
1295
1296 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:421297 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521298 request.method = "GET";
bncce36dca22015-04-21 22:11:231299 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:101300 request.traffic_annotation =
1301 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:521302
bnc691fda62016-08-12 00:43:161303 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271304
[email protected]49639fa2011-12-20 23:22:411305 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521306
tfarina42834112016-09-22 13:38:201307 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011308 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521309
1310 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011311 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521312
bnc691fda62016-08-12 00:43:161313 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521314 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521315
wezca1070932016-05-26 20:30:521316 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251317 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471318 EXPECT_TRUE(response->proxy_server.is_direct());
initial.commit586acc5fe2008-07-26 22:42:521319
1320 std::string response_data;
bnc691fda62016-08-12 00:43:161321 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011322 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251323 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521324 }
1325}
1326
bncd16676a2016-07-20 16:23:011327TEST_F(HttpNetworkTransactionTest, Ignores100) {
danakj1fd259a02016-04-16 03:17:091328 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:221329 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:191330 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:221331 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:271332
[email protected]1c773ea12009-04-28 19:58:421333 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521334 request.method = "POST";
1335 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271336 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:101337 request.traffic_annotation =
1338 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:521339
shivanishab9a143952016-09-19 17:23:411340 // Check the upload progress returned before initialization is correct.
1341 UploadProgress progress = request.upload_data_stream->GetUploadProgress();
1342 EXPECT_EQ(0u, progress.size());
1343 EXPECT_EQ(0u, progress.position());
1344
danakj1fd259a02016-04-16 03:17:091345 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161346 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271347
initial.commit586acc5fe2008-07-26 22:42:521348 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351349 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1350 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1351 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061352 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521353 };
Ryan Sleevib8d7ea02018-05-07 20:01:011354 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071355 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521356
[email protected]49639fa2011-12-20 23:22:411357 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521358
tfarina42834112016-09-22 13:38:201359 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011360 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521361
1362 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011363 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521364
bnc691fda62016-08-12 00:43:161365 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521366 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521367
wezca1070932016-05-26 20:30:521368 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251369 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521370
1371 std::string response_data;
bnc691fda62016-08-12 00:43:161372 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011373 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251374 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521375}
1376
[email protected]3a2d3662009-03-27 03:49:141377// This test is almost the same as Ignores100 above, but the response contains
1378// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571379// HTTP/1.1 and the two status headers are read in one read.
bncd16676a2016-07-20 16:23:011380TEST_F(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421381 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141382 request.method = "GET";
1383 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101384 request.traffic_annotation =
1385 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3a2d3662009-03-27 03:49:141386
danakj1fd259a02016-04-16 03:17:091387 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161388 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271389
[email protected]3a2d3662009-03-27 03:49:141390 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571391 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1392 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141393 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061394 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141395 };
Ryan Sleevib8d7ea02018-05-07 20:01:011396 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071397 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141398
[email protected]49639fa2011-12-20 23:22:411399 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141400
tfarina42834112016-09-22 13:38:201401 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011402 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3a2d3662009-03-27 03:49:141403
1404 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011405 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141406
bnc691fda62016-08-12 00:43:161407 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521408 ASSERT_TRUE(response);
[email protected]3a2d3662009-03-27 03:49:141409
wezca1070932016-05-26 20:30:521410 EXPECT_TRUE(response->headers);
[email protected]3a2d3662009-03-27 03:49:141411 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1412
1413 std::string response_data;
bnc691fda62016-08-12 00:43:161414 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011415 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141416 EXPECT_EQ("hello world", response_data);
1417}
1418
Andrew Comminos517a92c2019-01-14 17:49:561419TEST_F(HttpNetworkTransactionTest, LoadTimingMeasuresTimeToFirstByteForHttp) {
1420 static const base::TimeDelta kDelayAfterFirstByte =
Andrew Comminos1f2ff1cc2018-12-14 05:22:381421 base::TimeDelta::FromMilliseconds(10);
1422
1423 HttpRequestInfo request;
1424 request.method = "GET";
1425 request.url = GURL("http://www.foo.com/");
1426 request.traffic_annotation =
1427 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1428
1429 std::vector<MockWrite> data_writes = {
1430 MockWrite(ASYNC, 0,
1431 "GET / HTTP/1.1\r\n"
1432 "Host: www.foo.com\r\n"
1433 "Connection: keep-alive\r\n\r\n"),
1434 };
1435
1436 std::vector<MockRead> data_reads = {
1437 // Write one byte of the status line, followed by a pause.
1438 MockRead(ASYNC, 1, "H"),
1439 MockRead(ASYNC, ERR_IO_PENDING, 2),
1440 MockRead(ASYNC, 3, "TTP/1.1 200 OK\r\n\r\n"),
1441 MockRead(ASYNC, 4, "hello world"),
1442 MockRead(SYNCHRONOUS, OK, 5),
1443 };
1444
1445 SequencedSocketData data(data_reads, data_writes);
1446 session_deps_.socket_factory->AddSocketDataProvider(&data);
1447
1448 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1449
1450 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1451
1452 TestCompletionCallback callback;
1453
1454 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1455 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1456
1457 data.RunUntilPaused();
1458 ASSERT_TRUE(data.IsPaused());
Andrew Comminos517a92c2019-01-14 17:49:561459 FastForwardBy(kDelayAfterFirstByte);
Andrew Comminos1f2ff1cc2018-12-14 05:22:381460 data.Resume();
1461
1462 rv = callback.WaitForResult();
1463 EXPECT_THAT(rv, IsOk());
1464
1465 const HttpResponseInfo* response = trans.GetResponseInfo();
1466 ASSERT_TRUE(response);
1467
1468 EXPECT_TRUE(response->headers);
1469 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1470
1471 LoadTimingInfo load_timing_info;
1472 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
1473 EXPECT_FALSE(load_timing_info.receive_headers_start.is_null());
1474 EXPECT_FALSE(load_timing_info.connect_timing.connect_end.is_null());
Andrew Comminos517a92c2019-01-14 17:49:561475 // Ensure we didn't include the delay in the TTFB time.
1476 EXPECT_EQ(load_timing_info.receive_headers_start,
1477 load_timing_info.connect_timing.connect_end);
1478 // Ensure that the mock clock advanced at all.
1479 EXPECT_EQ(base::TimeTicks::Now() - load_timing_info.receive_headers_start,
1480 kDelayAfterFirstByte);
Andrew Comminos1f2ff1cc2018-12-14 05:22:381481
1482 std::string response_data;
1483 rv = ReadTransaction(&trans, &response_data);
1484 EXPECT_THAT(rv, IsOk());
1485 EXPECT_EQ("hello world", response_data);
1486}
1487
1488// Tests that the time-to-first-byte reported in a transaction's load timing
1489// info uses the first response, even if 1XX/informational.
1490void HttpNetworkTransactionTest::Check100ResponseTiming(bool use_spdy) {
Andrew Comminos517a92c2019-01-14 17:49:561491 static const base::TimeDelta kDelayAfter100Response =
Andrew Comminos1f2ff1cc2018-12-14 05:22:381492 base::TimeDelta::FromMilliseconds(10);
1493
1494 HttpRequestInfo request;
1495 request.method = "GET";
1496 request.url = GURL("https://www.foo.com/");
1497 request.traffic_annotation =
1498 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1499
1500 SSLSocketDataProvider ssl(ASYNC, OK);
1501 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
1502
1503 std::vector<MockWrite> data_writes;
1504 std::vector<MockRead> data_reads;
1505
1506 spdy::SpdySerializedFrame spdy_req(
1507 spdy_util_.ConstructSpdyGet(request.url.spec().c_str(), 1, LOWEST));
1508
1509 spdy::SpdyHeaderBlock spdy_resp1_headers;
1510 spdy_resp1_headers[spdy::kHttp2StatusHeader] = "100";
1511 spdy::SpdySerializedFrame spdy_resp1(
1512 spdy_util_.ConstructSpdyReply(1, spdy_resp1_headers.Clone()));
1513 spdy::SpdySerializedFrame spdy_resp2(
1514 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
1515 spdy::SpdySerializedFrame spdy_data(
1516 spdy_util_.ConstructSpdyDataFrame(1, "hello world", true));
1517
1518 if (use_spdy) {
1519 ssl.next_proto = kProtoHTTP2;
1520
1521 data_writes = {CreateMockWrite(spdy_req, 0)};
1522
1523 data_reads = {
1524 CreateMockRead(spdy_resp1, 1), MockRead(ASYNC, ERR_IO_PENDING, 2),
1525 CreateMockRead(spdy_resp2, 3), CreateMockRead(spdy_data, 4),
1526 MockRead(SYNCHRONOUS, OK, 5),
1527 };
1528 } else {
1529 data_writes = {
1530 MockWrite(ASYNC, 0,
1531 "GET / HTTP/1.1\r\n"
1532 "Host: www.foo.com\r\n"
1533 "Connection: keep-alive\r\n\r\n"),
1534 };
1535
1536 data_reads = {
1537 MockRead(ASYNC, 1, "HTTP/1.1 100 Continue\r\n\r\n"),
1538 MockRead(ASYNC, ERR_IO_PENDING, 2),
1539
1540 MockRead(ASYNC, 3, "HTTP/1.1 200 OK\r\n\r\n"),
1541 MockRead(ASYNC, 4, "hello world"),
1542 MockRead(SYNCHRONOUS, OK, 5),
1543 };
1544 }
1545
1546 SequencedSocketData data(data_reads, data_writes);
1547 session_deps_.socket_factory->AddSocketDataProvider(&data);
1548
1549 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1550
1551 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1552
1553 TestCompletionCallback callback;
1554
1555 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1556 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1557
1558 data.RunUntilPaused();
1559 // We should now have parsed the 100 response and hit ERR_IO_PENDING. Insert
1560 // the delay before parsing the 200 response.
1561 ASSERT_TRUE(data.IsPaused());
Andrew Comminos517a92c2019-01-14 17:49:561562 FastForwardBy(kDelayAfter100Response);
Andrew Comminos1f2ff1cc2018-12-14 05:22:381563 data.Resume();
1564
1565 rv = callback.WaitForResult();
1566 EXPECT_THAT(rv, IsOk());
1567
1568 const HttpResponseInfo* response = trans.GetResponseInfo();
1569 ASSERT_TRUE(response);
1570
1571 LoadTimingInfo load_timing_info;
1572 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
1573 EXPECT_FALSE(load_timing_info.receive_headers_start.is_null());
1574 EXPECT_FALSE(load_timing_info.connect_timing.connect_end.is_null());
Andrew Comminos517a92c2019-01-14 17:49:561575 // Ensure we didn't include the delay in the TTFB time.
1576 EXPECT_EQ(load_timing_info.receive_headers_start,
1577 load_timing_info.connect_timing.connect_end);
1578 // Ensure that the mock clock advanced at all.
1579 EXPECT_EQ(base::TimeTicks::Now() - load_timing_info.receive_headers_start,
1580 kDelayAfter100Response);
Andrew Comminos1f2ff1cc2018-12-14 05:22:381581
1582 std::string response_data;
1583 rv = ReadTransaction(&trans, &response_data);
1584 EXPECT_THAT(rv, IsOk());
1585 EXPECT_EQ("hello world", response_data);
1586}
1587
Andrew Comminos517a92c2019-01-14 17:49:561588TEST_F(HttpNetworkTransactionTest, MeasuresTimeToFirst100ResponseForHttp) {
Andrew Comminos1f2ff1cc2018-12-14 05:22:381589 Check100ResponseTiming(false /* use_spdy */);
1590}
1591
Andrew Comminos517a92c2019-01-14 17:49:561592TEST_F(HttpNetworkTransactionTest, MeasuresTimeToFirst100ResponseForSpdy) {
Andrew Comminos1f2ff1cc2018-12-14 05:22:381593 Check100ResponseTiming(true /* use_spdy */);
1594}
1595
bncd16676a2016-07-20 16:23:011596TEST_F(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
zmo9528c9f42015-08-04 22:12:081597 HttpRequestInfo request;
1598 request.method = "POST";
1599 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101600 request.traffic_annotation =
1601 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
zmo9528c9f42015-08-04 22:12:081602
danakj1fd259a02016-04-16 03:17:091603 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161604 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zmo9528c9f42015-08-04 22:12:081605
1606 MockRead data_reads[] = {
1607 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1608 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381609 };
Ryan Sleevib8d7ea02018-05-07 20:01:011610 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
zmo9528c9f42015-08-04 22:12:081611 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381612
zmo9528c9f42015-08-04 22:12:081613 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381614
tfarina42834112016-09-22 13:38:201615 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011616 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381617
zmo9528c9f42015-08-04 22:12:081618 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011619 EXPECT_THAT(rv, IsOk());
[email protected]ee9410e72010-01-07 01:42:381620
zmo9528c9f42015-08-04 22:12:081621 std::string response_data;
bnc691fda62016-08-12 00:43:161622 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011623 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:081624 EXPECT_EQ("", response_data);
[email protected]ee9410e72010-01-07 01:42:381625}
1626
bncd16676a2016-07-20 16:23:011627TEST_F(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381628 HttpRequestInfo request;
1629 request.method = "POST";
1630 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101631 request.traffic_annotation =
1632 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ee9410e72010-01-07 01:42:381633
danakj1fd259a02016-04-16 03:17:091634 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161635 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271636
[email protected]ee9410e72010-01-07 01:42:381637 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061638 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381639 };
Ryan Sleevib8d7ea02018-05-07 20:01:011640 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071641 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381642
[email protected]49639fa2011-12-20 23:22:411643 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381644
tfarina42834112016-09-22 13:38:201645 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011646 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381647
1648 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011649 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]ee9410e72010-01-07 01:42:381650}
1651
[email protected]23e482282013-06-14 16:08:021652void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511653 const MockWrite* write_failure,
1654 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421655 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521656 request.method = "GET";
1657 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101658 request.traffic_annotation =
1659 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:521660
vishal.b62985ca92015-04-17 08:45:511661 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071662 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091663 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271664
[email protected]202965992011-12-07 23:04:511665 // Written data for successfully sending both requests.
1666 MockWrite data1_writes[] = {
1667 MockWrite("GET / HTTP/1.1\r\n"
1668 "Host: www.foo.com\r\n"
1669 "Connection: keep-alive\r\n\r\n"),
1670 MockWrite("GET / HTTP/1.1\r\n"
1671 "Host: www.foo.com\r\n"
1672 "Connection: keep-alive\r\n\r\n")
1673 };
1674
1675 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521676 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351677 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1678 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061679 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521680 };
[email protected]202965992011-12-07 23:04:511681
1682 if (write_failure) {
[email protected]a34f61ee2014-03-18 20:59:491683 ASSERT_FALSE(read_failure);
[email protected]202965992011-12-07 23:04:511684 data1_writes[1] = *write_failure;
1685 } else {
1686 ASSERT_TRUE(read_failure);
1687 data1_reads[2] = *read_failure;
1688 }
1689
Ryan Sleevib8d7ea02018-05-07 20:01:011690 StaticSocketDataProvider data1(data1_reads, data1_writes);
[email protected]bb88e1d32013-05-03 23:11:071691 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521692
1693 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351694 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1695 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061696 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521697 };
Ryan Sleevib8d7ea02018-05-07 20:01:011698 StaticSocketDataProvider data2(data2_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071699 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521700
thestig9d3bb0c2015-01-24 00:49:511701 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521702 "hello", "world"
1703 };
1704
mikecironef22f9812016-10-04 03:40:191705 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521706 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411707 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521708
bnc691fda62016-08-12 00:43:161709 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
initial.commit586acc5fe2008-07-26 22:42:521710
tfarina42834112016-09-22 13:38:201711 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011712 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521713
1714 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011715 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521716
[email protected]58e32bb2013-01-21 18:23:251717 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161718 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:251719 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1720 if (i == 0) {
1721 first_socket_log_id = load_timing_info.socket_log_id;
1722 } else {
1723 // The second request should be using a new socket.
1724 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1725 }
1726
bnc691fda62016-08-12 00:43:161727 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521728 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521729
wezca1070932016-05-26 20:30:521730 EXPECT_TRUE(response->headers);
tbansal2ecbbc72016-10-06 17:15:471731 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]3d2a59b2008-09-26 19:44:251732 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521733
1734 std::string response_data;
bnc691fda62016-08-12 00:43:161735 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011736 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251737 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521738 }
1739}
[email protected]3d2a59b2008-09-26 19:44:251740
[email protected]a34f61ee2014-03-18 20:59:491741void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1742 const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:101743 const MockRead* read_failure,
1744 bool use_spdy) {
[email protected]a34f61ee2014-03-18 20:59:491745 HttpRequestInfo request;
1746 request.method = "GET";
[email protected]09356c652014-03-25 15:36:101747 request.url = GURL("https://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101748 request.traffic_annotation =
1749 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]a34f61ee2014-03-18 20:59:491750
vishal.b62985ca92015-04-17 08:45:511751 TestNetLog net_log;
[email protected]a34f61ee2014-03-18 20:59:491752 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091753 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a34f61ee2014-03-18 20:59:491754
[email protected]09356c652014-03-25 15:36:101755 SSLSocketDataProvider ssl1(ASYNC, OK);
1756 SSLSocketDataProvider ssl2(ASYNC, OK);
1757 if (use_spdy) {
bnc3cf2a592016-08-11 14:48:361758 ssl1.next_proto = kProtoHTTP2;
1759 ssl2.next_proto = kProtoHTTP2;
[email protected]09356c652014-03-25 15:36:101760 }
1761 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1762 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]a34f61ee2014-03-18 20:59:491763
[email protected]09356c652014-03-25 15:36:101764 // SPDY versions of the request and response.
Ryan Hamilton0239aac2018-05-19 00:03:131765 spdy::SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
bnc38dcd392016-02-09 23:19:491766 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
Ryan Hamilton0239aac2018-05-19 00:03:131767 spdy::SpdySerializedFrame spdy_response(
Raul Tambre94493c652019-03-11 17:18:351768 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:131769 spdy::SpdySerializedFrame spdy_data(
Bence Békyd74f4382018-02-20 18:26:191770 spdy_util_.ConstructSpdyDataFrame(1, "hello", true));
[email protected]a34f61ee2014-03-18 20:59:491771
[email protected]09356c652014-03-25 15:36:101772 // HTTP/1.1 versions of the request and response.
1773 const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1774 "Host: www.foo.com\r\n"
1775 "Connection: keep-alive\r\n\r\n";
1776 const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1777 const char kHttpData[] = "hello";
1778
1779 std::vector<MockRead> data1_reads;
1780 std::vector<MockWrite> data1_writes;
[email protected]a34f61ee2014-03-18 20:59:491781 if (write_failure) {
1782 ASSERT_FALSE(read_failure);
[email protected]09356c652014-03-25 15:36:101783 data1_writes.push_back(*write_failure);
1784 data1_reads.push_back(MockRead(ASYNC, OK));
[email protected]a34f61ee2014-03-18 20:59:491785 } else {
1786 ASSERT_TRUE(read_failure);
[email protected]09356c652014-03-25 15:36:101787 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411788 data1_writes.push_back(CreateMockWrite(spdy_request));
[email protected]09356c652014-03-25 15:36:101789 } else {
1790 data1_writes.push_back(MockWrite(kHttpRequest));
1791 }
1792 data1_reads.push_back(*read_failure);
[email protected]a34f61ee2014-03-18 20:59:491793 }
1794
Ryan Sleevib8d7ea02018-05-07 20:01:011795 StaticSocketDataProvider data1(data1_reads, data1_writes);
[email protected]a34f61ee2014-03-18 20:59:491796 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1797
[email protected]09356c652014-03-25 15:36:101798 std::vector<MockRead> data2_reads;
1799 std::vector<MockWrite> data2_writes;
1800
1801 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411802 data2_writes.push_back(CreateMockWrite(spdy_request, 0, ASYNC));
[email protected]09356c652014-03-25 15:36:101803
bncdf80d44fd2016-07-15 20:27:411804 data2_reads.push_back(CreateMockRead(spdy_response, 1, ASYNC));
1805 data2_reads.push_back(CreateMockRead(spdy_data, 2, ASYNC));
[email protected]09356c652014-03-25 15:36:101806 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1807 } else {
1808 data2_writes.push_back(
1809 MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1810
1811 data2_reads.push_back(
1812 MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1813 data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1814 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1815 }
Ryan Sleevib8d7ea02018-05-07 20:01:011816 SequencedSocketData data2(data2_reads, data2_writes);
[email protected]a34f61ee2014-03-18 20:59:491817 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1818
1819 // Preconnect a socket.
nharper8cdb0fb2016-04-22 21:34:591820 session->http_stream_factory()->PreconnectStreams(1, request);
[email protected]a34f61ee2014-03-18 20:59:491821 // Wait for the preconnect to complete.
1822 // TODO(davidben): Some way to wait for an idle socket count might be handy.
1823 base::RunLoop().RunUntilIdle();
Matt Menke9d5e2c92019-02-05 01:42:231824 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]a34f61ee2014-03-18 20:59:491825
1826 // Make the request.
1827 TestCompletionCallback callback;
1828
bnc691fda62016-08-12 00:43:161829 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a34f61ee2014-03-18 20:59:491830
tfarina42834112016-09-22 13:38:201831 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011832 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a34f61ee2014-03-18 20:59:491833
1834 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011835 EXPECT_THAT(rv, IsOk());
[email protected]a34f61ee2014-03-18 20:59:491836
1837 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161838 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]09356c652014-03-25 15:36:101839 TestLoadTimingNotReused(
1840 load_timing_info,
1841 CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]a34f61ee2014-03-18 20:59:491842
bnc691fda62016-08-12 00:43:161843 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521844 ASSERT_TRUE(response);
[email protected]a34f61ee2014-03-18 20:59:491845
wezca1070932016-05-26 20:30:521846 EXPECT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:021847 if (response->was_fetched_via_spdy) {
1848 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
1849 } else {
1850 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1851 }
[email protected]a34f61ee2014-03-18 20:59:491852
1853 std::string response_data;
bnc691fda62016-08-12 00:43:161854 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011855 EXPECT_THAT(rv, IsOk());
[email protected]09356c652014-03-25 15:36:101856 EXPECT_EQ(kHttpData, response_data);
[email protected]a34f61ee2014-03-18 20:59:491857}
1858
Biljith Jayan45a41722017-08-16 18:43:141859// Test that we do not retry indefinitely when a server sends an error like
1860// ERR_SPDY_PING_FAILED, ERR_SPDY_SERVER_REFUSED_STREAM,
1861// ERR_QUIC_HANDSHAKE_FAILED or ERR_QUIC_PROTOCOL_ERROR.
1862TEST_F(HttpNetworkTransactionTest, FiniteRetriesOnIOError) {
1863 HttpRequestInfo request;
1864 request.method = "GET";
1865 request.url = GURL("https://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101866 request.traffic_annotation =
1867 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Biljith Jayan45a41722017-08-16 18:43:141868
1869 // Check whether we give up after the third try.
1870
1871 // Construct an HTTP2 request and a "Go away" response.
Ryan Hamilton0239aac2018-05-19 00:03:131872 spdy::SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
Biljith Jayan45a41722017-08-16 18:43:141873 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
Ryan Hamilton0239aac2018-05-19 00:03:131874 spdy::SpdySerializedFrame spdy_response_go_away(
1875 spdy_util_.ConstructSpdyGoAway(0));
Ryan Sleevib8d7ea02018-05-07 20:01:011876 MockRead data_read1[] = {CreateMockRead(spdy_response_go_away)};
1877 MockWrite data_write[] = {CreateMockWrite(spdy_request, 0)};
Biljith Jayan45a41722017-08-16 18:43:141878
1879 // Three go away responses.
Ryan Sleevib8d7ea02018-05-07 20:01:011880 StaticSocketDataProvider data1(data_read1, data_write);
1881 StaticSocketDataProvider data2(data_read1, data_write);
1882 StaticSocketDataProvider data3(data_read1, data_write);
Biljith Jayan45a41722017-08-16 18:43:141883
1884 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1885 AddSSLSocketData();
1886 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1887 AddSSLSocketData();
1888 session_deps_.socket_factory->AddSocketDataProvider(&data3);
1889 AddSSLSocketData();
1890
1891 TestCompletionCallback callback;
1892 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1893 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1894
1895 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1896 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1897
1898 rv = callback.WaitForResult();
1899 EXPECT_THAT(rv, IsError(ERR_SPDY_SERVER_REFUSED_STREAM));
1900}
1901
1902TEST_F(HttpNetworkTransactionTest, RetryTwiceOnIOError) {
1903 HttpRequestInfo request;
1904 request.method = "GET";
1905 request.url = GURL("https://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101906 request.traffic_annotation =
1907 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Biljith Jayan45a41722017-08-16 18:43:141908
1909 // Check whether we try atleast thrice before giving up.
1910
1911 // Construct an HTTP2 request and a "Go away" response.
Ryan Hamilton0239aac2018-05-19 00:03:131912 spdy::SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
Biljith Jayan45a41722017-08-16 18:43:141913 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
Ryan Hamilton0239aac2018-05-19 00:03:131914 spdy::SpdySerializedFrame spdy_response_go_away(
1915 spdy_util_.ConstructSpdyGoAway(0));
Ryan Sleevib8d7ea02018-05-07 20:01:011916 MockRead data_read1[] = {CreateMockRead(spdy_response_go_away)};
1917 MockWrite data_write[] = {CreateMockWrite(spdy_request, 0)};
Biljith Jayan45a41722017-08-16 18:43:141918
1919 // Construct a non error HTTP2 response.
Ryan Hamilton0239aac2018-05-19 00:03:131920 spdy::SpdySerializedFrame spdy_response_no_error(
Biljith Jayan45a41722017-08-16 18:43:141921 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:131922 spdy::SpdySerializedFrame spdy_data(
1923 spdy_util_.ConstructSpdyDataFrame(1, true));
Biljith Jayan45a41722017-08-16 18:43:141924 MockRead data_read2[] = {CreateMockRead(spdy_response_no_error, 1),
1925 CreateMockRead(spdy_data, 2)};
1926
1927 // Two error responses.
Ryan Sleevib8d7ea02018-05-07 20:01:011928 StaticSocketDataProvider data1(data_read1, data_write);
1929 StaticSocketDataProvider data2(data_read1, data_write);
Biljith Jayan45a41722017-08-16 18:43:141930 // Followed by a success response.
Ryan Sleevib8d7ea02018-05-07 20:01:011931 SequencedSocketData data3(data_read2, data_write);
Biljith Jayan45a41722017-08-16 18:43:141932
1933 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1934 AddSSLSocketData();
1935 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1936 AddSSLSocketData();
1937 session_deps_.socket_factory->AddSocketDataProvider(&data3);
1938 AddSSLSocketData();
1939
1940 TestCompletionCallback callback;
1941 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1942 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1943
1944 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1945 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1946
1947 rv = callback.WaitForResult();
1948 EXPECT_THAT(rv, IsOk());
1949}
1950
bncd16676a2016-07-20 16:23:011951TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061952 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
Raul Tambre94493c652019-03-11 17:18:351953 KeepAliveConnectionResendRequestTest(&write_failure, nullptr);
[email protected]202965992011-12-07 23:04:511954}
1955
bncd16676a2016-07-20 16:23:011956TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061957 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
Raul Tambre94493c652019-03-11 17:18:351958 KeepAliveConnectionResendRequestTest(nullptr, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251959}
1960
bncd16676a2016-07-20 16:23:011961TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061962 MockRead read_failure(SYNCHRONOUS, OK); // EOF
Raul Tambre94493c652019-03-11 17:18:351963 KeepAliveConnectionResendRequestTest(nullptr, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251964}
1965
[email protected]d58ceea82014-06-04 10:55:541966// Make sure that on a 408 response (Request Timeout), the request is retried,
1967// if the socket was a reused keep alive socket.
bncd16676a2016-07-20 16:23:011968TEST_F(HttpNetworkTransactionTest, KeepAlive408) {
[email protected]d58ceea82014-06-04 10:55:541969 MockRead read_failure(SYNCHRONOUS,
1970 "HTTP/1.1 408 Request Timeout\r\n"
1971 "Connection: Keep-Alive\r\n"
1972 "Content-Length: 6\r\n\r\n"
1973 "Pickle");
Raul Tambre94493c652019-03-11 17:18:351974 KeepAliveConnectionResendRequestTest(nullptr, &read_failure);
[email protected]d58ceea82014-06-04 10:55:541975}
1976
bncd16676a2016-07-20 16:23:011977TEST_F(HttpNetworkTransactionTest, PreconnectErrorNotConnectedOnWrite) {
[email protected]a34f61ee2014-03-18 20:59:491978 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
Raul Tambre94493c652019-03-11 17:18:351979 PreconnectErrorResendRequestTest(&write_failure, nullptr, false);
[email protected]a34f61ee2014-03-18 20:59:491980}
1981
bncd16676a2016-07-20 16:23:011982TEST_F(HttpNetworkTransactionTest, PreconnectErrorReset) {
[email protected]a34f61ee2014-03-18 20:59:491983 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
Raul Tambre94493c652019-03-11 17:18:351984 PreconnectErrorResendRequestTest(nullptr, &read_failure, false);
[email protected]a34f61ee2014-03-18 20:59:491985}
1986
bncd16676a2016-07-20 16:23:011987TEST_F(HttpNetworkTransactionTest, PreconnectErrorEOF) {
[email protected]a34f61ee2014-03-18 20:59:491988 MockRead read_failure(SYNCHRONOUS, OK); // EOF
Raul Tambre94493c652019-03-11 17:18:351989 PreconnectErrorResendRequestTest(nullptr, &read_failure, false);
[email protected]09356c652014-03-25 15:36:101990}
1991
bncd16676a2016-07-20 16:23:011992TEST_F(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:101993 MockRead read_failure(ASYNC, OK); // EOF
Raul Tambre94493c652019-03-11 17:18:351994 PreconnectErrorResendRequestTest(nullptr, &read_failure, false);
[email protected]09356c652014-03-25 15:36:101995}
1996
[email protected]d58ceea82014-06-04 10:55:541997// Make sure that on a 408 response (Request Timeout), the request is retried,
1998// if the socket was a preconnected (UNUSED_IDLE) socket.
bncd16676a2016-07-20 16:23:011999TEST_F(HttpNetworkTransactionTest, RetryOnIdle408) {
[email protected]d58ceea82014-06-04 10:55:542000 MockRead read_failure(SYNCHRONOUS,
2001 "HTTP/1.1 408 Request Timeout\r\n"
2002 "Connection: Keep-Alive\r\n"
2003 "Content-Length: 6\r\n\r\n"
2004 "Pickle");
Raul Tambre94493c652019-03-11 17:18:352005 KeepAliveConnectionResendRequestTest(nullptr, &read_failure);
2006 PreconnectErrorResendRequestTest(nullptr, &read_failure, false);
[email protected]d58ceea82014-06-04 10:55:542007}
2008
bncd16676a2016-07-20 16:23:012009TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorNotConnectedOnWrite) {
[email protected]09356c652014-03-25 15:36:102010 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
Raul Tambre94493c652019-03-11 17:18:352011 PreconnectErrorResendRequestTest(&write_failure, nullptr, true);
[email protected]09356c652014-03-25 15:36:102012}
2013
bncd16676a2016-07-20 16:23:012014TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
[email protected]09356c652014-03-25 15:36:102015 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
Raul Tambre94493c652019-03-11 17:18:352016 PreconnectErrorResendRequestTest(nullptr, &read_failure, true);
[email protected]09356c652014-03-25 15:36:102017}
2018
bncd16676a2016-07-20 16:23:012019TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
[email protected]09356c652014-03-25 15:36:102020 MockRead read_failure(SYNCHRONOUS, OK); // EOF
Raul Tambre94493c652019-03-11 17:18:352021 PreconnectErrorResendRequestTest(nullptr, &read_failure, true);
[email protected]09356c652014-03-25 15:36:102022}
2023
bncd16676a2016-07-20 16:23:012024TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:102025 MockRead read_failure(ASYNC, OK); // EOF
Raul Tambre94493c652019-03-11 17:18:352026 PreconnectErrorResendRequestTest(nullptr, &read_failure, true);
[email protected]a34f61ee2014-03-18 20:59:492027}
2028
bncd16676a2016-07-20 16:23:012029TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:422030 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:252031 request.method = "GET";
bncce36dca22015-04-21 22:11:232032 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102033 request.traffic_annotation =
2034 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3d2a59b2008-09-26 19:44:252035
danakj1fd259a02016-04-16 03:17:092036 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162037 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272038
[email protected]3d2a59b2008-09-26 19:44:252039 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:062040 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:352041 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
2042 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:062043 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:252044 };
Ryan Sleevib8d7ea02018-05-07 20:01:012045 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:072046 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:252047
[email protected]49639fa2011-12-20 23:22:412048 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:252049
tfarina42834112016-09-22 13:38:202050 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012051 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3d2a59b2008-09-26 19:44:252052
2053 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:012054 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:592055
2056 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:162057 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592058 EXPECT_LT(0u, endpoint.address().size());
[email protected]3d2a59b2008-09-26 19:44:252059}
2060
2061// What do various browsers do when the server closes a non-keepalive
2062// connection without sending any response header or body?
2063//
2064// IE7: error page
2065// Safari 3.1.2 (Windows): error page
2066// Firefox 3.0.1: blank page
2067// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:422068// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
2069// Us: error page (EMPTY_RESPONSE)
bncd16676a2016-07-20 16:23:012070TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:252071 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:062072 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:352073 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
2074 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:062075 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:252076 };
Ryan Sleevib8d7ea02018-05-07 20:01:012077 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:012078 EXPECT_THAT(out.rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]3d2a59b2008-09-26 19:44:252079}
[email protected]1826a402014-01-08 15:40:482080
[email protected]7a5378b2012-11-04 03:25:172081// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
2082// tests. There was a bug causing HttpNetworkTransaction to hang in the
2083// destructor in such situations.
2084// See http://crbug.com/154712 and http://crbug.com/156609.
bncd16676a2016-07-20 16:23:012085TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:172086 HttpRequestInfo request;
2087 request.method = "GET";
bncce36dca22015-04-21 22:11:232088 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102089 request.traffic_annotation =
2090 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7a5378b2012-11-04 03:25:172091
danakj1fd259a02016-04-16 03:17:092092 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:582093 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:192094 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:172095
2096 MockRead data_reads[] = {
2097 MockRead("HTTP/1.0 200 OK\r\n"),
2098 MockRead("Connection: keep-alive\r\n"),
2099 MockRead("Content-Length: 100\r\n\r\n"),
2100 MockRead("hello"),
2101 MockRead(SYNCHRONOUS, 0),
2102 };
Ryan Sleevib8d7ea02018-05-07 20:01:012103 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:072104 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:172105
2106 TestCompletionCallback callback;
2107
tfarina42834112016-09-22 13:38:202108 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012109 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:172110
2111 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:012112 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:172113
Victor Costan9c7302b2018-08-27 16:39:442114 scoped_refptr<IOBufferWithSize> io_buf =
2115 base::MakeRefCounted<IOBufferWithSize>(100);
[email protected]90499482013-06-01 00:39:502116 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:172117 if (rv == ERR_IO_PENDING)
2118 rv = callback.WaitForResult();
2119 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:502120 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
robpercival214763f2016-07-01 23:27:012121 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:172122
2123 trans.reset();
fdoray92e35a72016-06-10 15:54:552124 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:172125 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2126}
2127
bncd16676a2016-07-20 16:23:012128TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:172129 HttpRequestInfo request;
2130 request.method = "GET";
bncce36dca22015-04-21 22:11:232131 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102132 request.traffic_annotation =
2133 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7a5378b2012-11-04 03:25:172134
danakj1fd259a02016-04-16 03:17:092135 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:582136 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:192137 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:172138
2139 MockRead data_reads[] = {
2140 MockRead("HTTP/1.0 200 OK\r\n"),
2141 MockRead("Connection: keep-alive\r\n"),
2142 MockRead("Content-Length: 100\r\n\r\n"),
2143 MockRead(SYNCHRONOUS, 0),
2144 };
Ryan Sleevib8d7ea02018-05-07 20:01:012145 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:072146 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:172147
2148 TestCompletionCallback callback;
2149
tfarina42834112016-09-22 13:38:202150 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012151 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:172152
2153 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:012154 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:172155
Victor Costan9c7302b2018-08-27 16:39:442156 scoped_refptr<IOBufferWithSize> io_buf(
2157 base::MakeRefCounted<IOBufferWithSize>(100));
[email protected]90499482013-06-01 00:39:502158 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:172159 if (rv == ERR_IO_PENDING)
2160 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:012161 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:172162
2163 trans.reset();
fdoray92e35a72016-06-10 15:54:552164 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:172165 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2166}
2167
[email protected]0b0bf032010-09-21 18:08:502168// Test that we correctly reuse a keep-alive connection after not explicitly
2169// reading the body.
bncd16676a2016-07-20 16:23:012170TEST_F(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:132171 HttpRequestInfo request;
2172 request.method = "GET";
2173 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:102174 request.traffic_annotation =
2175 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]fc31d6a42010-06-24 18:05:132176
vishal.b62985ca92015-04-17 08:45:512177 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:072178 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:092179 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272180
mmenkecc2298e2015-12-07 18:20:182181 const char* request_data =
2182 "GET / HTTP/1.1\r\n"
2183 "Host: www.foo.com\r\n"
2184 "Connection: keep-alive\r\n\r\n";
2185 MockWrite data_writes[] = {
2186 MockWrite(ASYNC, 0, request_data), MockWrite(ASYNC, 2, request_data),
2187 MockWrite(ASYNC, 4, request_data), MockWrite(ASYNC, 6, request_data),
2188 MockWrite(ASYNC, 8, request_data), MockWrite(ASYNC, 10, request_data),
2189 MockWrite(ASYNC, 12, request_data), MockWrite(ASYNC, 14, request_data),
2190 MockWrite(ASYNC, 17, request_data), MockWrite(ASYNC, 20, request_data),
2191 };
2192
[email protected]0b0bf032010-09-21 18:08:502193 // Note that because all these reads happen in the same
2194 // StaticSocketDataProvider, it shows that the same socket is being reused for
2195 // all transactions.
mmenkecc2298e2015-12-07 18:20:182196 MockRead data_reads[] = {
2197 MockRead(ASYNC, 1, "HTTP/1.1 204 No Content\r\n\r\n"),
2198 MockRead(ASYNC, 3, "HTTP/1.1 205 Reset Content\r\n\r\n"),
2199 MockRead(ASYNC, 5, "HTTP/1.1 304 Not Modified\r\n\r\n"),
2200 MockRead(ASYNC, 7,
2201 "HTTP/1.1 302 Found\r\n"
2202 "Content-Length: 0\r\n\r\n"),
2203 MockRead(ASYNC, 9,
2204 "HTTP/1.1 302 Found\r\n"
2205 "Content-Length: 5\r\n\r\n"
2206 "hello"),
2207 MockRead(ASYNC, 11,
2208 "HTTP/1.1 301 Moved Permanently\r\n"
2209 "Content-Length: 0\r\n\r\n"),
2210 MockRead(ASYNC, 13,
2211 "HTTP/1.1 301 Moved Permanently\r\n"
2212 "Content-Length: 5\r\n\r\n"
2213 "hello"),
[email protected]fc31d6a42010-06-24 18:05:132214
mmenkecc2298e2015-12-07 18:20:182215 // In the next two rounds, IsConnectedAndIdle returns false, due to
2216 // the set_busy_before_sync_reads(true) call, while the
2217 // HttpNetworkTransaction is being shut down, but the socket is still
2218 // reuseable. See http://crbug.com/544255.
2219 MockRead(ASYNC, 15,
2220 "HTTP/1.1 200 Hunky-Dory\r\n"
2221 "Content-Length: 5\r\n\r\n"),
2222 MockRead(SYNCHRONOUS, 16, "hello"),
[email protected]fc31d6a42010-06-24 18:05:132223
mmenkecc2298e2015-12-07 18:20:182224 MockRead(ASYNC, 18,
2225 "HTTP/1.1 200 Hunky-Dory\r\n"
2226 "Content-Length: 5\r\n\r\n"
2227 "he"),
2228 MockRead(SYNCHRONOUS, 19, "llo"),
2229
2230 // The body of the final request is actually read.
2231 MockRead(ASYNC, 21, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
2232 MockRead(ASYNC, 22, "hello"),
2233 };
Ryan Sleevib8d7ea02018-05-07 20:01:012234 SequencedSocketData data(data_reads, data_writes);
mmenkecc2298e2015-12-07 18:20:182235 data.set_busy_before_sync_reads(true);
2236 session_deps_.socket_factory->AddSocketDataProvider(&data);
2237
Avi Drissman4365a4782018-12-28 19:26:242238 const int kNumUnreadBodies = base::size(data_writes) - 1;
[email protected]0b0bf032010-09-21 18:08:502239 std::string response_lines[kNumUnreadBodies];
2240
mikecironef22f9812016-10-04 03:40:192241 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
mmenkecc2298e2015-12-07 18:20:182242 for (size_t i = 0; i < kNumUnreadBodies; ++i) {
[email protected]49639fa2011-12-20 23:22:412243 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:132244
Jeremy Roman0579ed62017-08-29 15:56:192245 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
bnc87dcefc2017-05-25 12:47:582246 session.get());
[email protected]fc31d6a42010-06-24 18:05:132247
tfarina42834112016-09-22 13:38:202248 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012249 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]fc31d6a42010-06-24 18:05:132250
[email protected]58e32bb2013-01-21 18:23:252251 LoadTimingInfo load_timing_info;
2252 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2253 if (i == 0) {
2254 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
2255 first_socket_log_id = load_timing_info.socket_log_id;
2256 } else {
2257 TestLoadTimingReused(load_timing_info);
2258 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
2259 }
2260
[email protected]fc31d6a42010-06-24 18:05:132261 const HttpResponseInfo* response = trans->GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182262 ASSERT_TRUE(response);
[email protected]fc31d6a42010-06-24 18:05:132263
mmenkecc2298e2015-12-07 18:20:182264 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502265 response_lines[i] = response->headers->GetStatusLine();
2266
mmenkecc2298e2015-12-07 18:20:182267 // Delete the transaction without reading the response bodies. Then spin
2268 // the message loop, so the response bodies are drained.
2269 trans.reset();
2270 base::RunLoop().RunUntilIdle();
[email protected]fc31d6a42010-06-24 18:05:132271 }
[email protected]0b0bf032010-09-21 18:08:502272
2273 const char* const kStatusLines[] = {
mmenkecc2298e2015-12-07 18:20:182274 "HTTP/1.1 204 No Content",
2275 "HTTP/1.1 205 Reset Content",
2276 "HTTP/1.1 304 Not Modified",
2277 "HTTP/1.1 302 Found",
2278 "HTTP/1.1 302 Found",
2279 "HTTP/1.1 301 Moved Permanently",
2280 "HTTP/1.1 301 Moved Permanently",
2281 "HTTP/1.1 200 Hunky-Dory",
2282 "HTTP/1.1 200 Hunky-Dory",
[email protected]0b0bf032010-09-21 18:08:502283 };
2284
Avi Drissman4365a4782018-12-28 19:26:242285 static_assert(kNumUnreadBodies == base::size(kStatusLines),
mostynb91e0da982015-01-20 19:17:272286 "forgot to update kStatusLines");
[email protected]0b0bf032010-09-21 18:08:502287
2288 for (int i = 0; i < kNumUnreadBodies; ++i)
2289 EXPECT_EQ(kStatusLines[i], response_lines[i]);
2290
[email protected]49639fa2011-12-20 23:22:412291 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:162292 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202293 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012294 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:162295 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182296 ASSERT_TRUE(response);
2297 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502298 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2299 std::string response_data;
bnc691fda62016-08-12 00:43:162300 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:012301 EXPECT_THAT(rv, IsOk());
[email protected]0b0bf032010-09-21 18:08:502302 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:132303}
2304
mmenke5f94fda2016-06-02 20:54:132305// Sockets that receive extra data after a response is complete should not be
2306// reused.
bncd16676a2016-07-20 16:23:012307TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData1) {
mmenke5f94fda2016-06-02 20:54:132308 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2309 MockWrite data_writes1[] = {
2310 MockWrite("HEAD / HTTP/1.1\r\n"
2311 "Host: www.borked.com\r\n"
2312 "Connection: keep-alive\r\n\r\n"),
2313 };
2314
2315 MockRead data_reads1[] = {
2316 MockRead("HTTP/1.1 200 OK\r\n"
2317 "Connection: keep-alive\r\n"
2318 "Content-Length: 22\r\n\r\n"
2319 "This server is borked."),
2320 };
2321
2322 MockWrite data_writes2[] = {
2323 MockWrite("GET /foo HTTP/1.1\r\n"
2324 "Host: www.borked.com\r\n"
2325 "Connection: keep-alive\r\n\r\n"),
2326 };
2327
2328 MockRead data_reads2[] = {
2329 MockRead("HTTP/1.1 200 OK\r\n"
2330 "Content-Length: 3\r\n\r\n"
2331 "foo"),
2332 };
Ryan Sleevib8d7ea02018-05-07 20:01:012333 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke5f94fda2016-06-02 20:54:132334 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:012335 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke5f94fda2016-06-02 20:54:132336 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2337
2338 TestCompletionCallback callback;
2339 HttpRequestInfo request1;
2340 request1.method = "HEAD";
2341 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e2018-02-07 07:41:102342 request1.traffic_annotation =
2343 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132344
bnc87dcefc2017-05-25 12:47:582345 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192346 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202347 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012348 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132349
2350 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2351 ASSERT_TRUE(response1);
2352 ASSERT_TRUE(response1->headers);
2353 EXPECT_EQ(200, response1->headers->response_code());
2354 EXPECT_TRUE(response1->headers->IsKeepAlive());
2355
2356 std::string response_data1;
robpercival214763f2016-07-01 23:27:012357 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132358 EXPECT_EQ("", response_data1);
2359 // Deleting the transaction attempts to release the socket back into the
2360 // socket pool.
2361 trans1.reset();
2362
2363 HttpRequestInfo request2;
2364 request2.method = "GET";
2365 request2.url = GURL("http://www.borked.com/foo");
Ramin Halavatib5e433e2018-02-07 07:41:102366 request2.traffic_annotation =
2367 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132368
bnc87dcefc2017-05-25 12:47:582369 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192370 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202371 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012372 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132373
2374 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2375 ASSERT_TRUE(response2);
2376 ASSERT_TRUE(response2->headers);
2377 EXPECT_EQ(200, response2->headers->response_code());
2378
2379 std::string response_data2;
robpercival214763f2016-07-01 23:27:012380 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132381 EXPECT_EQ("foo", response_data2);
2382}
2383
bncd16676a2016-07-20 16:23:012384TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData2) {
mmenke5f94fda2016-06-02 20:54:132385 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2386 MockWrite data_writes1[] = {
2387 MockWrite("GET / HTTP/1.1\r\n"
2388 "Host: www.borked.com\r\n"
2389 "Connection: keep-alive\r\n\r\n"),
2390 };
2391
2392 MockRead data_reads1[] = {
2393 MockRead("HTTP/1.1 200 OK\r\n"
2394 "Connection: keep-alive\r\n"
2395 "Content-Length: 22\r\n\r\n"
2396 "This server is borked."
2397 "Bonus data!"),
2398 };
2399
2400 MockWrite data_writes2[] = {
2401 MockWrite("GET /foo HTTP/1.1\r\n"
2402 "Host: www.borked.com\r\n"
2403 "Connection: keep-alive\r\n\r\n"),
2404 };
2405
2406 MockRead data_reads2[] = {
2407 MockRead("HTTP/1.1 200 OK\r\n"
2408 "Content-Length: 3\r\n\r\n"
2409 "foo"),
2410 };
Ryan Sleevib8d7ea02018-05-07 20:01:012411 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke5f94fda2016-06-02 20:54:132412 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:012413 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke5f94fda2016-06-02 20:54:132414 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2415
2416 TestCompletionCallback callback;
2417 HttpRequestInfo request1;
2418 request1.method = "GET";
2419 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e2018-02-07 07:41:102420 request1.traffic_annotation =
2421 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132422
bnc87dcefc2017-05-25 12:47:582423 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192424 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202425 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012426 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132427
2428 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2429 ASSERT_TRUE(response1);
2430 ASSERT_TRUE(response1->headers);
2431 EXPECT_EQ(200, response1->headers->response_code());
2432 EXPECT_TRUE(response1->headers->IsKeepAlive());
2433
2434 std::string response_data1;
robpercival214763f2016-07-01 23:27:012435 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132436 EXPECT_EQ("This server is borked.", response_data1);
2437 // Deleting the transaction attempts to release the socket back into the
2438 // socket pool.
2439 trans1.reset();
2440
2441 HttpRequestInfo request2;
2442 request2.method = "GET";
2443 request2.url = GURL("http://www.borked.com/foo");
Ramin Halavatib5e433e2018-02-07 07:41:102444 request2.traffic_annotation =
2445 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132446
bnc87dcefc2017-05-25 12:47:582447 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192448 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202449 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012450 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132451
2452 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2453 ASSERT_TRUE(response2);
2454 ASSERT_TRUE(response2->headers);
2455 EXPECT_EQ(200, response2->headers->response_code());
2456
2457 std::string response_data2;
robpercival214763f2016-07-01 23:27:012458 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132459 EXPECT_EQ("foo", response_data2);
2460}
2461
bncd16676a2016-07-20 16:23:012462TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData3) {
mmenke5f94fda2016-06-02 20:54:132463 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2464 MockWrite data_writes1[] = {
2465 MockWrite("GET / HTTP/1.1\r\n"
2466 "Host: www.borked.com\r\n"
2467 "Connection: keep-alive\r\n\r\n"),
2468 };
2469
2470 MockRead data_reads1[] = {
2471 MockRead("HTTP/1.1 200 OK\r\n"
2472 "Connection: keep-alive\r\n"
2473 "Transfer-Encoding: chunked\r\n\r\n"),
2474 MockRead("16\r\nThis server is borked.\r\n"),
2475 MockRead("0\r\n\r\nBonus data!"),
2476 };
2477
2478 MockWrite data_writes2[] = {
2479 MockWrite("GET /foo HTTP/1.1\r\n"
2480 "Host: www.borked.com\r\n"
2481 "Connection: keep-alive\r\n\r\n"),
2482 };
2483
2484 MockRead data_reads2[] = {
2485 MockRead("HTTP/1.1 200 OK\r\n"
2486 "Content-Length: 3\r\n\r\n"
2487 "foo"),
2488 };
Ryan Sleevib8d7ea02018-05-07 20:01:012489 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke5f94fda2016-06-02 20:54:132490 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:012491 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke5f94fda2016-06-02 20:54:132492 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2493
2494 TestCompletionCallback callback;
2495 HttpRequestInfo request1;
2496 request1.method = "GET";
2497 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e2018-02-07 07:41:102498 request1.traffic_annotation =
2499 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132500
bnc87dcefc2017-05-25 12:47:582501 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192502 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202503 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012504 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132505
2506 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2507 ASSERT_TRUE(response1);
2508 ASSERT_TRUE(response1->headers);
2509 EXPECT_EQ(200, response1->headers->response_code());
2510 EXPECT_TRUE(response1->headers->IsKeepAlive());
2511
2512 std::string response_data1;
robpercival214763f2016-07-01 23:27:012513 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132514 EXPECT_EQ("This server is borked.", response_data1);
2515 // Deleting the transaction attempts to release the socket back into the
2516 // socket pool.
2517 trans1.reset();
2518
2519 HttpRequestInfo request2;
2520 request2.method = "GET";
2521 request2.url = GURL("http://www.borked.com/foo");
Ramin Halavatib5e433e2018-02-07 07:41:102522 request2.traffic_annotation =
2523 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132524
bnc87dcefc2017-05-25 12:47:582525 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192526 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202527 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012528 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132529
2530 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2531 ASSERT_TRUE(response2);
2532 ASSERT_TRUE(response2->headers);
2533 EXPECT_EQ(200, response2->headers->response_code());
2534
2535 std::string response_data2;
robpercival214763f2016-07-01 23:27:012536 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132537 EXPECT_EQ("foo", response_data2);
2538}
2539
2540// This is a little different from the others - it tests the case that the
2541// HttpStreamParser doesn't know if there's extra data on a socket or not when
2542// the HttpNetworkTransaction is torn down, because the response body hasn't
2543// been read from yet, but the request goes through the HttpResponseBodyDrainer.
bncd16676a2016-07-20 16:23:012544TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData4) {
mmenke5f94fda2016-06-02 20:54:132545 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2546 MockWrite data_writes1[] = {
2547 MockWrite("GET / HTTP/1.1\r\n"
2548 "Host: www.borked.com\r\n"
2549 "Connection: keep-alive\r\n\r\n"),
2550 };
2551
2552 MockRead data_reads1[] = {
2553 MockRead("HTTP/1.1 200 OK\r\n"
2554 "Connection: keep-alive\r\n"
2555 "Transfer-Encoding: chunked\r\n\r\n"),
2556 MockRead("16\r\nThis server is borked.\r\n"),
2557 MockRead("0\r\n\r\nBonus data!"),
2558 };
Ryan Sleevib8d7ea02018-05-07 20:01:012559 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke5f94fda2016-06-02 20:54:132560 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2561
2562 TestCompletionCallback callback;
2563 HttpRequestInfo request1;
2564 request1.method = "GET";
2565 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e2018-02-07 07:41:102566 request1.traffic_annotation =
2567 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132568
bnc87dcefc2017-05-25 12:47:582569 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:192570 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
bnc87dcefc2017-05-25 12:47:582571 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012572 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132573
bnc87dcefc2017-05-25 12:47:582574 const HttpResponseInfo* response1 = trans->GetResponseInfo();
mmenke5f94fda2016-06-02 20:54:132575 ASSERT_TRUE(response1);
2576 ASSERT_TRUE(response1->headers);
2577 EXPECT_EQ(200, response1->headers->response_code());
2578 EXPECT_TRUE(response1->headers->IsKeepAlive());
2579
2580 // Deleting the transaction creates an HttpResponseBodyDrainer to read the
2581 // response body.
bnc87dcefc2017-05-25 12:47:582582 trans.reset();
mmenke5f94fda2016-06-02 20:54:132583
2584 // Let the HttpResponseBodyDrainer drain the socket. It should determine the
2585 // socket can't be reused, rather than returning it to the socket pool.
2586 base::RunLoop().RunUntilIdle();
2587
2588 // There should be no idle sockets in the pool.
2589 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2590}
2591
[email protected]038e9a32008-10-08 22:40:162592// Test the request-challenge-retry sequence for basic auth.
2593// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012594TEST_F(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:422595 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:162596 request.method = "GET";
bncce36dca22015-04-21 22:11:232597 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102598 request.traffic_annotation =
2599 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]038e9a32008-10-08 22:40:162600
vishal.b62985ca92015-04-17 08:45:512601 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072602 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092603 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162604 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272605
[email protected]f9ee6b52008-11-08 06:46:232606 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232607 MockWrite(
2608 "GET / HTTP/1.1\r\n"
2609 "Host: www.example.org\r\n"
2610 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:232611 };
2612
[email protected]038e9a32008-10-08 22:40:162613 MockRead data_reads1[] = {
2614 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2615 // Give a couple authenticate options (only the middle one is actually
2616 // supported).
[email protected]22927ad2009-09-21 19:56:192617 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:162618 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2619 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2620 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2621 // Large content-length -- won't matter, as connection will be reset.
2622 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062623 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:162624 };
2625
2626 // After calling trans->RestartWithAuth(), this is the request we should
2627 // be issuing -- the final header line contains the credentials.
2628 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232629 MockWrite(
2630 "GET / HTTP/1.1\r\n"
2631 "Host: www.example.org\r\n"
2632 "Connection: keep-alive\r\n"
2633 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:162634 };
2635
2636 // Lastly, the server responds with the actual content.
2637 MockRead data_reads2[] = {
2638 MockRead("HTTP/1.0 200 OK\r\n"),
2639 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2640 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062641 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:162642 };
2643
Ryan Sleevib8d7ea02018-05-07 20:01:012644 StaticSocketDataProvider data1(data_reads1, data_writes1);
2645 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:072646 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2647 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:162648
[email protected]49639fa2011-12-20 23:22:412649 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:162650
tfarina42834112016-09-22 13:38:202651 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012652 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162653
2654 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012655 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162656
[email protected]58e32bb2013-01-21 18:23:252657 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162658 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
[email protected]58e32bb2013-01-21 18:23:252659 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2660
Ryan Sleevib8d7ea02018-05-07 20:01:012661 int64_t writes_size1 = CountWriteBytes(data_writes1);
bnc691fda62016-08-12 00:43:162662 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012663 int64_t reads_size1 = CountReadBytes(data_reads1);
bnc691fda62016-08-12 00:43:162664 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192665
bnc691fda62016-08-12 00:43:162666 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522667 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042668 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:162669
[email protected]49639fa2011-12-20 23:22:412670 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:162671
bnc691fda62016-08-12 00:43:162672 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012673 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162674
2675 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012676 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162677
[email protected]58e32bb2013-01-21 18:23:252678 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162679 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
[email protected]58e32bb2013-01-21 18:23:252680 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2681 // The load timing after restart should have a new socket ID, and times after
2682 // those of the first load timing.
2683 EXPECT_LE(load_timing_info1.receive_headers_end,
2684 load_timing_info2.connect_timing.connect_start);
2685 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2686
Ryan Sleevib8d7ea02018-05-07 20:01:012687 int64_t writes_size2 = CountWriteBytes(data_writes2);
bnc691fda62016-08-12 00:43:162688 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012689 int64_t reads_size2 = CountReadBytes(data_reads2);
bnc691fda62016-08-12 00:43:162690 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192691
bnc691fda62016-08-12 00:43:162692 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522693 ASSERT_TRUE(response);
2694 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:162695 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:162696}
2697
ttuttled9dbc652015-09-29 20:00:592698// Test the request-challenge-retry sequence for basic auth.
2699// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012700TEST_F(HttpNetworkTransactionTest, BasicAuthWithAddressChange) {
ttuttled9dbc652015-09-29 20:00:592701 HttpRequestInfo request;
2702 request.method = "GET";
2703 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102704 request.traffic_annotation =
2705 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttled9dbc652015-09-29 20:00:592706
2707 TestNetLog log;
2708 MockHostResolver* resolver = new MockHostResolver();
2709 session_deps_.net_log = &log;
2710 session_deps_.host_resolver.reset(resolver);
danakj1fd259a02016-04-16 03:17:092711 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
bnc691fda62016-08-12 00:43:162712 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttled9dbc652015-09-29 20:00:592713
2714 resolver->rules()->ClearRules();
2715 resolver->rules()->AddRule("www.example.org", "127.0.0.1");
2716
2717 MockWrite data_writes1[] = {
2718 MockWrite("GET / HTTP/1.1\r\n"
2719 "Host: www.example.org\r\n"
2720 "Connection: keep-alive\r\n\r\n"),
2721 };
2722
2723 MockRead data_reads1[] = {
2724 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2725 // Give a couple authenticate options (only the middle one is actually
2726 // supported).
2727 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
2728 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2729 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2730 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2731 // Large content-length -- won't matter, as connection will be reset.
2732 MockRead("Content-Length: 10000\r\n\r\n"),
2733 MockRead(SYNCHRONOUS, ERR_FAILED),
2734 };
2735
2736 // After calling trans->RestartWithAuth(), this is the request we should
2737 // be issuing -- the final header line contains the credentials.
2738 MockWrite data_writes2[] = {
2739 MockWrite("GET / HTTP/1.1\r\n"
2740 "Host: www.example.org\r\n"
2741 "Connection: keep-alive\r\n"
2742 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2743 };
2744
2745 // Lastly, the server responds with the actual content.
2746 MockRead data_reads2[] = {
2747 MockRead("HTTP/1.0 200 OK\r\n"),
2748 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2749 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, OK),
2750 };
2751
Ryan Sleevib8d7ea02018-05-07 20:01:012752 StaticSocketDataProvider data1(data_reads1, data_writes1);
2753 StaticSocketDataProvider data2(data_reads2, data_writes2);
ttuttled9dbc652015-09-29 20:00:592754 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2755 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2756
2757 TestCompletionCallback callback1;
2758
bnc691fda62016-08-12 00:43:162759 EXPECT_EQ(OK, callback1.GetResult(trans.Start(&request, callback1.callback(),
tfarina42834112016-09-22 13:38:202760 NetLogWithSource())));
ttuttled9dbc652015-09-29 20:00:592761
2762 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162763 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
ttuttled9dbc652015-09-29 20:00:592764 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2765
Ryan Sleevib8d7ea02018-05-07 20:01:012766 int64_t writes_size1 = CountWriteBytes(data_writes1);
bnc691fda62016-08-12 00:43:162767 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012768 int64_t reads_size1 = CountReadBytes(data_reads1);
bnc691fda62016-08-12 00:43:162769 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592770
bnc691fda62016-08-12 00:43:162771 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592772 ASSERT_TRUE(response);
2773 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2774
2775 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:162776 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592777 ASSERT_FALSE(endpoint.address().empty());
2778 EXPECT_EQ("127.0.0.1:80", endpoint.ToString());
2779
2780 resolver->rules()->ClearRules();
2781 resolver->rules()->AddRule("www.example.org", "127.0.0.2");
2782
2783 TestCompletionCallback callback2;
2784
bnc691fda62016-08-12 00:43:162785 EXPECT_EQ(OK, callback2.GetResult(trans.RestartWithAuth(
ttuttled9dbc652015-09-29 20:00:592786 AuthCredentials(kFoo, kBar), callback2.callback())));
2787
2788 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162789 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
ttuttled9dbc652015-09-29 20:00:592790 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2791 // The load timing after restart should have a new socket ID, and times after
2792 // those of the first load timing.
2793 EXPECT_LE(load_timing_info1.receive_headers_end,
2794 load_timing_info2.connect_timing.connect_start);
2795 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2796
Ryan Sleevib8d7ea02018-05-07 20:01:012797 int64_t writes_size2 = CountWriteBytes(data_writes2);
bnc691fda62016-08-12 00:43:162798 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012799 int64_t reads_size2 = CountReadBytes(data_reads2);
bnc691fda62016-08-12 00:43:162800 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592801
bnc691fda62016-08-12 00:43:162802 response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592803 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:522804 EXPECT_FALSE(response->auth_challenge);
ttuttled9dbc652015-09-29 20:00:592805 EXPECT_EQ(100, response->headers->GetContentLength());
2806
bnc691fda62016-08-12 00:43:162807 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592808 ASSERT_FALSE(endpoint.address().empty());
2809 EXPECT_EQ("127.0.0.2:80", endpoint.ToString());
2810}
2811
David Benjamin83ddfb32018-03-30 01:07:522812// Test that, if the server requests auth indefinitely, HttpNetworkTransaction
2813// will eventually give up.
2814TEST_F(HttpNetworkTransactionTest, BasicAuthForever) {
2815 HttpRequestInfo request;
2816 request.method = "GET";
2817 request.url = GURL("http://www.example.org/");
2818 request.traffic_annotation =
2819 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2820
2821 TestNetLog log;
2822 session_deps_.net_log = &log;
2823 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2824 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
2825
2826 MockWrite data_writes[] = {
2827 MockWrite("GET / HTTP/1.1\r\n"
2828 "Host: www.example.org\r\n"
2829 "Connection: keep-alive\r\n\r\n"),
2830 };
2831
2832 MockRead data_reads[] = {
2833 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2834 // Give a couple authenticate options (only the middle one is actually
2835 // supported).
2836 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
2837 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2838 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2839 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2840 // Large content-length -- won't matter, as connection will be reset.
2841 MockRead("Content-Length: 10000\r\n\r\n"),
2842 MockRead(SYNCHRONOUS, ERR_FAILED),
2843 };
2844
2845 // After calling trans->RestartWithAuth(), this is the request we should
2846 // be issuing -- the final header line contains the credentials.
2847 MockWrite data_writes_restart[] = {
2848 MockWrite("GET / HTTP/1.1\r\n"
2849 "Host: www.example.org\r\n"
2850 "Connection: keep-alive\r\n"
2851 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2852 };
2853
Ryan Sleevib8d7ea02018-05-07 20:01:012854 StaticSocketDataProvider data(data_reads, data_writes);
David Benjamin83ddfb32018-03-30 01:07:522855 session_deps_.socket_factory->AddSocketDataProvider(&data);
2856
2857 TestCompletionCallback callback;
2858 int rv = callback.GetResult(
2859 trans.Start(&request, callback.callback(), NetLogWithSource()));
2860
2861 std::vector<std::unique_ptr<StaticSocketDataProvider>> data_restarts;
2862 for (int i = 0; i < 32; i++) {
2863 // Check the previous response was a 401.
2864 EXPECT_THAT(rv, IsOk());
2865 const HttpResponseInfo* response = trans.GetResponseInfo();
2866 ASSERT_TRUE(response);
2867 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2868
2869 data_restarts.push_back(std::make_unique<StaticSocketDataProvider>(
Ryan Sleevib8d7ea02018-05-07 20:01:012870 data_reads, data_writes_restart));
David Benjamin83ddfb32018-03-30 01:07:522871 session_deps_.socket_factory->AddSocketDataProvider(
2872 data_restarts.back().get());
2873 rv = callback.GetResult(trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
2874 callback.callback()));
2875 }
2876
2877 // After too many tries, the transaction should have given up.
2878 EXPECT_THAT(rv, IsError(ERR_TOO_MANY_RETRIES));
2879}
2880
bncd16676a2016-07-20 16:23:012881TEST_F(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:462882 HttpRequestInfo request;
2883 request.method = "GET";
bncce36dca22015-04-21 22:11:232884 request.url = GURL("http://www.example.org/");
ttuttle859dc7a2015-04-23 19:42:292885 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:102886 request.traffic_annotation =
2887 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]861fcd52009-08-26 02:33:462888
danakj1fd259a02016-04-16 03:17:092889 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162890 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272891
[email protected]861fcd52009-08-26 02:33:462892 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:232893 MockWrite(
2894 "GET / HTTP/1.1\r\n"
2895 "Host: www.example.org\r\n"
2896 "Connection: keep-alive\r\n\r\n"),
[email protected]861fcd52009-08-26 02:33:462897 };
2898
2899 MockRead data_reads[] = {
2900 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2901 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2902 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2903 // Large content-length -- won't matter, as connection will be reset.
2904 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062905 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:462906 };
2907
Ryan Sleevib8d7ea02018-05-07 20:01:012908 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:072909 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:412910 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:462911
tfarina42834112016-09-22 13:38:202912 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012913 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]861fcd52009-08-26 02:33:462914
2915 rv = callback.WaitForResult();
2916 EXPECT_EQ(0, rv);
2917
Ryan Sleevib8d7ea02018-05-07 20:01:012918 int64_t writes_size = CountWriteBytes(data_writes);
bnc691fda62016-08-12 00:43:162919 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012920 int64_t reads_size = CountReadBytes(data_reads);
bnc691fda62016-08-12 00:43:162921 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192922
bnc691fda62016-08-12 00:43:162923 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522924 ASSERT_TRUE(response);
2925 EXPECT_FALSE(response->auth_challenge);
[email protected]861fcd52009-08-26 02:33:462926}
2927
[email protected]2d2697f92009-02-18 21:00:322928// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2929// connection.
bncd16676a2016-07-20 16:23:012930TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
mmenkecc2298e2015-12-07 18:20:182931 // On the second pass, the body read of the auth challenge is synchronous, so
2932 // IsConnectedAndIdle returns false. The socket should still be drained and
2933 // reused. See http://crbug.com/544255.
2934 for (int i = 0; i < 2; ++i) {
2935 HttpRequestInfo request;
2936 request.method = "GET";
2937 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102938 request.traffic_annotation =
2939 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:322940
mmenkecc2298e2015-12-07 18:20:182941 TestNetLog log;
2942 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092943 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272944
mmenkecc2298e2015-12-07 18:20:182945 MockWrite data_writes[] = {
2946 MockWrite(ASYNC, 0,
2947 "GET / HTTP/1.1\r\n"
2948 "Host: www.example.org\r\n"
2949 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322950
bnc691fda62016-08-12 00:43:162951 // After calling trans.RestartWithAuth(), this is the request we should
mmenkecc2298e2015-12-07 18:20:182952 // be issuing -- the final header line contains the credentials.
2953 MockWrite(ASYNC, 6,
2954 "GET / HTTP/1.1\r\n"
2955 "Host: www.example.org\r\n"
2956 "Connection: keep-alive\r\n"
2957 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2958 };
[email protected]2d2697f92009-02-18 21:00:322959
mmenkecc2298e2015-12-07 18:20:182960 MockRead data_reads[] = {
2961 MockRead(ASYNC, 1, "HTTP/1.1 401 Unauthorized\r\n"),
2962 MockRead(ASYNC, 2, "WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2963 MockRead(ASYNC, 3, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2964 MockRead(ASYNC, 4, "Content-Length: 14\r\n\r\n"),
2965 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 5, "Unauthorized\r\n"),
[email protected]2d2697f92009-02-18 21:00:322966
mmenkecc2298e2015-12-07 18:20:182967 // Lastly, the server responds with the actual content.
2968 MockRead(ASYNC, 7, "HTTP/1.1 200 OK\r\n"),
2969 MockRead(ASYNC, 8, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2970 MockRead(ASYNC, 9, "Content-Length: 5\r\n\r\n"),
2971 MockRead(ASYNC, 10, "Hello"),
2972 };
[email protected]2d2697f92009-02-18 21:00:322973
Ryan Sleevib8d7ea02018-05-07 20:01:012974 SequencedSocketData data(data_reads, data_writes);
mmenkecc2298e2015-12-07 18:20:182975 data.set_busy_before_sync_reads(true);
2976 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]2d0a4f92011-05-05 16:38:462977
mmenkecc2298e2015-12-07 18:20:182978 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322979
bnc691fda62016-08-12 00:43:162980 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202981 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012982 ASSERT_THAT(callback1.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322983
mmenkecc2298e2015-12-07 18:20:182984 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162985 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
mmenkecc2298e2015-12-07 18:20:182986 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
[email protected]2d2697f92009-02-18 21:00:322987
bnc691fda62016-08-12 00:43:162988 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182989 ASSERT_TRUE(response);
2990 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322991
mmenkecc2298e2015-12-07 18:20:182992 TestCompletionCallback callback2;
[email protected]58e32bb2013-01-21 18:23:252993
bnc691fda62016-08-12 00:43:162994 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
2995 callback2.callback());
robpercival214763f2016-07-01 23:27:012996 ASSERT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322997
mmenkecc2298e2015-12-07 18:20:182998 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162999 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
mmenkecc2298e2015-12-07 18:20:183000 TestLoadTimingReused(load_timing_info2);
3001 // The load timing after restart should have the same socket ID, and times
3002 // those of the first load timing.
3003 EXPECT_LE(load_timing_info1.receive_headers_end,
3004 load_timing_info2.send_start);
3005 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]2d2697f92009-02-18 21:00:323006
bnc691fda62016-08-12 00:43:163007 response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:183008 ASSERT_TRUE(response);
3009 EXPECT_FALSE(response->auth_challenge);
3010 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:323011
mmenkecc2298e2015-12-07 18:20:183012 std::string response_data;
bnc691fda62016-08-12 00:43:163013 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]2d2697f92009-02-18 21:00:323014
Ryan Sleevib8d7ea02018-05-07 20:01:013015 int64_t writes_size = CountWriteBytes(data_writes);
bnc691fda62016-08-12 00:43:163016 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:013017 int64_t reads_size = CountReadBytes(data_reads);
bnc691fda62016-08-12 00:43:163018 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
mmenkecc2298e2015-12-07 18:20:183019 }
[email protected]2d2697f92009-02-18 21:00:323020}
3021
3022// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3023// connection and with no response body to drain.
bncd16676a2016-07-20 16:23:013024TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:423025 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:323026 request.method = "GET";
bncce36dca22015-04-21 22:11:233027 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:103028 request.traffic_annotation =
3029 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:323030
danakj1fd259a02016-04-16 03:17:093031 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273032
[email protected]2d2697f92009-02-18 21:00:323033 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:163034 MockWrite("GET / HTTP/1.1\r\n"
3035 "Host: www.example.org\r\n"
3036 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323037
bnc691fda62016-08-12 00:43:163038 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:233039 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:163040 MockWrite("GET / HTTP/1.1\r\n"
3041 "Host: www.example.org\r\n"
3042 "Connection: keep-alive\r\n"
3043 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323044 };
3045
[email protected]2d2697f92009-02-18 21:00:323046 MockRead data_reads1[] = {
3047 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
3048 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:313049 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:323050
3051 // Lastly, the server responds with the actual content.
3052 MockRead("HTTP/1.1 200 OK\r\n"),
3053 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:503054 MockRead("Content-Length: 5\r\n\r\n"),
3055 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:323056 };
3057
[email protected]2d0a4f92011-05-05 16:38:463058 // An incorrect reconnect would cause this to be read.
3059 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:063060 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:463061 };
3062
Ryan Sleevib8d7ea02018-05-07 20:01:013063 StaticSocketDataProvider data1(data_reads1, data_writes1);
3064 StaticSocketDataProvider data2(data_reads2, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:073065 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3066 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:323067
[email protected]49639fa2011-12-20 23:22:413068 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323069
bnc691fda62016-08-12 00:43:163070 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:203071 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013072 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:323073
3074 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013075 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:323076
bnc691fda62016-08-12 00:43:163077 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523078 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:043079 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:323080
[email protected]49639fa2011-12-20 23:22:413081 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323082
bnc691fda62016-08-12 00:43:163083 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013084 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:323085
3086 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013087 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:323088
bnc691fda62016-08-12 00:43:163089 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523090 ASSERT_TRUE(response);
3091 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503092 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:323093}
3094
3095// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3096// connection and with a large response body to drain.
bncd16676a2016-07-20 16:23:013097TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:423098 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:323099 request.method = "GET";
bncce36dca22015-04-21 22:11:233100 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:103101 request.traffic_annotation =
3102 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:323103
danakj1fd259a02016-04-16 03:17:093104 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273105
[email protected]2d2697f92009-02-18 21:00:323106 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:163107 MockWrite("GET / HTTP/1.1\r\n"
3108 "Host: www.example.org\r\n"
3109 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323110
bnc691fda62016-08-12 00:43:163111 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:233112 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:163113 MockWrite("GET / HTTP/1.1\r\n"
3114 "Host: www.example.org\r\n"
3115 "Connection: keep-alive\r\n"
3116 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323117 };
3118
3119 // Respond with 5 kb of response body.
3120 std::string large_body_string("Unauthorized");
3121 large_body_string.append(5 * 1024, ' ');
3122 large_body_string.append("\r\n");
3123
3124 MockRead data_reads1[] = {
3125 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
3126 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3127 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3128 // 5134 = 12 + 5 * 1024 + 2
3129 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063130 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:323131
3132 // Lastly, the server responds with the actual content.
3133 MockRead("HTTP/1.1 200 OK\r\n"),
3134 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:503135 MockRead("Content-Length: 5\r\n\r\n"),
3136 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:323137 };
3138
[email protected]2d0a4f92011-05-05 16:38:463139 // An incorrect reconnect would cause this to be read.
3140 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:063141 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:463142 };
3143
Ryan Sleevib8d7ea02018-05-07 20:01:013144 StaticSocketDataProvider data1(data_reads1, data_writes1);
3145 StaticSocketDataProvider data2(data_reads2, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:073146 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3147 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:323148
[email protected]49639fa2011-12-20 23:22:413149 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323150
bnc691fda62016-08-12 00:43:163151 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:203152 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013153 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:323154
3155 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013156 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:323157
bnc691fda62016-08-12 00:43:163158 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523159 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:043160 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:323161
[email protected]49639fa2011-12-20 23:22:413162 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323163
bnc691fda62016-08-12 00:43:163164 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013165 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:323166
3167 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013168 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:323169
bnc691fda62016-08-12 00:43:163170 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523171 ASSERT_TRUE(response);
3172 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503173 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:323174}
3175
3176// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:313177// connection, but the server gets impatient and closes the connection.
bncd16676a2016-07-20 16:23:013178TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:313179 HttpRequestInfo request;
3180 request.method = "GET";
bncce36dca22015-04-21 22:11:233181 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:103182 request.traffic_annotation =
3183 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]11203f012009-11-12 23:02:313184
danakj1fd259a02016-04-16 03:17:093185 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273186
[email protected]11203f012009-11-12 23:02:313187 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233188 MockWrite(
3189 "GET / HTTP/1.1\r\n"
3190 "Host: www.example.org\r\n"
3191 "Connection: keep-alive\r\n\r\n"),
3192 // This simulates the seemingly successful write to a closed connection
3193 // if the bug is not fixed.
3194 MockWrite(
3195 "GET / HTTP/1.1\r\n"
3196 "Host: www.example.org\r\n"
3197 "Connection: keep-alive\r\n"
3198 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:313199 };
3200
3201 MockRead data_reads1[] = {
3202 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
3203 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3204 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3205 MockRead("Content-Length: 14\r\n\r\n"),
3206 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:063207 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:313208 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:063209 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:313210 };
3211
bnc691fda62016-08-12 00:43:163212 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]11203f012009-11-12 23:02:313213 // be issuing -- the final header line contains the credentials.
3214 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:233215 MockWrite(
3216 "GET / HTTP/1.1\r\n"
3217 "Host: www.example.org\r\n"
3218 "Connection: keep-alive\r\n"
3219 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:313220 };
3221
3222 // Lastly, the server responds with the actual content.
3223 MockRead data_reads2[] = {
3224 MockRead("HTTP/1.1 200 OK\r\n"),
3225 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:503226 MockRead("Content-Length: 5\r\n\r\n"),
3227 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:313228 };
3229
Ryan Sleevib8d7ea02018-05-07 20:01:013230 StaticSocketDataProvider data1(data_reads1, data_writes1);
3231 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:073232 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3233 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:313234
[email protected]49639fa2011-12-20 23:22:413235 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:313236
bnc691fda62016-08-12 00:43:163237 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:203238 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013239 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:313240
3241 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013242 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:313243
bnc691fda62016-08-12 00:43:163244 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523245 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:043246 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:313247
[email protected]49639fa2011-12-20 23:22:413248 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:313249
bnc691fda62016-08-12 00:43:163250 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013251 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:313252
3253 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013254 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:313255
bnc691fda62016-08-12 00:43:163256 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523257 ASSERT_TRUE(response);
3258 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503259 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:313260}
3261
[email protected]394816e92010-08-03 07:38:593262// Test the request-challenge-retry sequence for basic auth, over a connection
3263// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013264TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
ttuttle34f63b52015-03-05 04:33:013265 HttpRequestInfo request;
3266 request.method = "GET";
bncce36dca22015-04-21 22:11:233267 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:013268 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293269 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103270 request.traffic_annotation =
3271 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle34f63b52015-03-05 04:33:013272
3273 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593274 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493275 ProxyResolutionService::CreateFixedFromPacResult(
3276 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513277 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:013278 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093279 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013280
3281 // Since we have proxy, should try to establish tunnel.
3282 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543283 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173284 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543285 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013286 };
3287
mmenkee71e15332015-10-07 16:39:543288 // The proxy responds to the connect with a 407, using a non-persistent
ttuttle34f63b52015-03-05 04:33:013289 // connection.
3290 MockRead data_reads1[] = {
3291 // No credentials.
3292 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
3293 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
mmenkee71e15332015-10-07 16:39:543294 };
ttuttle34f63b52015-03-05 04:33:013295
mmenkee71e15332015-10-07 16:39:543296 // Since the first connection couldn't be reused, need to establish another
3297 // once given credentials.
3298 MockWrite data_writes2[] = {
3299 // After calling trans->RestartWithAuth(), this is the request we should
3300 // be issuing -- the final header line contains the credentials.
3301 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173302 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543303 "Proxy-Connection: keep-alive\r\n"
3304 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3305
3306 MockWrite("GET / HTTP/1.1\r\n"
3307 "Host: www.example.org\r\n"
3308 "Connection: keep-alive\r\n\r\n"),
3309 };
3310
3311 MockRead data_reads2[] = {
ttuttle34f63b52015-03-05 04:33:013312 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3313
3314 MockRead("HTTP/1.1 200 OK\r\n"),
3315 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3316 MockRead("Content-Length: 5\r\n\r\n"),
3317 MockRead(SYNCHRONOUS, "hello"),
3318 };
3319
Ryan Sleevib8d7ea02018-05-07 20:01:013320 StaticSocketDataProvider data1(data_reads1, data_writes1);
ttuttle34f63b52015-03-05 04:33:013321 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:013322 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenkee71e15332015-10-07 16:39:543323 session_deps_.socket_factory->AddSocketDataProvider(&data2);
ttuttle34f63b52015-03-05 04:33:013324 SSLSocketDataProvider ssl(ASYNC, OK);
3325 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3326
3327 TestCompletionCallback callback1;
3328
bnc87dcefc2017-05-25 12:47:583329 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193330 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013331
3332 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013333 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:013334
3335 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013336 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463337 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:013338 log.GetEntries(&entries);
3339 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003340 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3341 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013342 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003343 entries, pos,
3344 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3345 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013346
3347 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523348 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013349 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523350 ASSERT_TRUE(response->headers);
ttuttle34f63b52015-03-05 04:33:013351 EXPECT_EQ(407, response->headers->response_code());
3352 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3353 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3354
3355 LoadTimingInfo load_timing_info;
3356 // CONNECT requests and responses are handled at the connect job level, so
3357 // the transaction does not yet have a connection.
3358 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3359
3360 TestCompletionCallback callback2;
3361
3362 rv =
3363 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013364 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:013365
3366 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013367 EXPECT_THAT(rv, IsOk());
ttuttle34f63b52015-03-05 04:33:013368
3369 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523370 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013371
3372 EXPECT_TRUE(response->headers->IsKeepAlive());
3373 EXPECT_EQ(200, response->headers->response_code());
3374 EXPECT_EQ(5, response->headers->GetContentLength());
3375 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3376
3377 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523378 EXPECT_FALSE(response->auth_challenge);
ttuttle34f63b52015-03-05 04:33:013379
3380 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3381 TestLoadTimingNotReusedWithPac(load_timing_info,
3382 CONNECT_TIMING_HAS_SSL_TIMES);
3383
3384 trans.reset();
3385 session->CloseAllConnections();
3386}
3387
3388// Test the request-challenge-retry sequence for basic auth, over a connection
3389// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013390TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) {
[email protected]394816e92010-08-03 07:38:593391 HttpRequestInfo request;
3392 request.method = "GET";
bncce36dca22015-04-21 22:11:233393 request.url = GURL("https://www.example.org/");
[email protected]394816e92010-08-03 07:38:593394 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293395 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103396 request.traffic_annotation =
3397 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]394816e92010-08-03 07:38:593398
[email protected]cb9bf6ca2011-01-28 13:15:273399 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593400 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493401 ProxyResolutionService::CreateFixedFromPacResult(
3402 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513403 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073404 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093405 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273406
[email protected]394816e92010-08-03 07:38:593407 // Since we have proxy, should try to establish tunnel.
3408 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543409 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173410 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543411 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenkee0b5c882015-08-26 20:29:113412 };
3413
mmenkee71e15332015-10-07 16:39:543414 // The proxy responds to the connect with a 407, using a non-persistent
mmenke0fd148d2015-09-30 23:00:083415 // connection.
3416 MockRead data_reads1[] = {
mmenkee71e15332015-10-07 16:39:543417 // No credentials.
3418 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3419 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3420 MockRead("Proxy-Connection: close\r\n\r\n"),
3421 };
mmenkee0b5c882015-08-26 20:29:113422
mmenkee71e15332015-10-07 16:39:543423 MockWrite data_writes2[] = {
3424 // After calling trans->RestartWithAuth(), this is the request we should
3425 // be issuing -- the final header line contains the credentials.
3426 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173427 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543428 "Proxy-Connection: keep-alive\r\n"
3429 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
mmenke0fd148d2015-09-30 23:00:083430
mmenkee71e15332015-10-07 16:39:543431 MockWrite("GET / HTTP/1.1\r\n"
3432 "Host: www.example.org\r\n"
3433 "Connection: keep-alive\r\n\r\n"),
3434 };
3435
3436 MockRead data_reads2[] = {
3437 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3438
3439 MockRead("HTTP/1.1 200 OK\r\n"),
3440 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3441 MockRead("Content-Length: 5\r\n\r\n"),
3442 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:593443 };
3444
Ryan Sleevib8d7ea02018-05-07 20:01:013445 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:073446 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:013447 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenkee71e15332015-10-07 16:39:543448 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8ddf8322012-02-23 18:08:063449 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073450 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:593451
[email protected]49639fa2011-12-20 23:22:413452 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:593453
bnc87dcefc2017-05-25 12:47:583454 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193455 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:503456
[email protected]49639fa2011-12-20 23:22:413457 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013458 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593459
3460 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013461 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463462 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403463 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:593464 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003465 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3466 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593467 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403468 entries, pos,
mikecirone8b85c432016-09-08 19:11:003469 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3470 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593471
3472 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523473 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013474 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523475 ASSERT_TRUE(response->headers);
[email protected]394816e92010-08-03 07:38:593476 EXPECT_EQ(407, response->headers->response_code());
3477 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043478 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:593479
[email protected]029c83b62013-01-24 05:28:203480 LoadTimingInfo load_timing_info;
3481 // CONNECT requests and responses are handled at the connect job level, so
3482 // the transaction does not yet have a connection.
3483 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3484
[email protected]49639fa2011-12-20 23:22:413485 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:593486
[email protected]49639fa2011-12-20 23:22:413487 rv = trans->RestartWithAuth(
3488 AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013489 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593490
3491 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013492 EXPECT_THAT(rv, IsOk());
[email protected]394816e92010-08-03 07:38:593493
3494 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523495 ASSERT_TRUE(response);
[email protected]394816e92010-08-03 07:38:593496
3497 EXPECT_TRUE(response->headers->IsKeepAlive());
3498 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:503499 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:593500 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3501
3502 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523503 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503504
[email protected]029c83b62013-01-24 05:28:203505 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3506 TestLoadTimingNotReusedWithPac(load_timing_info,
3507 CONNECT_TIMING_HAS_SSL_TIMES);
3508
[email protected]0b0bf032010-09-21 18:08:503509 trans.reset();
[email protected]102e27c2011-02-23 01:01:313510 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:593511}
3512
[email protected]11203f012009-11-12 23:02:313513// Test the request-challenge-retry sequence for basic auth, over a keep-alive
ttuttle34f63b52015-03-05 04:33:013514// proxy connection with HTTP/1.0 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013515TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
mmenked39192ee2015-12-09 00:57:233516 // On the second pass, the body read of the auth challenge is synchronous, so
3517 // IsConnectedAndIdle returns false. The socket should still be drained and
3518 // reused. See http://crbug.com/544255.
3519 for (int i = 0; i < 2; ++i) {
3520 HttpRequestInfo request;
3521 request.method = "GET";
3522 request.url = GURL("https://www.example.org/");
3523 // Ensure that proxy authentication is attempted even
3524 // when the no authentication data flag is set.
3525 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103526 request.traffic_annotation =
3527 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle34f63b52015-03-05 04:33:013528
mmenked39192ee2015-12-09 00:57:233529 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593530 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493531 ProxyResolutionService::CreateFixed("myproxy:70",
3532 TRAFFIC_ANNOTATION_FOR_TESTS);
mmenked39192ee2015-12-09 00:57:233533 BoundTestNetLog log;
3534 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093535 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013536
bnc691fda62016-08-12 00:43:163537 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013538
mmenked39192ee2015-12-09 00:57:233539 // Since we have proxy, should try to establish tunnel.
3540 MockWrite data_writes1[] = {
3541 MockWrite(ASYNC, 0,
3542 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3543 "Host: www.example.org:443\r\n"
3544 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013545
bnc691fda62016-08-12 00:43:163546 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233547 // be issuing -- the final header line contains the credentials.
3548 MockWrite(ASYNC, 3,
3549 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3550 "Host: www.example.org:443\r\n"
3551 "Proxy-Connection: keep-alive\r\n"
3552 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3553 };
ttuttle34f63b52015-03-05 04:33:013554
mmenked39192ee2015-12-09 00:57:233555 // The proxy responds to the connect with a 407, using a persistent
3556 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3557 MockRead data_reads1[] = {
3558 // No credentials.
3559 MockRead(ASYNC, 1,
3560 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3561 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3562 "Proxy-Connection: keep-alive\r\n"
3563 "Content-Length: 10\r\n\r\n"),
3564 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
ttuttle34f63b52015-03-05 04:33:013565
mmenked39192ee2015-12-09 00:57:233566 // Wrong credentials (wrong password).
3567 MockRead(ASYNC, 4,
3568 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3569 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3570 "Proxy-Connection: keep-alive\r\n"
3571 "Content-Length: 10\r\n\r\n"),
3572 // No response body because the test stops reading here.
3573 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3574 };
ttuttle34f63b52015-03-05 04:33:013575
Ryan Sleevib8d7ea02018-05-07 20:01:013576 SequencedSocketData data1(data_reads1, data_writes1);
mmenked39192ee2015-12-09 00:57:233577 data1.set_busy_before_sync_reads(true);
3578 session_deps_.socket_factory->AddSocketDataProvider(&data1);
ttuttle34f63b52015-03-05 04:33:013579
mmenked39192ee2015-12-09 00:57:233580 TestCompletionCallback callback1;
ttuttle34f63b52015-03-05 04:33:013581
bnc691fda62016-08-12 00:43:163582 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013583 EXPECT_THAT(callback1.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013584
mmenked39192ee2015-12-09 00:57:233585 TestNetLogEntry::List entries;
3586 log.GetEntries(&entries);
3587 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003588 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3589 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233590 ExpectLogContainsSomewhere(
3591 entries, pos,
mikecirone8b85c432016-09-08 19:11:003592 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3593 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013594
bnc691fda62016-08-12 00:43:163595 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233596 ASSERT_TRUE(response);
3597 ASSERT_TRUE(response->headers);
3598 EXPECT_TRUE(response->headers->IsKeepAlive());
3599 EXPECT_EQ(407, response->headers->response_code());
3600 EXPECT_EQ(10, response->headers->GetContentLength());
3601 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3602 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013603
mmenked39192ee2015-12-09 00:57:233604 TestCompletionCallback callback2;
ttuttle34f63b52015-03-05 04:33:013605
mmenked39192ee2015-12-09 00:57:233606 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163607 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3608 callback2.callback());
robpercival214763f2016-07-01 23:27:013609 EXPECT_THAT(callback2.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013610
bnc691fda62016-08-12 00:43:163611 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233612 ASSERT_TRUE(response);
3613 ASSERT_TRUE(response->headers);
3614 EXPECT_TRUE(response->headers->IsKeepAlive());
3615 EXPECT_EQ(407, response->headers->response_code());
3616 EXPECT_EQ(10, response->headers->GetContentLength());
3617 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3618 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013619
mmenked39192ee2015-12-09 00:57:233620 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3621 // out of scope.
3622 session->CloseAllConnections();
3623 }
ttuttle34f63b52015-03-05 04:33:013624}
3625
3626// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3627// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013628TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
mmenked39192ee2015-12-09 00:57:233629 // On the second pass, the body read of the auth challenge is synchronous, so
3630 // IsConnectedAndIdle returns false. The socket should still be drained and
3631 // reused. See http://crbug.com/544255.
3632 for (int i = 0; i < 2; ++i) {
3633 HttpRequestInfo request;
3634 request.method = "GET";
3635 request.url = GURL("https://www.example.org/");
3636 // Ensure that proxy authentication is attempted even
3637 // when the no authentication data flag is set.
3638 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103639 request.traffic_annotation =
3640 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenked39192ee2015-12-09 00:57:233641
3642 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593643 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493644 ProxyResolutionService::CreateFixed("myproxy:70",
3645 TRAFFIC_ANNOTATION_FOR_TESTS);
mmenked39192ee2015-12-09 00:57:233646 BoundTestNetLog log;
3647 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093648 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenked39192ee2015-12-09 00:57:233649
bnc691fda62016-08-12 00:43:163650 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenked39192ee2015-12-09 00:57:233651
3652 // Since we have proxy, should try to establish tunnel.
3653 MockWrite data_writes1[] = {
3654 MockWrite(ASYNC, 0,
3655 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3656 "Host: www.example.org:443\r\n"
3657 "Proxy-Connection: keep-alive\r\n\r\n"),
3658
bnc691fda62016-08-12 00:43:163659 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233660 // be issuing -- the final header line contains the credentials.
3661 MockWrite(ASYNC, 3,
3662 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3663 "Host: www.example.org:443\r\n"
3664 "Proxy-Connection: keep-alive\r\n"
3665 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3666 };
3667
3668 // The proxy responds to the connect with a 407, using a persistent
3669 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3670 MockRead data_reads1[] = {
3671 // No credentials.
3672 MockRead(ASYNC, 1,
3673 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3674 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3675 "Content-Length: 10\r\n\r\n"),
3676 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
3677
3678 // Wrong credentials (wrong password).
3679 MockRead(ASYNC, 4,
3680 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3681 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3682 "Content-Length: 10\r\n\r\n"),
3683 // No response body because the test stops reading here.
3684 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3685 };
3686
Ryan Sleevib8d7ea02018-05-07 20:01:013687 SequencedSocketData data1(data_reads1, data_writes1);
mmenked39192ee2015-12-09 00:57:233688 data1.set_busy_before_sync_reads(true);
3689 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3690
3691 TestCompletionCallback callback1;
3692
bnc691fda62016-08-12 00:43:163693 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013694 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233695
3696 TestNetLogEntry::List entries;
3697 log.GetEntries(&entries);
3698 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003699 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3700 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233701 ExpectLogContainsSomewhere(
3702 entries, pos,
mikecirone8b85c432016-09-08 19:11:003703 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3704 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233705
bnc691fda62016-08-12 00:43:163706 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233707 ASSERT_TRUE(response);
3708 ASSERT_TRUE(response->headers);
3709 EXPECT_TRUE(response->headers->IsKeepAlive());
3710 EXPECT_EQ(407, response->headers->response_code());
3711 EXPECT_EQ(10, response->headers->GetContentLength());
3712 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3713 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3714
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()));
3730
3731 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3732 // out of scope.
3733 session->CloseAllConnections();
3734 }
3735}
3736
3737// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3738// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel, in
3739// the case the server sends extra data on the original socket, so it can't be
3740// reused.
bncd16676a2016-07-20 16:23:013741TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveExtraData) {
[email protected]cb9bf6ca2011-01-28 13:15:273742 HttpRequestInfo request;
3743 request.method = "GET";
bncce36dca22015-04-21 22:11:233744 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273745 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293746 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103747 request.traffic_annotation =
3748 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:273749
[email protected]2d2697f92009-02-18 21:00:323750 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593751 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493752 ProxyResolutionService::CreateFixedFromPacResult(
3753 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513754 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073755 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093756 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:323757
[email protected]2d2697f92009-02-18 21:00:323758 // Since we have proxy, should try to establish tunnel.
3759 MockWrite data_writes1[] = {
mmenked39192ee2015-12-09 00:57:233760 MockWrite(ASYNC, 0,
3761 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173762 "Host: www.example.org:443\r\n"
3763 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233764 };
[email protected]2d2697f92009-02-18 21:00:323765
mmenked39192ee2015-12-09 00:57:233766 // The proxy responds to the connect with a 407, using a persistent, but sends
3767 // extra data, so the socket cannot be reused.
3768 MockRead data_reads1[] = {
3769 // No credentials.
3770 MockRead(ASYNC, 1,
3771 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3772 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3773 "Content-Length: 10\r\n\r\n"),
3774 MockRead(SYNCHRONOUS, 2, "0123456789"),
3775 MockRead(SYNCHRONOUS, 3, "I'm broken!"),
3776 };
3777
3778 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:233779 // After calling trans->RestartWithAuth(), this is the request we should
3780 // be issuing -- the final header line contains the credentials.
mmenked39192ee2015-12-09 00:57:233781 MockWrite(ASYNC, 0,
3782 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173783 "Host: www.example.org:443\r\n"
3784 "Proxy-Connection: keep-alive\r\n"
mmenked39192ee2015-12-09 00:57:233785 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3786
3787 MockWrite(ASYNC, 2,
3788 "GET / HTTP/1.1\r\n"
3789 "Host: www.example.org\r\n"
3790 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323791 };
3792
mmenked39192ee2015-12-09 00:57:233793 MockRead data_reads2[] = {
3794 MockRead(ASYNC, 1, "HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323795
mmenked39192ee2015-12-09 00:57:233796 MockRead(ASYNC, 3,
3797 "HTTP/1.1 200 OK\r\n"
3798 "Content-Type: text/html; charset=iso-8859-1\r\n"
3799 "Content-Length: 5\r\n\r\n"),
3800 // No response body because the test stops reading here.
3801 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 4),
[email protected]2d2697f92009-02-18 21:00:323802 };
3803
Ryan Sleevib8d7ea02018-05-07 20:01:013804 SequencedSocketData data1(data_reads1, data_writes1);
mmenked39192ee2015-12-09 00:57:233805 data1.set_busy_before_sync_reads(true);
[email protected]bb88e1d32013-05-03 23:11:073806 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:013807 SequencedSocketData data2(data_reads2, data_writes2);
mmenked39192ee2015-12-09 00:57:233808 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3809 SSLSocketDataProvider ssl(ASYNC, OK);
3810 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d2697f92009-02-18 21:00:323811
[email protected]49639fa2011-12-20 23:22:413812 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323813
bnc87dcefc2017-05-25 12:47:583814 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193815 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d2697f92009-02-18 21:00:323816
mmenked39192ee2015-12-09 00:57:233817 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013818 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233819
mmenke43758e62015-05-04 21:09:463820 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403821 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:393822 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003823 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3824 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:393825 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403826 entries, pos,
mikecirone8b85c432016-09-08 19:11:003827 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3828 NetLogEventPhase::NONE);
[email protected]2d2697f92009-02-18 21:00:323829
[email protected]1c773ea12009-04-28 19:58:423830 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243831 ASSERT_TRUE(response);
3832 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:323833 EXPECT_TRUE(response->headers->IsKeepAlive());
3834 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423835 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043836 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:323837
mmenked39192ee2015-12-09 00:57:233838 LoadTimingInfo load_timing_info;
3839 // CONNECT requests and responses are handled at the connect job level, so
3840 // the transaction does not yet have a connection.
3841 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3842
[email protected]49639fa2011-12-20 23:22:413843 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323844
mmenked39192ee2015-12-09 00:57:233845 rv =
3846 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013847 EXPECT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:323848
[email protected]2d2697f92009-02-18 21:00:323849 EXPECT_TRUE(response->headers->IsKeepAlive());
mmenked39192ee2015-12-09 00:57:233850 EXPECT_EQ(200, response->headers->response_code());
3851 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:423852 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]e772db3f2010-07-12 18:11:133853
mmenked39192ee2015-12-09 00:57:233854 // The password prompt info should not be set.
3855 EXPECT_FALSE(response->auth_challenge);
3856
3857 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3858 TestLoadTimingNotReusedWithPac(load_timing_info,
3859 CONNECT_TIMING_HAS_SSL_TIMES);
3860
3861 trans.reset();
[email protected]102e27c2011-02-23 01:01:313862 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:323863}
3864
mmenkee71e15332015-10-07 16:39:543865// Test the case a proxy closes a socket while the challenge body is being
3866// drained.
bncd16676a2016-07-20 16:23:013867TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHangupDuringBody) {
mmenkee71e15332015-10-07 16:39:543868 HttpRequestInfo request;
3869 request.method = "GET";
3870 request.url = GURL("https://www.example.org/");
3871 // Ensure that proxy authentication is attempted even
3872 // when the no authentication data flag is set.
3873 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103874 request.traffic_annotation =
3875 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenkee71e15332015-10-07 16:39:543876
3877 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:493878 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
3879 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:093880 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenkee71e15332015-10-07 16:39:543881
bnc691fda62016-08-12 00:43:163882 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkee71e15332015-10-07 16:39:543883
3884 // Since we have proxy, should try to establish tunnel.
3885 MockWrite data_writes1[] = {
3886 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173887 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543888 "Proxy-Connection: keep-alive\r\n\r\n"),
3889 };
3890
3891 // The proxy responds to the connect with a 407, using a persistent
3892 // connection.
3893 MockRead data_reads1[] = {
3894 // No credentials.
3895 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3896 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3897 MockRead("Content-Length: 10\r\n\r\n"), MockRead("spam!"),
3898 // Server hands up in the middle of the body.
3899 MockRead(ASYNC, ERR_CONNECTION_CLOSED),
3900 };
3901
3902 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:163903 // After calling trans.RestartWithAuth(), this is the request we should
mmenkee71e15332015-10-07 16:39:543904 // be issuing -- the final header line contains the credentials.
3905 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173906 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543907 "Proxy-Connection: keep-alive\r\n"
3908 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3909
3910 MockWrite("GET / HTTP/1.1\r\n"
3911 "Host: www.example.org\r\n"
3912 "Connection: keep-alive\r\n\r\n"),
3913 };
3914
3915 MockRead data_reads2[] = {
3916 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3917
3918 MockRead("HTTP/1.1 200 OK\r\n"),
3919 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3920 MockRead("Content-Length: 5\r\n\r\n"),
3921 MockRead(SYNCHRONOUS, "hello"),
3922 };
3923
Ryan Sleevib8d7ea02018-05-07 20:01:013924 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenkee71e15332015-10-07 16:39:543925 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:013926 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenkee71e15332015-10-07 16:39:543927 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3928 SSLSocketDataProvider ssl(ASYNC, OK);
3929 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3930
3931 TestCompletionCallback callback;
3932
tfarina42834112016-09-22 13:38:203933 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013934 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543935
bnc691fda62016-08-12 00:43:163936 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543937 ASSERT_TRUE(response);
3938 ASSERT_TRUE(response->headers);
3939 EXPECT_TRUE(response->headers->IsKeepAlive());
3940 EXPECT_EQ(407, response->headers->response_code());
3941 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3942
bnc691fda62016-08-12 00:43:163943 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
robpercival214763f2016-07-01 23:27:013944 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543945
bnc691fda62016-08-12 00:43:163946 response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543947 ASSERT_TRUE(response);
3948 ASSERT_TRUE(response->headers);
3949 EXPECT_TRUE(response->headers->IsKeepAlive());
3950 EXPECT_EQ(200, response->headers->response_code());
3951 std::string body;
bnc691fda62016-08-12 00:43:163952 EXPECT_THAT(ReadTransaction(&trans, &body), IsOk());
mmenkee71e15332015-10-07 16:39:543953 EXPECT_EQ("hello", body);
3954}
3955
[email protected]a8e9b162009-03-12 00:06:443956// Test that we don't read the response body when we fail to establish a tunnel,
3957// even if the user cancels the proxy's auth attempt.
bncd16676a2016-07-20 16:23:013958TEST_F(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:273959 HttpRequestInfo request;
3960 request.method = "GET";
bncce36dca22015-04-21 22:11:233961 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:103962 request.traffic_annotation =
3963 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:273964
[email protected]a8e9b162009-03-12 00:06:443965 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:493966 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
3967 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]a8e9b162009-03-12 00:06:443968
danakj1fd259a02016-04-16 03:17:093969 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:443970
bnc691fda62016-08-12 00:43:163971 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a8e9b162009-03-12 00:06:443972
[email protected]a8e9b162009-03-12 00:06:443973 // Since we have proxy, should try to establish tunnel.
3974 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173975 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3976 "Host: www.example.org:443\r\n"
3977 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:443978 };
3979
3980 // The proxy responds to the connect with a 407.
3981 MockRead data_reads[] = {
ttuttle7933c112015-01-06 00:55:243982 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3983 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3984 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233985 MockRead("0123456789"),
ttuttle7933c112015-01-06 00:55:243986 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]a8e9b162009-03-12 00:06:443987 };
3988
Ryan Sleevib8d7ea02018-05-07 20:01:013989 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:073990 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:443991
[email protected]49639fa2011-12-20 23:22:413992 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:443993
tfarina42834112016-09-22 13:38:203994 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013995 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a8e9b162009-03-12 00:06:443996
3997 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013998 EXPECT_THAT(rv, IsOk());
[email protected]a8e9b162009-03-12 00:06:443999
bnc691fda62016-08-12 00:43:164000 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:244001 ASSERT_TRUE(response);
4002 ASSERT_TRUE(response->headers);
[email protected]a8e9b162009-03-12 00:06:444003 EXPECT_TRUE(response->headers->IsKeepAlive());
4004 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:424005 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:444006
4007 std::string response_data;
bnc691fda62016-08-12 00:43:164008 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:014009 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]e60e47a2010-07-14 03:37:184010
4011 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:314012 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:444013}
4014
ttuttle7933c112015-01-06 00:55:244015// Test that we don't pass extraneous headers from the proxy's response to the
4016// caller when the proxy responds to CONNECT with 407.
bncd16676a2016-07-20 16:23:014017TEST_F(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
ttuttle7933c112015-01-06 00:55:244018 HttpRequestInfo request;
4019 request.method = "GET";
bncce36dca22015-04-21 22:11:234020 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104021 request.traffic_annotation =
4022 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle7933c112015-01-06 00:55:244023
4024 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:494025 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
4026 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle7933c112015-01-06 00:55:244027
danakj1fd259a02016-04-16 03:17:094028 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle7933c112015-01-06 00:55:244029
bnc691fda62016-08-12 00:43:164030 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle7933c112015-01-06 00:55:244031
4032 // Since we have proxy, should try to establish tunnel.
4033 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:174034 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4035 "Host: www.example.org:443\r\n"
4036 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle7933c112015-01-06 00:55:244037 };
4038
4039 // The proxy responds to the connect with a 407.
4040 MockRead data_reads[] = {
4041 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4042 MockRead("X-Foo: bar\r\n"),
4043 MockRead("Set-Cookie: foo=bar\r\n"),
4044 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4045 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:234046 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
ttuttle7933c112015-01-06 00:55:244047 };
4048
Ryan Sleevib8d7ea02018-05-07 20:01:014049 StaticSocketDataProvider data(data_reads, data_writes);
ttuttle7933c112015-01-06 00:55:244050 session_deps_.socket_factory->AddSocketDataProvider(&data);
4051
4052 TestCompletionCallback callback;
4053
tfarina42834112016-09-22 13:38:204054 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014055 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle7933c112015-01-06 00:55:244056
4057 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:014058 EXPECT_THAT(rv, IsOk());
ttuttle7933c112015-01-06 00:55:244059
bnc691fda62016-08-12 00:43:164060 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:244061 ASSERT_TRUE(response);
4062 ASSERT_TRUE(response->headers);
4063 EXPECT_TRUE(response->headers->IsKeepAlive());
4064 EXPECT_EQ(407, response->headers->response_code());
4065 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4066 EXPECT_FALSE(response->headers->HasHeader("X-Foo"));
4067 EXPECT_FALSE(response->headers->HasHeader("Set-Cookie"));
4068
4069 std::string response_data;
bnc691fda62016-08-12 00:43:164070 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:014071 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
ttuttle7933c112015-01-06 00:55:244072
4073 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
4074 session->CloseAllConnections();
4075}
4076
[email protected]8fdbcd22010-05-05 02:54:524077// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
4078// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
bncd16676a2016-07-20 16:23:014079TEST_F(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:524080 HttpRequestInfo request;
4081 request.method = "GET";
bncce36dca22015-04-21 22:11:234082 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104083 request.traffic_annotation =
4084 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8fdbcd22010-05-05 02:54:524085
[email protected]cb9bf6ca2011-01-28 13:15:274086 // We are using a DIRECT connection (i.e. no proxy) for this session.
danakj1fd259a02016-04-16 03:17:094087 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:164088 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:274089
[email protected]8fdbcd22010-05-05 02:54:524090 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:234091 MockWrite(
4092 "GET / HTTP/1.1\r\n"
4093 "Host: www.example.org\r\n"
4094 "Connection: keep-alive\r\n\r\n"),
[email protected]8fdbcd22010-05-05 02:54:524095 };
4096
4097 MockRead data_reads1[] = {
4098 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
4099 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4100 // Large content-length -- won't matter, as connection will be reset.
4101 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064102 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:524103 };
4104
Ryan Sleevib8d7ea02018-05-07 20:01:014105 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:074106 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:524107
[email protected]49639fa2011-12-20 23:22:414108 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:524109
tfarina42834112016-09-22 13:38:204110 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014111 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8fdbcd22010-05-05 02:54:524112
4113 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:014114 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
[email protected]8fdbcd22010-05-05 02:54:524115}
4116
[email protected]7a67a8152010-11-05 18:31:104117// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
4118// through a non-authenticating proxy. The request should fail with
4119// ERR_UNEXPECTED_PROXY_AUTH.
4120// Note that it is impossible to detect if an HTTP server returns a 407 through
4121// a non-authenticating proxy - there is nothing to indicate whether the
4122// response came from the proxy or the server, so it is treated as if the proxy
4123// issued the challenge.
bncd16676a2016-07-20 16:23:014124TEST_F(HttpNetworkTransactionTest, HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:274125 HttpRequestInfo request;
4126 request.method = "GET";
bncce36dca22015-04-21 22:11:234127 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104128 request.traffic_annotation =
4129 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:274130
Ramin Halavatica8d5252018-03-12 05:33:494131 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
4132 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:514133 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074134 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094135 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:104136
[email protected]7a67a8152010-11-05 18:31:104137 // Since we have proxy, should try to establish tunnel.
4138 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174139 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4140 "Host: www.example.org:443\r\n"
4141 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:104142
rsleevidb16bb02015-11-12 23:47:174143 MockWrite("GET / HTTP/1.1\r\n"
4144 "Host: www.example.org\r\n"
4145 "Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:104146 };
4147
4148 MockRead data_reads1[] = {
4149 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4150
4151 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
4152 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4153 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:064154 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:104155 };
4156
Ryan Sleevib8d7ea02018-05-07 20:01:014157 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:074158 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:064159 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074160 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:104161
[email protected]49639fa2011-12-20 23:22:414162 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:104163
bnc691fda62016-08-12 00:43:164164 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]7a67a8152010-11-05 18:31:104165
bnc691fda62016-08-12 00:43:164166 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014167 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a67a8152010-11-05 18:31:104168
4169 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014170 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
mmenke43758e62015-05-04 21:09:464171 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:404172 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:104173 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:004174 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
4175 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:104176 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:404177 entries, pos,
mikecirone8b85c432016-09-08 19:11:004178 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
4179 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:104180}
[email protected]2df19bb2010-08-25 20:13:464181
mmenke2a1781d2015-10-07 19:25:334182// Test a proxy auth scheme that allows default credentials and a proxy server
4183// that uses non-persistent connections.
bncd16676a2016-07-20 16:23:014184TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334185 AuthAllowsDefaultCredentialsTunnelConnectionClose) {
4186 HttpRequestInfo request;
4187 request.method = "GET";
4188 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104189 request.traffic_annotation =
4190 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334191
4192 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594193 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494194 ProxyResolutionService::CreateFixedFromPacResult(
4195 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334196
Jeremy Roman0579ed62017-08-29 15:56:194197 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334198 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194199 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334200 mock_handler->set_allows_default_credentials(true);
4201 auth_handler_factory->AddMockHandler(mock_handler.release(),
4202 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484203 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334204
4205 // Add NetLog just so can verify load timing information gets a NetLog ID.
4206 NetLog net_log;
4207 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094208 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334209
4210 // Since we have proxy, should try to establish tunnel.
4211 MockWrite data_writes1[] = {
4212 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174213 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334214 "Proxy-Connection: keep-alive\r\n\r\n"),
4215 };
4216
4217 // The proxy responds to the connect with a 407, using a non-persistent
4218 // connection.
4219 MockRead data_reads1[] = {
4220 // No credentials.
4221 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4222 MockRead("Proxy-Authenticate: Mock\r\n"),
4223 MockRead("Proxy-Connection: close\r\n\r\n"),
4224 };
4225
4226 // Since the first connection couldn't be reused, need to establish another
4227 // once given credentials.
4228 MockWrite data_writes2[] = {
4229 // After calling trans->RestartWithAuth(), this is the request we should
4230 // be issuing -- the final header line contains the credentials.
4231 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174232 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334233 "Proxy-Connection: keep-alive\r\n"
4234 "Proxy-Authorization: auth_token\r\n\r\n"),
4235
4236 MockWrite("GET / HTTP/1.1\r\n"
4237 "Host: www.example.org\r\n"
4238 "Connection: keep-alive\r\n\r\n"),
4239 };
4240
4241 MockRead data_reads2[] = {
4242 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
4243
4244 MockRead("HTTP/1.1 200 OK\r\n"),
4245 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4246 MockRead("Content-Length: 5\r\n\r\n"),
4247 MockRead(SYNCHRONOUS, "hello"),
4248 };
4249
Ryan Sleevib8d7ea02018-05-07 20:01:014250 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke2a1781d2015-10-07 19:25:334251 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:014252 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke2a1781d2015-10-07 19:25:334253 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4254 SSLSocketDataProvider ssl(ASYNC, OK);
4255 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4256
bnc87dcefc2017-05-25 12:47:584257 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194258 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334259
4260 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204261 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014262 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334263
4264 const HttpResponseInfo* response = trans->GetResponseInfo();
4265 ASSERT_TRUE(response);
4266 ASSERT_TRUE(response->headers);
4267 EXPECT_FALSE(response->headers->IsKeepAlive());
4268 EXPECT_EQ(407, response->headers->response_code());
4269 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4270 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
wezca1070932016-05-26 20:30:524271 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:334272
4273 LoadTimingInfo load_timing_info;
4274 // CONNECT requests and responses are handled at the connect job level, so
4275 // the transaction does not yet have a connection.
4276 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4277
4278 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014279 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334280 response = trans->GetResponseInfo();
4281 ASSERT_TRUE(response);
4282 ASSERT_TRUE(response->headers);
4283 EXPECT_TRUE(response->headers->IsKeepAlive());
4284 EXPECT_EQ(200, response->headers->response_code());
4285 EXPECT_EQ(5, response->headers->GetContentLength());
4286 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4287
4288 // The password prompt info should not be set.
4289 EXPECT_FALSE(response->auth_challenge);
4290
4291 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4292 TestLoadTimingNotReusedWithPac(load_timing_info,
4293 CONNECT_TIMING_HAS_SSL_TIMES);
4294
4295 trans.reset();
4296 session->CloseAllConnections();
4297}
4298
4299// Test a proxy auth scheme that allows default credentials and a proxy server
4300// that hangs up when credentials are initially sent.
bncd16676a2016-07-20 16:23:014301TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334302 AuthAllowsDefaultCredentialsTunnelServerClosesConnection) {
4303 HttpRequestInfo request;
4304 request.method = "GET";
4305 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104306 request.traffic_annotation =
4307 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334308
4309 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594310 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494311 ProxyResolutionService::CreateFixedFromPacResult(
4312 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334313
Jeremy Roman0579ed62017-08-29 15:56:194314 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334315 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194316 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334317 mock_handler->set_allows_default_credentials(true);
4318 auth_handler_factory->AddMockHandler(mock_handler.release(),
4319 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484320 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334321
4322 // Add NetLog just so can verify load timing information gets a NetLog ID.
4323 NetLog net_log;
4324 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094325 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334326
4327 // Should try to establish tunnel.
4328 MockWrite data_writes1[] = {
4329 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174330 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334331 "Proxy-Connection: keep-alive\r\n\r\n"),
4332
4333 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174334 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334335 "Proxy-Connection: keep-alive\r\n"
4336 "Proxy-Authorization: auth_token\r\n\r\n"),
4337 };
4338
4339 // The proxy responds to the connect with a 407, using a non-persistent
4340 // connection.
4341 MockRead data_reads1[] = {
4342 // No credentials.
4343 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4344 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4345 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4346 };
4347
4348 // Since the first connection was closed, need to establish another once given
4349 // credentials.
4350 MockWrite data_writes2[] = {
4351 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174352 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334353 "Proxy-Connection: keep-alive\r\n"
4354 "Proxy-Authorization: auth_token\r\n\r\n"),
4355
4356 MockWrite("GET / HTTP/1.1\r\n"
4357 "Host: www.example.org\r\n"
4358 "Connection: keep-alive\r\n\r\n"),
4359 };
4360
4361 MockRead data_reads2[] = {
4362 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
4363
4364 MockRead("HTTP/1.1 200 OK\r\n"),
4365 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4366 MockRead("Content-Length: 5\r\n\r\n"),
4367 MockRead(SYNCHRONOUS, "hello"),
4368 };
4369
Ryan Sleevib8d7ea02018-05-07 20:01:014370 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke2a1781d2015-10-07 19:25:334371 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:014372 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke2a1781d2015-10-07 19:25:334373 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4374 SSLSocketDataProvider ssl(ASYNC, OK);
4375 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4376
bnc87dcefc2017-05-25 12:47:584377 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194378 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334379
4380 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204381 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014382 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334383
4384 const HttpResponseInfo* response = trans->GetResponseInfo();
4385 ASSERT_TRUE(response);
4386 ASSERT_TRUE(response->headers);
4387 EXPECT_TRUE(response->headers->IsKeepAlive());
4388 EXPECT_EQ(407, response->headers->response_code());
4389 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4390 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4391 EXPECT_FALSE(response->auth_challenge);
4392
4393 LoadTimingInfo load_timing_info;
4394 // CONNECT requests and responses are handled at the connect job level, so
4395 // the transaction does not yet have a connection.
4396 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4397
4398 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014399 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334400
4401 response = trans->GetResponseInfo();
4402 ASSERT_TRUE(response);
4403 ASSERT_TRUE(response->headers);
4404 EXPECT_TRUE(response->headers->IsKeepAlive());
4405 EXPECT_EQ(200, response->headers->response_code());
4406 EXPECT_EQ(5, response->headers->GetContentLength());
4407 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4408
4409 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524410 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:334411
4412 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4413 TestLoadTimingNotReusedWithPac(load_timing_info,
4414 CONNECT_TIMING_HAS_SSL_TIMES);
4415
4416 trans.reset();
4417 session->CloseAllConnections();
4418}
4419
4420// Test a proxy auth scheme that allows default credentials and a proxy server
4421// that hangs up when credentials are initially sent, and hangs up again when
4422// they are retried.
bncd16676a2016-07-20 16:23:014423TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334424 AuthAllowsDefaultCredentialsTunnelServerClosesConnectionTwice) {
4425 HttpRequestInfo request;
4426 request.method = "GET";
4427 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104428 request.traffic_annotation =
4429 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334430
4431 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594432 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494433 ProxyResolutionService::CreateFixedFromPacResult(
4434 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334435
Jeremy Roman0579ed62017-08-29 15:56:194436 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334437 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194438 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334439 mock_handler->set_allows_default_credentials(true);
4440 auth_handler_factory->AddMockHandler(mock_handler.release(),
4441 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484442 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334443
4444 // Add NetLog just so can verify load timing information gets a NetLog ID.
4445 NetLog net_log;
4446 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094447 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334448
4449 // Should try to establish tunnel.
4450 MockWrite data_writes1[] = {
4451 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174452 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334453 "Proxy-Connection: keep-alive\r\n\r\n"),
4454
4455 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174456 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334457 "Proxy-Connection: keep-alive\r\n"
4458 "Proxy-Authorization: auth_token\r\n\r\n"),
4459 };
4460
4461 // The proxy responds to the connect with a 407, and then hangs up after the
4462 // second request is sent.
4463 MockRead data_reads1[] = {
4464 // No credentials.
4465 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4466 MockRead("Content-Length: 0\r\n"),
4467 MockRead("Proxy-Connection: keep-alive\r\n"),
4468 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4469 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4470 };
4471
4472 // HttpNetworkTransaction sees a reused connection that was closed with
4473 // ERR_CONNECTION_CLOSED, realized it might have been a race, so retries the
4474 // request.
4475 MockWrite data_writes2[] = {
4476 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174477 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334478 "Proxy-Connection: keep-alive\r\n\r\n"),
4479 };
4480
4481 // The proxy, having had more than enough of us, just hangs up.
4482 MockRead data_reads2[] = {
4483 // No credentials.
4484 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4485 };
4486
Ryan Sleevib8d7ea02018-05-07 20:01:014487 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke2a1781d2015-10-07 19:25:334488 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:014489 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke2a1781d2015-10-07 19:25:334490 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4491
bnc87dcefc2017-05-25 12:47:584492 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194493 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334494
4495 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204496 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014497 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334498
4499 const HttpResponseInfo* response = trans->GetResponseInfo();
4500 ASSERT_TRUE(response);
4501 ASSERT_TRUE(response->headers);
4502 EXPECT_TRUE(response->headers->IsKeepAlive());
4503 EXPECT_EQ(407, response->headers->response_code());
4504 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4505 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4506 EXPECT_FALSE(response->auth_challenge);
4507
4508 LoadTimingInfo load_timing_info;
4509 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4510
4511 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014512 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_EMPTY_RESPONSE));
mmenke2a1781d2015-10-07 19:25:334513
4514 trans.reset();
4515 session->CloseAllConnections();
4516}
4517
Asanka Herathbc3f8f62018-11-16 23:08:304518// This test exercises an odd edge case where the proxy closes the connection
4519// after the authentication handshake is complete. Presumably this technique is
4520// used in lieu of returning a 403 or 5xx status code when the authentication
4521// succeeds, but the user is not authorized to connect to the destination
4522// server. There's no standard for what a proxy should do to indicate a blocked
4523// site.
4524TEST_F(HttpNetworkTransactionTest,
4525 AuthAllowsDefaultCredentialsTunnelConnectionClosesBeforeBody) {
4526 HttpRequestInfo request;
4527 request.method = "GET";
4528 request.url = GURL("https://www.example.org/");
4529 request.traffic_annotation =
4530 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4531
4532 // Configure against proxy server "myproxy:70".
4533 session_deps_.proxy_resolution_service =
4534 ProxyResolutionService::CreateFixedFromPacResult(
4535 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
4536
Steven Valdez0ef94d02018-11-19 23:28:134537 // When TLS 1.3 is enabled, spurious connections are made as part of the SSL
4538 // version interference probes.
4539 // TODO(crbug.com/906668): Correctly handle version interference probes to
4540 // test TLS 1.3.
4541 SSLConfig config;
4542 config.version_max = SSL_PROTOCOL_VERSION_TLS1_2;
4543 session_deps_.ssl_config_service =
4544 std::make_unique<TestSSLConfigService>(config);
4545
Asanka Herathbc3f8f62018-11-16 23:08:304546 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
4547 auth_handler_factory->set_do_init_from_challenge(true);
4548
4549 // Create two mock AuthHandlers. This is because the transaction gets retried
4550 // after the first ERR_CONNECTION_CLOSED since it's ambiguous whether there
4551 // was a real network error.
4552 //
4553 // The handlers support both default and explicit credentials. The retry
4554 // mentioned above should be able to reuse the default identity. Thus there
4555 // should never be a need to prompt for explicit credentials.
4556 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
4557 mock_handler->set_allows_default_credentials(true);
4558 mock_handler->set_allows_explicit_credentials(true);
4559 mock_handler->set_connection_based(true);
4560 auth_handler_factory->AddMockHandler(mock_handler.release(),
4561 HttpAuth::AUTH_PROXY);
4562 mock_handler = std::make_unique<HttpAuthHandlerMock>();
4563 mock_handler->set_allows_default_credentials(true);
4564 mock_handler->set_allows_explicit_credentials(true);
4565 mock_handler->set_connection_based(true);
4566 auth_handler_factory->AddMockHandler(mock_handler.release(),
4567 HttpAuth::AUTH_PROXY);
4568 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
4569
4570 NetLog net_log;
4571 session_deps_.net_log = &net_log;
4572 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4573
4574 // Data for both sockets.
4575 //
4576 // Writes are for the tunnel establishment attempts and the
4577 // authentication handshake.
4578 MockWrite data_writes1[] = {
4579 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4580 "Host: www.example.org:443\r\n"
4581 "Proxy-Connection: keep-alive\r\n\r\n"),
4582
4583 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4584 "Host: www.example.org:443\r\n"
4585 "Proxy-Connection: keep-alive\r\n"
4586 "Proxy-Authorization: auth_token\r\n\r\n"),
4587
4588 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4589 "Host: www.example.org:443\r\n"
4590 "Proxy-Connection: keep-alive\r\n"
4591 "Proxy-Authorization: auth_token\r\n\r\n"),
4592 };
4593
4594 // The server side of the authentication handshake. Note that the response to
4595 // the final CONNECT request is ERR_CONNECTION_CLOSED.
4596 MockRead data_reads1[] = {
4597 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4598 MockRead("Content-Length: 0\r\n"),
4599 MockRead("Proxy-Connection: keep-alive\r\n"),
4600 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4601
4602 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4603 MockRead("Content-Length: 0\r\n"),
4604 MockRead("Proxy-Connection: keep-alive\r\n"),
4605 MockRead("Proxy-Authenticate: Mock foo\r\n\r\n"),
4606
4607 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4608 };
4609
4610 StaticSocketDataProvider data1(data_reads1, data_writes1);
4611 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4612
4613 // The second socket is for the reconnection attempt. Data is identical to the
4614 // first attempt.
4615 StaticSocketDataProvider data2(data_reads1, data_writes1);
4616 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4617
4618 auto trans =
4619 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
4620
4621 TestCompletionCallback callback;
4622 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4623
4624 // Two rounds per handshake. After one retry, the error is propagated up the
4625 // stack.
4626 for (int i = 0; i < 4; ++i) {
4627 EXPECT_THAT(callback.GetResult(rv), IsOk());
4628
4629 const HttpResponseInfo* response = trans->GetResponseInfo();
4630 ASSERT_TRUE(response);
4631 ASSERT_TRUE(response->headers);
4632 EXPECT_EQ(407, response->headers->response_code());
4633 ASSERT_TRUE(trans->IsReadyToRestartForAuth());
4634
4635 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4636 }
4637
4638 // One shall be the number thou shalt retry, and the number of the retrying
4639 // shall be one. Two shalt thou not retry, neither retry thou zero, excepting
4640 // that thou then proceed to one. Three is right out. Once the number one,
4641 // being the first number, be reached, then lobbest thou thy
4642 // ERR_CONNECTION_CLOSED towards they network transaction, who shall snuff it.
4643 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.GetResult(rv));
4644
4645 trans.reset();
4646 session->CloseAllConnections();
4647}
4648
mmenke2a1781d2015-10-07 19:25:334649// Test a proxy auth scheme that allows default credentials and a proxy server
4650// that hangs up when credentials are initially sent, and sends a challenge
4651// again they are retried.
bncd16676a2016-07-20 16:23:014652TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334653 AuthAllowsDefaultCredentialsTunnelServerChallengesTwice) {
4654 HttpRequestInfo request;
4655 request.method = "GET";
4656 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104657 request.traffic_annotation =
4658 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334659
4660 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594661 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494662 ProxyResolutionService::CreateFixedFromPacResult(
4663 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334664
Jeremy Roman0579ed62017-08-29 15:56:194665 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334666 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194667 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334668 mock_handler->set_allows_default_credentials(true);
4669 auth_handler_factory->AddMockHandler(mock_handler.release(),
4670 HttpAuth::AUTH_PROXY);
4671 // Add another handler for the second challenge. It supports default
4672 // credentials, but they shouldn't be used, since they were already tried.
Jeremy Roman0579ed62017-08-29 15:56:194673 mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334674 mock_handler->set_allows_default_credentials(true);
4675 auth_handler_factory->AddMockHandler(mock_handler.release(),
4676 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484677 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334678
4679 // Add NetLog just so can verify load timing information gets a NetLog ID.
4680 NetLog net_log;
4681 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094682 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334683
4684 // Should try to establish tunnel.
4685 MockWrite data_writes1[] = {
4686 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174687 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334688 "Proxy-Connection: keep-alive\r\n\r\n"),
4689 };
4690
4691 // The proxy responds to the connect with a 407, using a non-persistent
4692 // connection.
4693 MockRead data_reads1[] = {
4694 // No credentials.
4695 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4696 MockRead("Proxy-Authenticate: Mock\r\n"),
4697 MockRead("Proxy-Connection: close\r\n\r\n"),
4698 };
4699
4700 // Since the first connection was closed, need to establish another once given
4701 // credentials.
4702 MockWrite data_writes2[] = {
4703 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174704 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334705 "Proxy-Connection: keep-alive\r\n"
4706 "Proxy-Authorization: auth_token\r\n\r\n"),
4707 };
4708
4709 MockRead data_reads2[] = {
4710 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4711 MockRead("Proxy-Authenticate: Mock\r\n"),
4712 MockRead("Proxy-Connection: close\r\n\r\n"),
4713 };
4714
Ryan Sleevib8d7ea02018-05-07 20:01:014715 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke2a1781d2015-10-07 19:25:334716 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:014717 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke2a1781d2015-10-07 19:25:334718 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4719 SSLSocketDataProvider ssl(ASYNC, OK);
4720 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4721
bnc87dcefc2017-05-25 12:47:584722 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194723 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334724
4725 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204726 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014727 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334728
4729 const HttpResponseInfo* response = trans->GetResponseInfo();
4730 ASSERT_TRUE(response);
4731 ASSERT_TRUE(response->headers);
4732 EXPECT_EQ(407, response->headers->response_code());
4733 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4734 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4735 EXPECT_FALSE(response->auth_challenge);
4736
4737 LoadTimingInfo load_timing_info;
4738 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4739
4740 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014741 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334742 response = trans->GetResponseInfo();
4743 ASSERT_TRUE(response);
4744 ASSERT_TRUE(response->headers);
4745 EXPECT_EQ(407, response->headers->response_code());
4746 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4747 EXPECT_TRUE(response->auth_challenge);
4748
4749 trans.reset();
4750 session->CloseAllConnections();
4751}
4752
asankae2257db2016-10-11 22:03:164753// A more nuanced test than GenerateAuthToken test which asserts that
4754// ERR_INVALID_AUTH_CREDENTIALS does not cause the auth scheme to be
4755// unnecessarily invalidated, and that if the server co-operates, the
4756// authentication handshake can continue with the same scheme but with a
4757// different identity.
4758TEST_F(HttpNetworkTransactionTest, NonPermanentGenerateAuthTokenError) {
4759 HttpRequestInfo request;
4760 request.method = "GET";
4761 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104762 request.traffic_annotation =
4763 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
asankae2257db2016-10-11 22:03:164764
Jeremy Roman0579ed62017-08-29 15:56:194765 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
asankae2257db2016-10-11 22:03:164766 auth_handler_factory->set_do_init_from_challenge(true);
4767
4768 // First handler. Uses default credentials, but barfs at generate auth token.
Jeremy Roman0579ed62017-08-29 15:56:194769 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164770 mock_handler->set_allows_default_credentials(true);
4771 mock_handler->set_allows_explicit_credentials(true);
4772 mock_handler->set_connection_based(true);
4773 mock_handler->SetGenerateExpectation(true, ERR_INVALID_AUTH_CREDENTIALS);
4774 auth_handler_factory->AddMockHandler(mock_handler.release(),
4775 HttpAuth::AUTH_SERVER);
4776
4777 // Add another handler for the second challenge. It supports default
4778 // credentials, but they shouldn't be used, since they were already tried.
Jeremy Roman0579ed62017-08-29 15:56:194779 mock_handler = std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164780 mock_handler->set_allows_default_credentials(true);
4781 mock_handler->set_allows_explicit_credentials(true);
4782 mock_handler->set_connection_based(true);
4783 auth_handler_factory->AddMockHandler(mock_handler.release(),
4784 HttpAuth::AUTH_SERVER);
4785 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
4786
4787 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4788
4789 MockWrite data_writes1[] = {
4790 MockWrite("GET / HTTP/1.1\r\n"
4791 "Host: www.example.org\r\n"
4792 "Connection: keep-alive\r\n\r\n"),
4793 };
4794
4795 MockRead data_reads1[] = {
4796 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4797 "WWW-Authenticate: Mock\r\n"
4798 "Connection: keep-alive\r\n\r\n"),
4799 };
4800
4801 // Identical to data_writes1[]. The AuthHandler encounters a
4802 // ERR_INVALID_AUTH_CREDENTIALS during the GenerateAuthToken stage, so the
4803 // transaction procceds without an authorization header.
4804 MockWrite data_writes2[] = {
4805 MockWrite("GET / HTTP/1.1\r\n"
4806 "Host: www.example.org\r\n"
4807 "Connection: keep-alive\r\n\r\n"),
4808 };
4809
4810 MockRead data_reads2[] = {
4811 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4812 "WWW-Authenticate: Mock\r\n"
4813 "Connection: keep-alive\r\n\r\n"),
4814 };
4815
4816 MockWrite data_writes3[] = {
4817 MockWrite("GET / HTTP/1.1\r\n"
4818 "Host: www.example.org\r\n"
4819 "Connection: keep-alive\r\n"
4820 "Authorization: auth_token\r\n\r\n"),
4821 };
4822
4823 MockRead data_reads3[] = {
4824 MockRead("HTTP/1.1 200 OK\r\n"
4825 "Content-Length: 5\r\n"
4826 "Content-Type: text/plain\r\n"
4827 "Connection: keep-alive\r\n\r\n"
4828 "Hello"),
4829 };
4830
Ryan Sleevib8d7ea02018-05-07 20:01:014831 StaticSocketDataProvider data1(data_reads1, data_writes1);
asankae2257db2016-10-11 22:03:164832 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4833
Ryan Sleevib8d7ea02018-05-07 20:01:014834 StaticSocketDataProvider data2(data_reads2, data_writes2);
asankae2257db2016-10-11 22:03:164835 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4836
Ryan Sleevib8d7ea02018-05-07 20:01:014837 StaticSocketDataProvider data3(data_reads3, data_writes3);
asankae2257db2016-10-11 22:03:164838 session_deps_.socket_factory->AddSocketDataProvider(&data3);
4839
bnc87dcefc2017-05-25 12:47:584840 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194841 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
asankae2257db2016-10-11 22:03:164842
4843 TestCompletionCallback callback;
4844 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4845 EXPECT_THAT(callback.GetResult(rv), IsOk());
4846
4847 const HttpResponseInfo* response = trans->GetResponseInfo();
4848 ASSERT_TRUE(response);
4849 ASSERT_TRUE(response->headers);
4850 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4851
4852 // The following three tests assert that an authentication challenge was
4853 // received and that the stack is ready to respond to the challenge using
4854 // ambient credentials.
4855 EXPECT_EQ(401, response->headers->response_code());
4856 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4857 EXPECT_FALSE(response->auth_challenge);
4858
4859 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4860 EXPECT_THAT(callback.GetResult(rv), IsOk());
4861 response = trans->GetResponseInfo();
4862 ASSERT_TRUE(response);
4863 ASSERT_TRUE(response->headers);
4864
4865 // The following three tests assert that an authentication challenge was
4866 // received and that the stack needs explicit credentials before it is ready
4867 // to respond to the challenge.
4868 EXPECT_EQ(401, response->headers->response_code());
4869 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4870 EXPECT_TRUE(response->auth_challenge);
4871
4872 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4873 EXPECT_THAT(callback.GetResult(rv), IsOk());
4874 response = trans->GetResponseInfo();
4875 ASSERT_TRUE(response);
4876 ASSERT_TRUE(response->headers);
4877 EXPECT_EQ(200, response->headers->response_code());
4878
4879 trans.reset();
4880 session->CloseAllConnections();
4881}
4882
Matt Menked1eb6d42018-01-17 04:54:064883// Proxy resolver that returns a proxy with the same host and port for different
4884// schemes, based on the path of the URL being requests.
4885class SameProxyWithDifferentSchemesProxyResolver : public ProxyResolver {
4886 public:
4887 SameProxyWithDifferentSchemesProxyResolver() {}
4888 ~SameProxyWithDifferentSchemesProxyResolver() override {}
4889
4890 static std::string ProxyHostPortPairAsString() { return "proxy.test:10000"; }
4891
4892 static HostPortPair ProxyHostPortPair() {
4893 return HostPortPair::FromString(ProxyHostPortPairAsString());
4894 }
4895
4896 // ProxyResolver implementation.
4897 int GetProxyForURL(const GURL& url,
4898 ProxyInfo* results,
Bence Békycc5b88a2018-05-25 20:24:174899 CompletionOnceCallback callback,
Matt Menked1eb6d42018-01-17 04:54:064900 std::unique_ptr<Request>* request,
4901 const NetLogWithSource& /*net_log*/) override {
4902 *results = ProxyInfo();
Ramin Halavati921731ea2018-03-16 08:24:574903 results->set_traffic_annotation(
4904 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
Matt Menked1eb6d42018-01-17 04:54:064905 if (url.path() == "/socks4") {
4906 results->UsePacString("SOCKS " + ProxyHostPortPairAsString());
4907 return OK;
4908 }
4909 if (url.path() == "/socks5") {
4910 results->UsePacString("SOCKS5 " + ProxyHostPortPairAsString());
4911 return OK;
4912 }
4913 if (url.path() == "/http") {
4914 results->UsePacString("PROXY " + ProxyHostPortPairAsString());
4915 return OK;
4916 }
4917 if (url.path() == "/https") {
4918 results->UsePacString("HTTPS " + ProxyHostPortPairAsString());
4919 return OK;
4920 }
Matt Menkee8648fa2019-01-17 16:47:074921 if (url.path() == "/https_trusted") {
4922 results->UseProxyServer(ProxyServer(ProxyServer::SCHEME_HTTPS,
4923 ProxyHostPortPair(),
4924 true /* is_trusted_proxy */));
4925 return OK;
4926 }
Matt Menked1eb6d42018-01-17 04:54:064927 NOTREACHED();
4928 return ERR_NOT_IMPLEMENTED;
4929 }
4930
4931 private:
4932 DISALLOW_COPY_AND_ASSIGN(SameProxyWithDifferentSchemesProxyResolver);
4933};
4934
4935class SameProxyWithDifferentSchemesProxyResolverFactory
4936 : public ProxyResolverFactory {
4937 public:
4938 SameProxyWithDifferentSchemesProxyResolverFactory()
4939 : ProxyResolverFactory(false) {}
4940
Lily Houghton99597862018-03-07 16:40:424941 int CreateProxyResolver(const scoped_refptr<PacFileData>& pac_script,
4942 std::unique_ptr<ProxyResolver>* resolver,
Bence Békycc5b88a2018-05-25 20:24:174943 CompletionOnceCallback callback,
Lily Houghton99597862018-03-07 16:40:424944 std::unique_ptr<Request>* request) override {
Matt Menked1eb6d42018-01-17 04:54:064945 *resolver = std::make_unique<SameProxyWithDifferentSchemesProxyResolver>();
4946 return OK;
4947 }
4948
4949 private:
4950 DISALLOW_COPY_AND_ASSIGN(SameProxyWithDifferentSchemesProxyResolverFactory);
4951};
4952
4953// Check that when different proxy schemes are all applied to a proxy at the
Matt Menkee8648fa2019-01-17 16:47:074954// same address, the connections are not grouped together. i.e., a request to
Matt Menked1eb6d42018-01-17 04:54:064955// foo.com using proxy.com as an HTTPS proxy won't use the same socket as a
4956// request to foo.com using proxy.com as an HTTP proxy.
4957TEST_F(HttpNetworkTransactionTest, SameDestinationForDifferentProxyTypes) {
Ramin Halavatica8d5252018-03-12 05:33:494958 session_deps_.proxy_resolution_service =
4959 std::make_unique<ProxyResolutionService>(
4960 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
4961 ProxyConfig::CreateAutoDetect(), TRAFFIC_ANNOTATION_FOR_TESTS)),
4962 std::make_unique<SameProxyWithDifferentSchemesProxyResolverFactory>(),
4963 nullptr);
Matt Menked1eb6d42018-01-17 04:54:064964
4965 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4966
4967 MockWrite socks_writes[] = {
4968 MockWrite(SYNCHRONOUS, kSOCKS4OkRequestLocalHostPort80,
4969 kSOCKS4OkRequestLocalHostPort80Length),
4970 MockWrite(SYNCHRONOUS,
4971 "GET /socks4 HTTP/1.1\r\n"
4972 "Host: test\r\n"
4973 "Connection: keep-alive\r\n\r\n"),
4974 };
4975 MockRead socks_reads[] = {
4976 MockRead(SYNCHRONOUS, kSOCKS4OkReply, kSOCKS4OkReplyLength),
4977 MockRead("HTTP/1.0 200 OK\r\n"
4978 "Connection: keep-alive\r\n"
4979 "Content-Length: 15\r\n\r\n"
4980 "SOCKS4 Response"),
4981 };
Ryan Sleevib8d7ea02018-05-07 20:01:014982 StaticSocketDataProvider socks_data(socks_reads, socks_writes);
Matt Menked1eb6d42018-01-17 04:54:064983 session_deps_.socket_factory->AddSocketDataProvider(&socks_data);
4984
4985 const char kSOCKS5Request[] = {
4986 0x05, // Version
4987 0x01, // Command (CONNECT)
4988 0x00, // Reserved
4989 0x03, // Address type (DOMAINNAME)
4990 0x04, // Length of domain (4)
4991 't', 'e', 's', 't', // Domain string
4992 0x00, 0x50, // 16-bit port (80)
4993 };
4994 MockWrite socks5_writes[] = {
4995 MockWrite(ASYNC, kSOCKS5GreetRequest, kSOCKS5GreetRequestLength),
Avi Drissman4365a4782018-12-28 19:26:244996 MockWrite(ASYNC, kSOCKS5Request, base::size(kSOCKS5Request)),
Matt Menked1eb6d42018-01-17 04:54:064997 MockWrite(SYNCHRONOUS,
4998 "GET /socks5 HTTP/1.1\r\n"
4999 "Host: test\r\n"
5000 "Connection: keep-alive\r\n\r\n"),
5001 };
5002 MockRead socks5_reads[] = {
5003 MockRead(ASYNC, kSOCKS5GreetResponse, kSOCKS5GreetResponseLength),
5004 MockRead(ASYNC, kSOCKS5OkResponse, kSOCKS5OkResponseLength),
5005 MockRead("HTTP/1.0 200 OK\r\n"
5006 "Connection: keep-alive\r\n"
5007 "Content-Length: 15\r\n\r\n"
5008 "SOCKS5 Response"),
5009 };
Ryan Sleevib8d7ea02018-05-07 20:01:015010 StaticSocketDataProvider socks5_data(socks5_reads, socks5_writes);
Matt Menked1eb6d42018-01-17 04:54:065011 session_deps_.socket_factory->AddSocketDataProvider(&socks5_data);
5012
5013 MockWrite http_writes[] = {
5014 MockWrite(SYNCHRONOUS,
5015 "GET http://test/http HTTP/1.1\r\n"
5016 "Host: test\r\n"
5017 "Proxy-Connection: keep-alive\r\n\r\n"),
5018 };
5019 MockRead http_reads[] = {
5020 MockRead("HTTP/1.1 200 OK\r\n"
5021 "Proxy-Connection: keep-alive\r\n"
5022 "Content-Length: 13\r\n\r\n"
5023 "HTTP Response"),
5024 };
Ryan Sleevib8d7ea02018-05-07 20:01:015025 StaticSocketDataProvider http_data(http_reads, http_writes);
Matt Menked1eb6d42018-01-17 04:54:065026 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
5027
5028 MockWrite https_writes[] = {
5029 MockWrite(SYNCHRONOUS,
5030 "GET http://test/https HTTP/1.1\r\n"
5031 "Host: test\r\n"
5032 "Proxy-Connection: keep-alive\r\n\r\n"),
5033 };
5034 MockRead https_reads[] = {
5035 MockRead("HTTP/1.1 200 OK\r\n"
5036 "Proxy-Connection: keep-alive\r\n"
5037 "Content-Length: 14\r\n\r\n"
5038 "HTTPS Response"),
5039 };
Ryan Sleevib8d7ea02018-05-07 20:01:015040 StaticSocketDataProvider https_data(https_reads, https_writes);
Matt Menked1eb6d42018-01-17 04:54:065041 session_deps_.socket_factory->AddSocketDataProvider(&https_data);
5042 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
5043 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5044
Matt Menkee8648fa2019-01-17 16:47:075045 MockWrite https_trusted_writes[] = {
5046 MockWrite(SYNCHRONOUS,
5047 "GET http://test/https_trusted HTTP/1.1\r\n"
5048 "Host: test\r\n"
5049 "Proxy-Connection: keep-alive\r\n\r\n"),
5050 };
5051 MockRead https_trusted_reads[] = {
5052 MockRead("HTTP/1.1 200 OK\r\n"
5053 "Proxy-Connection: keep-alive\r\n"
5054 "Content-Length: 22\r\n\r\n"
5055 "HTTPS Trusted Response"),
5056 };
5057 StaticSocketDataProvider trusted_https_data(https_trusted_reads,
5058 https_trusted_writes);
5059 session_deps_.socket_factory->AddSocketDataProvider(&trusted_https_data);
5060 SSLSocketDataProvider ssl2(SYNCHRONOUS, OK);
5061 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
5062
Matt Menked1eb6d42018-01-17 04:54:065063 struct TestCase {
5064 GURL url;
5065 std::string expected_response;
Matt Menkee8648fa2019-01-17 16:47:075066 // How many idle sockets there should be in the SOCKS 4/5 proxy socket pools
Matt Menked1eb6d42018-01-17 04:54:065067 // after the test.
Matt Menkee8648fa2019-01-17 16:47:075068 int expected_idle_socks4_sockets;
5069 int expected_idle_socks5_sockets;
5070 // How many idle sockets there should be in the HTTP/HTTPS proxy socket
5071 // pools after the test.
Matt Menked1eb6d42018-01-17 04:54:065072 int expected_idle_http_sockets;
Matt Menkee8648fa2019-01-17 16:47:075073 int expected_idle_https_sockets;
5074 // How many idle sockets there should be in the HTTPS proxy socket pool with
5075 // the ProxyServer's |is_trusted_proxy| bit set after the test.
5076 int expected_idle_trusted_https_sockets;
Matt Menked1eb6d42018-01-17 04:54:065077 } const kTestCases[] = {
Matt Menkee8648fa2019-01-17 16:47:075078 {GURL("http://test/socks4"), "SOCKS4 Response", 1, 0, 0, 0, 0},
5079 {GURL("http://test/socks5"), "SOCKS5 Response", 1, 1, 0, 0, 0},
5080 {GURL("http://test/http"), "HTTP Response", 1, 1, 1, 0, 0},
5081 {GURL("http://test/https"), "HTTPS Response", 1, 1, 1, 1, 0},
5082 {GURL("http://test/https_trusted"), "HTTPS Trusted Response", 1, 1, 1, 1,
5083 1},
Matt Menked1eb6d42018-01-17 04:54:065084 };
5085
5086 for (const auto& test_case : kTestCases) {
5087 HttpRequestInfo request;
5088 request.method = "GET";
5089 request.url = test_case.url;
Ramin Halavatib5e433e2018-02-07 07:41:105090 request.traffic_annotation =
5091 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Matt Menked1eb6d42018-01-17 04:54:065092 std::unique_ptr<HttpNetworkTransaction> trans =
5093 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
5094 session.get());
5095 TestCompletionCallback callback;
5096 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
5097 EXPECT_THAT(callback.GetResult(rv), IsOk());
5098
5099 const HttpResponseInfo* response = trans->GetResponseInfo();
5100 ASSERT_TRUE(response);
5101 ASSERT_TRUE(response->headers);
5102 EXPECT_EQ(200, response->headers->response_code());
5103 std::string response_data;
5104 EXPECT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
5105 EXPECT_EQ(test_case.expected_response, response_data);
5106
5107 // Return the socket to the socket pool, so can make sure it's not used for
5108 // the next requests.
5109 trans.reset();
5110 base::RunLoop().RunUntilIdle();
5111
5112 // Check the number of idle sockets in the pool, to make sure that used
5113 // sockets are indeed being returned to the socket pool. If each request
5114 // doesn't return an idle socket to the pool, the test would incorrectly
5115 // pass.
Matt Menkee8648fa2019-01-17 16:47:075116 EXPECT_EQ(test_case.expected_idle_socks4_sockets,
5117 session
Matt Menked23ab952019-03-06 00:24:405118 ->GetSocketPool(
Matt Menkee8648fa2019-01-17 16:47:075119 HttpNetworkSession::NORMAL_SOCKET_POOL,
5120 ProxyServer(ProxyServer::SCHEME_SOCKS4,
5121 SameProxyWithDifferentSchemesProxyResolver::
5122 ProxyHostPortPair()))
5123 ->IdleSocketCount());
5124 EXPECT_EQ(test_case.expected_idle_socks5_sockets,
5125 session
Matt Menked23ab952019-03-06 00:24:405126 ->GetSocketPool(
Matt Menkee8648fa2019-01-17 16:47:075127 HttpNetworkSession::NORMAL_SOCKET_POOL,
5128 ProxyServer(ProxyServer::SCHEME_SOCKS5,
5129 SameProxyWithDifferentSchemesProxyResolver::
5130 ProxyHostPortPair()))
5131 ->IdleSocketCount());
5132 EXPECT_EQ(test_case.expected_idle_http_sockets,
5133 session
Matt Menked23ab952019-03-06 00:24:405134 ->GetSocketPool(
Matt Menkee8648fa2019-01-17 16:47:075135 HttpNetworkSession::NORMAL_SOCKET_POOL,
5136 ProxyServer(ProxyServer::SCHEME_HTTP,
5137 SameProxyWithDifferentSchemesProxyResolver::
5138 ProxyHostPortPair()))
5139 ->IdleSocketCount());
5140 EXPECT_EQ(test_case.expected_idle_https_sockets,
5141 session
Matt Menked23ab952019-03-06 00:24:405142 ->GetSocketPool(
Matt Menkee8648fa2019-01-17 16:47:075143 HttpNetworkSession::NORMAL_SOCKET_POOL,
5144 ProxyServer(ProxyServer::SCHEME_HTTPS,
5145 SameProxyWithDifferentSchemesProxyResolver::
5146 ProxyHostPortPair()))
5147 ->IdleSocketCount());
5148 EXPECT_EQ(test_case.expected_idle_trusted_https_sockets,
5149 session
Matt Menked23ab952019-03-06 00:24:405150 ->GetSocketPool(
Matt Menkee8648fa2019-01-17 16:47:075151 HttpNetworkSession::NORMAL_SOCKET_POOL,
5152 ProxyServer(ProxyServer::SCHEME_HTTPS,
5153 SameProxyWithDifferentSchemesProxyResolver::
5154 ProxyHostPortPair(),
5155 true /* is_trusted_proxy */))
5156 ->IdleSocketCount());
Matt Menked1eb6d42018-01-17 04:54:065157 }
5158}
5159
[email protected]029c83b62013-01-24 05:28:205160// Test the load timing for HTTPS requests with an HTTP proxy.
bncd16676a2016-07-20 16:23:015161TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:205162 HttpRequestInfo request1;
5163 request1.method = "GET";
bncce36dca22015-04-21 22:11:235164 request1.url = GURL("https://www.example.org/1");
Ramin Halavatib5e433e2018-02-07 07:41:105165 request1.traffic_annotation =
5166 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:205167
5168 HttpRequestInfo request2;
5169 request2.method = "GET";
bncce36dca22015-04-21 22:11:235170 request2.url = GURL("https://www.example.org/2");
Ramin Halavatib5e433e2018-02-07 07:41:105171 request2.traffic_annotation =
5172 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:205173
5174 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495175 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5176 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515177 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075178 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095179 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:205180
5181 // Since we have proxy, should try to establish tunnel.
5182 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:175183 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5184 "Host: www.example.org:443\r\n"
5185 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205186
rsleevidb16bb02015-11-12 23:47:175187 MockWrite("GET /1 HTTP/1.1\r\n"
5188 "Host: www.example.org\r\n"
5189 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205190
rsleevidb16bb02015-11-12 23:47:175191 MockWrite("GET /2 HTTP/1.1\r\n"
5192 "Host: www.example.org\r\n"
5193 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205194 };
5195
5196 // The proxy responds to the connect with a 407, using a persistent
5197 // connection.
5198 MockRead data_reads1[] = {
5199 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
5200
5201 MockRead("HTTP/1.1 200 OK\r\n"),
5202 MockRead("Content-Length: 1\r\n\r\n"),
5203 MockRead(SYNCHRONOUS, "1"),
5204
5205 MockRead("HTTP/1.1 200 OK\r\n"),
5206 MockRead("Content-Length: 2\r\n\r\n"),
5207 MockRead(SYNCHRONOUS, "22"),
5208 };
5209
Ryan Sleevib8d7ea02018-05-07 20:01:015210 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:075211 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:205212 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075213 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:205214
5215 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:585216 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:195217 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:205218
5219 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015220 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:205221
5222 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015223 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:205224
5225 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:525226 ASSERT_TRUE(response1);
tbansal2ecbbc72016-10-06 17:15:475227 EXPECT_TRUE(response1->proxy_server.is_http());
wezca1070932016-05-26 20:30:525228 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:205229 EXPECT_EQ(1, response1->headers->GetContentLength());
5230
5231 LoadTimingInfo load_timing_info1;
5232 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
5233 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
5234
5235 trans1.reset();
5236
5237 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:585238 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:195239 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:205240
5241 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015242 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:205243
5244 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015245 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:205246
5247 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:525248 ASSERT_TRUE(response2);
tbansal2ecbbc72016-10-06 17:15:475249 EXPECT_TRUE(response2->proxy_server.is_http());
wezca1070932016-05-26 20:30:525250 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:205251 EXPECT_EQ(2, response2->headers->GetContentLength());
5252
5253 LoadTimingInfo load_timing_info2;
5254 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5255 TestLoadTimingReused(load_timing_info2);
5256
5257 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
5258
5259 trans2.reset();
5260 session->CloseAllConnections();
5261}
5262
5263// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
bncd16676a2016-07-20 16:23:015264TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:205265 HttpRequestInfo request1;
5266 request1.method = "GET";
bncce36dca22015-04-21 22:11:235267 request1.url = GURL("https://www.example.org/1");
Ramin Halavatib5e433e2018-02-07 07:41:105268 request1.traffic_annotation =
5269 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:205270
5271 HttpRequestInfo request2;
5272 request2.method = "GET";
bncce36dca22015-04-21 22:11:235273 request2.url = GURL("https://www.example.org/2");
Ramin Halavatib5e433e2018-02-07 07:41:105274 request2.traffic_annotation =
5275 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:205276
5277 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595278 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:495279 ProxyResolutionService::CreateFixedFromPacResult(
5280 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515281 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075282 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095283 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:205284
5285 // Since we have proxy, should try to establish tunnel.
5286 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:175287 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5288 "Host: www.example.org:443\r\n"
5289 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205290
rsleevidb16bb02015-11-12 23:47:175291 MockWrite("GET /1 HTTP/1.1\r\n"
5292 "Host: www.example.org\r\n"
5293 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205294
rsleevidb16bb02015-11-12 23:47:175295 MockWrite("GET /2 HTTP/1.1\r\n"
5296 "Host: www.example.org\r\n"
5297 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205298 };
5299
5300 // The proxy responds to the connect with a 407, using a persistent
5301 // connection.
5302 MockRead data_reads1[] = {
5303 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
5304
5305 MockRead("HTTP/1.1 200 OK\r\n"),
5306 MockRead("Content-Length: 1\r\n\r\n"),
5307 MockRead(SYNCHRONOUS, "1"),
5308
5309 MockRead("HTTP/1.1 200 OK\r\n"),
5310 MockRead("Content-Length: 2\r\n\r\n"),
5311 MockRead(SYNCHRONOUS, "22"),
5312 };
5313
Ryan Sleevib8d7ea02018-05-07 20:01:015314 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:075315 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:205316 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075317 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:205318
5319 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:585320 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:195321 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:205322
5323 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015324 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:205325
5326 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015327 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:205328
5329 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:525330 ASSERT_TRUE(response1);
5331 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:205332 EXPECT_EQ(1, response1->headers->GetContentLength());
5333
5334 LoadTimingInfo load_timing_info1;
5335 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
5336 TestLoadTimingNotReusedWithPac(load_timing_info1,
5337 CONNECT_TIMING_HAS_SSL_TIMES);
5338
5339 trans1.reset();
5340
5341 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:585342 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:195343 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:205344
5345 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015346 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:205347
5348 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015349 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:205350
5351 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:525352 ASSERT_TRUE(response2);
5353 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:205354 EXPECT_EQ(2, response2->headers->GetContentLength());
5355
5356 LoadTimingInfo load_timing_info2;
5357 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5358 TestLoadTimingReusedWithPac(load_timing_info2);
5359
5360 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
5361
5362 trans2.reset();
5363 session->CloseAllConnections();
5364}
5365
[email protected]2df19bb2010-08-25 20:13:465366// Test a simple get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015367TEST_F(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:275368 HttpRequestInfo request;
5369 request.method = "GET";
bncce36dca22015-04-21 22:11:235370 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105371 request.traffic_annotation =
5372 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275373
[email protected]2df19bb2010-08-25 20:13:465374 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495375 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5376 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515377 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075378 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095379 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:465380
[email protected]2df19bb2010-08-25 20:13:465381 // Since we have proxy, should use full url
5382 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235383 MockWrite(
5384 "GET http://www.example.org/ HTTP/1.1\r\n"
5385 "Host: www.example.org\r\n"
5386 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465387 };
5388
5389 MockRead data_reads1[] = {
5390 MockRead("HTTP/1.1 200 OK\r\n"),
5391 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5392 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065393 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:465394 };
5395
Ryan Sleevib8d7ea02018-05-07 20:01:015396 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:075397 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:065398 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075399 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:465400
[email protected]49639fa2011-12-20 23:22:415401 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:465402
bnc691fda62016-08-12 00:43:165403 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505404
bnc691fda62016-08-12 00:43:165405 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015406 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465407
5408 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015409 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465410
[email protected]58e32bb2013-01-21 18:23:255411 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165412 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255413 TestLoadTimingNotReused(load_timing_info,
5414 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5415
bnc691fda62016-08-12 00:43:165416 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525417 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:465418
tbansal2ecbbc72016-10-06 17:15:475419 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:465420 EXPECT_TRUE(response->headers->IsKeepAlive());
5421 EXPECT_EQ(200, response->headers->response_code());
5422 EXPECT_EQ(100, response->headers->GetContentLength());
5423 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5424
5425 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525426 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:465427}
5428
[email protected]7642b5ae2010-09-01 20:55:175429// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015430TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:275431 HttpRequestInfo request;
5432 request.method = "GET";
bncce36dca22015-04-21 22:11:235433 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105434 request.traffic_annotation =
5435 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275436
[email protected]7642b5ae2010-09-01 20:55:175437 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495438 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5439 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515440 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075441 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095442 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:175443
bncce36dca22015-04-21 22:11:235444 // fetch http://www.example.org/ via SPDY
Ryan Hamilton0239aac2018-05-19 00:03:135445 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:455446 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415447 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]7642b5ae2010-09-01 20:55:175448
Ryan Hamilton0239aac2018-05-19 00:03:135449 spdy::SpdySerializedFrame resp(
5450 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
5451 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:175452 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415453 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]7642b5ae2010-09-01 20:55:175454 };
5455
Ryan Sleevib8d7ea02018-05-07 20:01:015456 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075457 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:175458
[email protected]8ddf8322012-02-23 18:08:065459 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365460 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075461 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:175462
[email protected]49639fa2011-12-20 23:22:415463 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:175464
bnc691fda62016-08-12 00:43:165465 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505466
bnc691fda62016-08-12 00:43:165467 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015468 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7642b5ae2010-09-01 20:55:175469
5470 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015471 EXPECT_THAT(rv, IsOk());
[email protected]7642b5ae2010-09-01 20:55:175472
[email protected]58e32bb2013-01-21 18:23:255473 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165474 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255475 TestLoadTimingNotReused(load_timing_info,
5476 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5477
bnc691fda62016-08-12 00:43:165478 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525479 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:475480 EXPECT_TRUE(response->proxy_server.is_https());
wezca1070932016-05-26 20:30:525481 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025482 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]7642b5ae2010-09-01 20:55:175483
5484 std::string response_data;
bnc691fda62016-08-12 00:43:165485 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235486 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:175487}
5488
[email protected]1c173852014-06-19 12:51:505489// Verifies that a session which races and wins against the owning transaction
5490// (completing prior to host resolution), doesn't fail the transaction.
5491// Regression test for crbug.com/334413.
bncd16676a2016-07-20 16:23:015492TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
[email protected]1c173852014-06-19 12:51:505493 HttpRequestInfo request;
5494 request.method = "GET";
bncce36dca22015-04-21 22:11:235495 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105496 request.traffic_annotation =
5497 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c173852014-06-19 12:51:505498
5499 // Configure SPDY proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495500 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5501 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515502 BoundTestNetLog log;
[email protected]1c173852014-06-19 12:51:505503 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095504 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1c173852014-06-19 12:51:505505
bncce36dca22015-04-21 22:11:235506 // Fetch http://www.example.org/ through the SPDY proxy.
Ryan Hamilton0239aac2018-05-19 00:03:135507 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:455508 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415509 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]1c173852014-06-19 12:51:505510
Raul Tambre94493c652019-03-11 17:18:355511 spdy::SpdySerializedFrame resp(
5512 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135513 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]1c173852014-06-19 12:51:505514 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415515 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]1c173852014-06-19 12:51:505516 };
5517
Ryan Sleevib8d7ea02018-05-07 20:01:015518 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]1c173852014-06-19 12:51:505519 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
5520
5521 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365522 ssl.next_proto = kProtoHTTP2;
[email protected]1c173852014-06-19 12:51:505523 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5524
5525 TestCompletionCallback callback1;
5526
bnc691fda62016-08-12 00:43:165527 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1c173852014-06-19 12:51:505528
5529 // Stall the hostname resolution begun by the transaction.
[email protected]1c173852014-06-19 12:51:505530 session_deps_.host_resolver->set_ondemand_mode(true);
5531
bnc691fda62016-08-12 00:43:165532 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015533 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c173852014-06-19 12:51:505534
5535 // Race a session to the proxy, which completes first.
5536 session_deps_.host_resolver->set_ondemand_mode(false);
Paul Jensena457017a2018-01-19 23:52:045537 SpdySessionKey key(HostPortPair("proxy", 70), ProxyServer::Direct(),
Matt Menke2436b2f2018-12-11 18:07:115538 PRIVACY_MODE_DISABLED,
5539 SpdySessionKey::IsProxySession::kTrue, SocketTag());
[email protected]1c173852014-06-19 12:51:505540 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:525541 CreateSpdySession(session.get(), key, log.bound());
[email protected]1c173852014-06-19 12:51:505542
5543 // Unstall the resolution begun by the transaction.
5544 session_deps_.host_resolver->set_ondemand_mode(true);
5545 session_deps_.host_resolver->ResolveAllPending();
5546
5547 EXPECT_FALSE(callback1.have_result());
5548 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015549 EXPECT_THAT(rv, IsOk());
[email protected]1c173852014-06-19 12:51:505550
bnc691fda62016-08-12 00:43:165551 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525552 ASSERT_TRUE(response);
5553 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025554 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]1c173852014-06-19 12:51:505555
5556 std::string response_data;
bnc691fda62016-08-12 00:43:165557 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]1c173852014-06-19 12:51:505558 EXPECT_EQ(kUploadData, response_data);
5559}
5560
[email protected]dc7bd1c52010-11-12 00:01:135561// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015562TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:275563 HttpRequestInfo request;
5564 request.method = "GET";
bncce36dca22015-04-21 22:11:235565 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105566 request.traffic_annotation =
5567 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275568
[email protected]79cb5c12011-09-12 13:12:045569 // Configure against https proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495570 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5571 "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515572 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075573 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095574 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:135575
[email protected]dc7bd1c52010-11-12 00:01:135576 // The first request will be a bare GET, the second request will be a
5577 // GET with a Proxy-Authorization header.
bncb26024382016-06-29 02:39:455578 spdy_util_.set_default_url(request.url);
Ryan Hamilton0239aac2018-05-19 00:03:135579 spdy::SpdySerializedFrame req_get(
Bence Béky27ad0a12018-02-08 00:35:485580 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:385581 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]dc7bd1c52010-11-12 00:01:135582 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:465583 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:135584 };
Ryan Hamilton0239aac2018-05-19 00:03:135585 spdy::SpdySerializedFrame req_get_authorization(spdy_util_.ConstructSpdyGet(
Avi Drissman4365a4782018-12-28 19:26:245586 kExtraAuthorizationHeaders, base::size(kExtraAuthorizationHeaders) / 2, 3,
Bence Béky27ad0a12018-02-08 00:35:485587 LOWEST));
[email protected]dc7bd1c52010-11-12 00:01:135588 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415589 CreateMockWrite(req_get, 0), CreateMockWrite(req_get_authorization, 3),
[email protected]dc7bd1c52010-11-12 00:01:135590 };
5591
5592 // The first response is a 407 proxy authentication challenge, and the second
5593 // response will be a 200 response since the second request includes a valid
5594 // Authorization header.
5595 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:465596 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:135597 };
Ryan Hamilton0239aac2018-05-19 00:03:135598 spdy::SpdySerializedFrame resp_authentication(
5599 spdy_util_.ConstructSpdyReplyError(
5600 "407", kExtraAuthenticationHeaders,
Avi Drissman4365a4782018-12-28 19:26:245601 base::size(kExtraAuthenticationHeaders) / 2, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135602 spdy::SpdySerializedFrame body_authentication(
bncdf80d44fd2016-07-15 20:27:415603 spdy_util_.ConstructSpdyDataFrame(1, true));
Ryan Hamilton0239aac2018-05-19 00:03:135604 spdy::SpdySerializedFrame resp_data(
Raul Tambre94493c652019-03-11 17:18:355605 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
Ryan Hamilton0239aac2018-05-19 00:03:135606 spdy::SpdySerializedFrame body_data(
5607 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:135608 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415609 CreateMockRead(resp_authentication, 1),
bnceb9aa7112017-01-05 01:03:465610 CreateMockRead(body_authentication, 2, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415611 CreateMockRead(resp_data, 4),
5612 CreateMockRead(body_data, 5),
rch8e6c6c42015-05-01 14:05:135613 MockRead(ASYNC, 0, 6),
[email protected]dc7bd1c52010-11-12 00:01:135614 };
5615
Ryan Sleevib8d7ea02018-05-07 20:01:015616 SequencedSocketData data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075617 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:135618
[email protected]8ddf8322012-02-23 18:08:065619 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365620 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075621 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:135622
[email protected]49639fa2011-12-20 23:22:415623 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:135624
bnc691fda62016-08-12 00:43:165625 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]dc7bd1c52010-11-12 00:01:135626
bnc691fda62016-08-12 00:43:165627 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015628 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:135629
5630 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015631 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:135632
bnc691fda62016-08-12 00:43:165633 const HttpResponseInfo* const response = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:135634
wezca1070932016-05-26 20:30:525635 ASSERT_TRUE(response);
5636 ASSERT_TRUE(response->headers);
[email protected]dc7bd1c52010-11-12 00:01:135637 EXPECT_EQ(407, response->headers->response_code());
5638 EXPECT_TRUE(response->was_fetched_via_spdy);
asanka098c0092016-06-16 20:18:435639 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:135640
[email protected]49639fa2011-12-20 23:22:415641 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:135642
bnc691fda62016-08-12 00:43:165643 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015644 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:135645
5646 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015647 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:135648
bnc691fda62016-08-12 00:43:165649 const HttpResponseInfo* const response_restart = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:135650
wezca1070932016-05-26 20:30:525651 ASSERT_TRUE(response_restart);
5652 ASSERT_TRUE(response_restart->headers);
[email protected]dc7bd1c52010-11-12 00:01:135653 EXPECT_EQ(200, response_restart->headers->response_code());
5654 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525655 EXPECT_FALSE(response_restart->auth_challenge);
[email protected]dc7bd1c52010-11-12 00:01:135656}
5657
[email protected]d9da5fe2010-10-13 22:37:165658// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
bncd16676a2016-07-20 16:23:015659TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:275660 HttpRequestInfo request;
5661 request.method = "GET";
bncce36dca22015-04-21 22:11:235662 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105663 request.traffic_annotation =
5664 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275665
[email protected]d9da5fe2010-10-13 22:37:165666 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495667 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5668 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515669 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075670 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095671 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165672
bnc691fda62016-08-12 00:43:165673 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165674
bncce36dca22015-04-21 22:11:235675 // CONNECT to www.example.org:443 via SPDY
Ryan Hamilton0239aac2018-05-19 00:03:135676 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
Raul Tambre94493c652019-03-11 17:18:355677 nullptr, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncce36dca22015-04-21 22:11:235678 // fetch https://www.example.org/ via HTTP
[email protected]d9da5fe2010-10-13 22:37:165679
bncce36dca22015-04-21 22:11:235680 const char get[] =
5681 "GET / HTTP/1.1\r\n"
5682 "Host: www.example.org\r\n"
5683 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:135684 spdy::SpdySerializedFrame wrapped_get(
Bence Békyd74f4382018-02-20 18:26:195685 spdy_util_.ConstructSpdyDataFrame(1, get, false));
Ryan Hamilton0239aac2018-05-19 00:03:135686 spdy::SpdySerializedFrame conn_resp(
Raul Tambre94493c652019-03-11 17:18:355687 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:165688 const char resp[] = "HTTP/1.1 200 OK\r\n"
5689 "Content-Length: 10\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:135690 spdy::SpdySerializedFrame wrapped_get_resp(
Bence Békyd74f4382018-02-20 18:26:195691 spdy_util_.ConstructSpdyDataFrame(1, resp, false));
Ryan Hamilton0239aac2018-05-19 00:03:135692 spdy::SpdySerializedFrame wrapped_body(
Bence Békyd74f4382018-02-20 18:26:195693 spdy_util_.ConstructSpdyDataFrame(1, "1234567890", false));
Ryan Hamilton0239aac2018-05-19 00:03:135694 spdy::SpdySerializedFrame window_update(
bncdf80d44fd2016-07-15 20:27:415695 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
[email protected]8d2f7012012-02-16 00:08:045696
5697 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415698 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
5699 CreateMockWrite(window_update, 6),
[email protected]8d2f7012012-02-16 00:08:045700 };
5701
[email protected]d9da5fe2010-10-13 22:37:165702 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415703 CreateMockRead(conn_resp, 1, ASYNC),
5704 CreateMockRead(wrapped_get_resp, 3, ASYNC),
5705 CreateMockRead(wrapped_body, 4, ASYNC),
5706 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:135707 MockRead(ASYNC, 0, 7),
[email protected]d9da5fe2010-10-13 22:37:165708 };
5709
Ryan Sleevib8d7ea02018-05-07 20:01:015710 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075711 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165712
[email protected]8ddf8322012-02-23 18:08:065713 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365714 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075715 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065716 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075717 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165718
[email protected]49639fa2011-12-20 23:22:415719 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165720
bnc691fda62016-08-12 00:43:165721 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015722 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165723
5724 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015725 ASSERT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:165726
[email protected]58e32bb2013-01-21 18:23:255727 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165728 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255729 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5730
bnc691fda62016-08-12 00:43:165731 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525732 ASSERT_TRUE(response);
5733 ASSERT_TRUE(response->headers);
[email protected]d9da5fe2010-10-13 22:37:165734 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5735
5736 std::string response_data;
bnc691fda62016-08-12 00:43:165737 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]d9da5fe2010-10-13 22:37:165738 EXPECT_EQ("1234567890", response_data);
5739}
5740
5741// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
bncd16676a2016-07-20 16:23:015742TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
5743 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:385744
[email protected]cb9bf6ca2011-01-28 13:15:275745 HttpRequestInfo request;
5746 request.method = "GET";
bncce36dca22015-04-21 22:11:235747 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105748 request.traffic_annotation =
5749 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275750
[email protected]d9da5fe2010-10-13 22:37:165751 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495752 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5753 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515754 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075755 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095756 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165757
bnc691fda62016-08-12 00:43:165758 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165759
bncce36dca22015-04-21 22:11:235760 // CONNECT to www.example.org:443 via SPDY
Ryan Hamilton0239aac2018-05-19 00:03:135761 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
Raul Tambre94493c652019-03-11 17:18:355762 nullptr, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncce36dca22015-04-21 22:11:235763 // fetch https://www.example.org/ via SPDY
5764 const char kMyUrl[] = "https://www.example.org/";
Ryan Hamilton0239aac2018-05-19 00:03:135765 spdy::SpdySerializedFrame get(
bnc38dcd392016-02-09 23:19:495766 spdy_util_wrapped.ConstructSpdyGet(kMyUrl, 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:135767 spdy::SpdySerializedFrame wrapped_get(
5768 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
5769 spdy::SpdySerializedFrame conn_resp(
Raul Tambre94493c652019-03-11 17:18:355770 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135771 spdy::SpdySerializedFrame get_resp(
Raul Tambre94493c652019-03-11 17:18:355772 spdy_util_wrapped.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135773 spdy::SpdySerializedFrame wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:025774 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135775 spdy::SpdySerializedFrame body(
5776 spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
5777 spdy::SpdySerializedFrame wrapped_body(
[email protected]23e482282013-06-14 16:08:025778 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135779 spdy::SpdySerializedFrame window_update_get_resp(
bncdf80d44fd2016-07-15 20:27:415780 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
Ryan Hamilton0239aac2018-05-19 00:03:135781 spdy::SpdySerializedFrame window_update_body(
bncdf80d44fd2016-07-15 20:27:415782 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
[email protected]8d2f7012012-02-16 00:08:045783
5784 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415785 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
5786 CreateMockWrite(window_update_get_resp, 6),
5787 CreateMockWrite(window_update_body, 7),
[email protected]8d2f7012012-02-16 00:08:045788 };
5789
[email protected]d9da5fe2010-10-13 22:37:165790 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415791 CreateMockRead(conn_resp, 1, ASYNC),
rch32320842015-05-16 15:57:095792 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:415793 CreateMockRead(wrapped_get_resp, 4, ASYNC),
5794 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:135795 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:165796 };
5797
Ryan Sleevib8d7ea02018-05-07 20:01:015798 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075799 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165800
[email protected]8ddf8322012-02-23 18:08:065801 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365802 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075803 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065804 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365805 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075806 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165807
[email protected]49639fa2011-12-20 23:22:415808 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165809
bnc691fda62016-08-12 00:43:165810 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015811 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165812
rch32320842015-05-16 15:57:095813 // Allow the SpdyProxyClientSocket's write callback to complete.
fdoray92e35a72016-06-10 15:54:555814 base::RunLoop().RunUntilIdle();
rch32320842015-05-16 15:57:095815 // Now allow the read of the response to complete.
mmenkee24011922015-12-17 22:12:595816 spdy_data.Resume();
[email protected]d9da5fe2010-10-13 22:37:165817 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015818 EXPECT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:165819
[email protected]58e32bb2013-01-21 18:23:255820 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165821 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255822 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5823
bnc691fda62016-08-12 00:43:165824 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525825 ASSERT_TRUE(response);
5826 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025827 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d9da5fe2010-10-13 22:37:165828
5829 std::string response_data;
bnc691fda62016-08-12 00:43:165830 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235831 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:165832}
5833
5834// Test a SPDY CONNECT failure through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015835TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:275836 HttpRequestInfo request;
5837 request.method = "GET";
bncce36dca22015-04-21 22:11:235838 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105839 request.traffic_annotation =
5840 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275841
[email protected]d9da5fe2010-10-13 22:37:165842 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495843 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5844 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515845 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075846 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095847 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165848
bnc691fda62016-08-12 00:43:165849 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165850
bncce36dca22015-04-21 22:11:235851 // CONNECT to www.example.org:443 via SPDY
Ryan Hamilton0239aac2018-05-19 00:03:135852 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
Raul Tambre94493c652019-03-11 17:18:355853 nullptr, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:135854 spdy::SpdySerializedFrame get(
5855 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:165856
5857 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415858 CreateMockWrite(connect, 0), CreateMockWrite(get, 2),
[email protected]d9da5fe2010-10-13 22:37:165859 };
5860
Ryan Hamilton0239aac2018-05-19 00:03:135861 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(1));
5862 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:165863 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415864 CreateMockRead(resp, 1, ASYNC), MockRead(ASYNC, 0, 3),
[email protected]d9da5fe2010-10-13 22:37:165865 };
5866
Ryan Sleevib8d7ea02018-05-07 20:01:015867 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075868 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165869
[email protected]8ddf8322012-02-23 18:08:065870 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365871 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075872 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065873 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365874 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075875 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165876
[email protected]49639fa2011-12-20 23:22:415877 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165878
bnc691fda62016-08-12 00:43:165879 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015880 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165881
5882 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015883 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]d9da5fe2010-10-13 22:37:165884
ttuttle960fcbf2016-04-19 13:26:325885 // TODO(juliatuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:165886}
5887
Matt Menkecb2cd0982018-12-19 17:54:045888// Test the case where a proxied H2 session doesn't exist when an auth challenge
5889// is observed, but does exist by the time auth credentials are provided.
5890// Proxy-Connection: Close is used so that there's a second DNS lookup, which is
5891// what causes the existing H2 session to be noticed and reused.
5892TEST_F(HttpNetworkTransactionTest, ProxiedH2SessionAppearsDuringAuth) {
5893 ProxyConfig proxy_config;
5894 proxy_config.set_auto_detect(true);
5895 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
5896
5897 CapturingProxyResolver capturing_proxy_resolver;
5898 capturing_proxy_resolver.set_proxy_server(
5899 ProxyServer(ProxyServer::SCHEME_HTTP, HostPortPair("myproxy", 70)));
5900 session_deps_.proxy_resolution_service =
5901 std::make_unique<ProxyResolutionService>(
5902 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
5903 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
5904 std::make_unique<CapturingProxyResolverFactory>(
5905 &capturing_proxy_resolver),
5906 nullptr);
5907
5908 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
5909
5910 const char kMyUrl[] = "https://www.example.org/";
5911 spdy::SpdySerializedFrame get(spdy_util_.ConstructSpdyGet(kMyUrl, 1, LOWEST));
5912 spdy::SpdySerializedFrame get_resp(
Raul Tambre94493c652019-03-11 17:18:355913 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Matt Menkecb2cd0982018-12-19 17:54:045914 spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
5915
5916 spdy_util_.UpdateWithStreamDestruction(1);
5917 spdy::SpdySerializedFrame get2(
5918 spdy_util_.ConstructSpdyGet(kMyUrl, 3, LOWEST));
5919 spdy::SpdySerializedFrame get_resp2(
Raul Tambre94493c652019-03-11 17:18:355920 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
Matt Menkecb2cd0982018-12-19 17:54:045921 spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
5922
5923 MockWrite auth_challenge_writes[] = {
5924 MockWrite(ASYNC, 0,
5925 "CONNECT www.example.org:443 HTTP/1.1\r\n"
5926 "Host: www.example.org:443\r\n"
5927 "Proxy-Connection: keep-alive\r\n\r\n"),
5928 };
5929
5930 MockRead auth_challenge_reads[] = {
5931 MockRead(ASYNC, 1,
5932 "HTTP/1.1 407 Authentication Required\r\n"
5933 "Content-Length: 0\r\n"
5934 "Proxy-Connection: close\r\n"
5935 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
5936 };
5937
5938 MockWrite spdy_writes[] = {
5939 MockWrite(ASYNC, 0,
5940 "CONNECT www.example.org:443 HTTP/1.1\r\n"
5941 "Host: www.example.org:443\r\n"
5942 "Proxy-Connection: keep-alive\r\n"
5943 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5944 CreateMockWrite(get, 2),
5945 CreateMockWrite(get2, 5),
5946 };
5947
5948 MockRead spdy_reads[] = {
5949 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\n\r\n"),
5950 CreateMockRead(get_resp, 3, ASYNC),
5951 CreateMockRead(body, 4, ASYNC),
5952 CreateMockRead(get_resp2, 6, ASYNC),
5953 CreateMockRead(body2, 7, ASYNC),
5954
5955 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 8),
5956 };
5957
5958 SequencedSocketData auth_challenge1(auth_challenge_reads,
5959 auth_challenge_writes);
5960 session_deps_.socket_factory->AddSocketDataProvider(&auth_challenge1);
5961
5962 SequencedSocketData auth_challenge2(auth_challenge_reads,
5963 auth_challenge_writes);
5964 session_deps_.socket_factory->AddSocketDataProvider(&auth_challenge2);
5965
5966 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
5967 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
5968
5969 SSLSocketDataProvider ssl(ASYNC, OK);
5970 ssl.next_proto = kProtoHTTP2;
5971 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5972
5973 TestCompletionCallback callback;
5974 std::string response_data;
5975
5976 // Run first request until an auth challenge is observed.
5977 HttpRequestInfo request1;
5978 request1.method = "GET";
5979 request1.url = GURL(kMyUrl);
5980 request1.traffic_annotation =
5981 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5982 HttpNetworkTransaction trans1(LOWEST, session.get());
5983 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
5984 EXPECT_THAT(callback.GetResult(rv), IsOk());
5985 const HttpResponseInfo* response = trans1.GetResponseInfo();
5986 ASSERT_TRUE(response);
5987 ASSERT_TRUE(response->headers);
5988 EXPECT_EQ(407, response->headers->response_code());
5989 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5990 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
5991
5992 // Run second request until an auth challenge is observed.
5993 HttpRequestInfo request2;
5994 request2.method = "GET";
5995 request2.url = GURL(kMyUrl);
5996 request2.traffic_annotation =
5997 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5998 HttpNetworkTransaction trans2(LOWEST, session.get());
5999 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
6000 EXPECT_THAT(callback.GetResult(rv), IsOk());
6001 response = trans2.GetResponseInfo();
6002 ASSERT_TRUE(response);
6003 ASSERT_TRUE(response->headers);
6004 EXPECT_EQ(407, response->headers->response_code());
6005 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6006 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
6007
6008 // Now provide credentials for the first request, and wait for it to complete.
6009 rv = trans1.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
6010 rv = callback.GetResult(rv);
6011 EXPECT_THAT(rv, IsOk());
6012 response = trans1.GetResponseInfo();
6013 ASSERT_TRUE(response);
6014 ASSERT_TRUE(response->headers);
6015 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
6016 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
6017 EXPECT_EQ(kUploadData, response_data);
6018
6019 // Now provide credentials for the second request. It should notice the
6020 // existing session, and reuse it.
6021 rv = trans2.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
6022 EXPECT_THAT(callback.GetResult(rv), IsOk());
6023 response = trans2.GetResponseInfo();
6024 ASSERT_TRUE(response);
6025 ASSERT_TRUE(response->headers);
6026 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
6027 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
6028 EXPECT_EQ(kUploadData, response_data);
6029}
6030
[email protected]f6c63db52013-02-02 00:35:226031// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
6032// HTTPS Proxy to different servers.
bncd16676a2016-07-20 16:23:016033TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:226034 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
6035 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496036 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6037 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:516038 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076039 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:096040 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:506041 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:226042
6043 HttpRequestInfo request1;
6044 request1.method = "GET";
bncce36dca22015-04-21 22:11:236045 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:226046 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:106047 request1.traffic_annotation =
6048 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226049
6050 HttpRequestInfo request2;
6051 request2.method = "GET";
bncce36dca22015-04-21 22:11:236052 request2.url = GURL("https://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:226053 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:106054 request2.traffic_annotation =
6055 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226056
bncce36dca22015-04-21 22:11:236057 // CONNECT to www.example.org:443 via SPDY.
Ryan Hamilton0239aac2018-05-19 00:03:136058 spdy::SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
Raul Tambre94493c652019-03-11 17:18:356059 nullptr, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:136060 spdy::SpdySerializedFrame conn_resp1(
Raul Tambre94493c652019-03-11 17:18:356061 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
[email protected]f6c63db52013-02-02 00:35:226062
bncce36dca22015-04-21 22:11:236063 // Fetch https://www.example.org/ via HTTP.
6064 const char get1[] =
6065 "GET / HTTP/1.1\r\n"
6066 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:226067 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136068 spdy::SpdySerializedFrame wrapped_get1(
Bence Békyd74f4382018-02-20 18:26:196069 spdy_util_.ConstructSpdyDataFrame(1, get1, false));
[email protected]f6c63db52013-02-02 00:35:226070 const char resp1[] = "HTTP/1.1 200 OK\r\n"
6071 "Content-Length: 1\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136072 spdy::SpdySerializedFrame wrapped_get_resp1(
Bence Békyd74f4382018-02-20 18:26:196073 spdy_util_.ConstructSpdyDataFrame(1, resp1, false));
Ryan Hamilton0239aac2018-05-19 00:03:136074 spdy::SpdySerializedFrame wrapped_body1(
Bence Békyd74f4382018-02-20 18:26:196075 spdy_util_.ConstructSpdyDataFrame(1, "1", false));
Ryan Hamilton0239aac2018-05-19 00:03:136076 spdy::SpdySerializedFrame window_update(
bncdf80d44fd2016-07-15 20:27:416077 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:226078
bncce36dca22015-04-21 22:11:236079 // CONNECT to mail.example.org:443 via SPDY.
Ryan Hamilton0239aac2018-05-19 00:03:136080 spdy::SpdyHeaderBlock connect2_block;
6081 connect2_block[spdy::kHttp2MethodHeader] = "CONNECT";
6082 connect2_block[spdy::kHttp2AuthorityHeader] = "mail.example.org:443";
6083 spdy::SpdySerializedFrame connect2(spdy_util_.ConstructSpdyHeaders(
bnc42331402016-07-25 13:36:156084 3, std::move(connect2_block), LOWEST, false));
[email protected]601e03f12014-04-06 16:26:396085
Ryan Hamilton0239aac2018-05-19 00:03:136086 spdy::SpdySerializedFrame conn_resp2(
Raul Tambre94493c652019-03-11 17:18:356087 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
[email protected]f6c63db52013-02-02 00:35:226088
bncce36dca22015-04-21 22:11:236089 // Fetch https://mail.example.org/ via HTTP.
6090 const char get2[] =
6091 "GET / HTTP/1.1\r\n"
6092 "Host: mail.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:226093 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136094 spdy::SpdySerializedFrame wrapped_get2(
Bence Békyd74f4382018-02-20 18:26:196095 spdy_util_.ConstructSpdyDataFrame(3, get2, false));
[email protected]f6c63db52013-02-02 00:35:226096 const char resp2[] = "HTTP/1.1 200 OK\r\n"
6097 "Content-Length: 2\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136098 spdy::SpdySerializedFrame wrapped_get_resp2(
Bence Békyd74f4382018-02-20 18:26:196099 spdy_util_.ConstructSpdyDataFrame(3, resp2, false));
Ryan Hamilton0239aac2018-05-19 00:03:136100 spdy::SpdySerializedFrame wrapped_body2(
Bence Békyd74f4382018-02-20 18:26:196101 spdy_util_.ConstructSpdyDataFrame(3, "22", false));
[email protected]f6c63db52013-02-02 00:35:226102
6103 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:416104 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
6105 CreateMockWrite(connect2, 5), CreateMockWrite(wrapped_get2, 7),
[email protected]f6c63db52013-02-02 00:35:226106 };
6107
6108 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:416109 CreateMockRead(conn_resp1, 1, ASYNC),
6110 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
6111 CreateMockRead(wrapped_body1, 4, ASYNC),
6112 CreateMockRead(conn_resp2, 6, ASYNC),
6113 CreateMockRead(wrapped_get_resp2, 8, ASYNC),
6114 CreateMockRead(wrapped_body2, 9, ASYNC),
6115 MockRead(ASYNC, 0, 10),
[email protected]f6c63db52013-02-02 00:35:226116 };
6117
Ryan Sleevib8d7ea02018-05-07 20:01:016118 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
mmenke11eb5152015-06-09 14:50:506119 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:226120
6121 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:366122 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:506123 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:226124 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:506125 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:226126 SSLSocketDataProvider ssl3(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:506127 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:226128
6129 TestCompletionCallback callback;
6130
bnc691fda62016-08-12 00:43:166131 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206132 int rv = trans.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016133 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:226134
6135 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:166136 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]f6c63db52013-02-02 00:35:226137 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
6138
bnc691fda62016-08-12 00:43:166139 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526140 ASSERT_TRUE(response);
6141 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:226142 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6143
6144 std::string response_data;
Victor Costan9c7302b2018-08-27 16:39:446145 scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(256);
bnc691fda62016-08-12 00:43:166146 rv = trans.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:506147 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:226148
bnc691fda62016-08-12 00:43:166149 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206150 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016151 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:226152
6153 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:166154 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:226155 // Even though the SPDY connection is reused, a new tunnelled connection has
6156 // to be created, so the socket's load timing looks like a fresh connection.
6157 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
6158
6159 // The requests should have different IDs, since they each are using their own
6160 // separate stream.
6161 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
6162
bnc691fda62016-08-12 00:43:166163 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:506164 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:226165}
6166
6167// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
6168// HTTPS Proxy to the same server.
bncd16676a2016-07-20 16:23:016169TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:226170 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
6171 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496172 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6173 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:516174 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076175 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:096176 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:506177 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:226178
6179 HttpRequestInfo request1;
6180 request1.method = "GET";
bncce36dca22015-04-21 22:11:236181 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:226182 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:106183 request1.traffic_annotation =
6184 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226185
6186 HttpRequestInfo request2;
6187 request2.method = "GET";
bncce36dca22015-04-21 22:11:236188 request2.url = GURL("https://www.example.org/2");
[email protected]f6c63db52013-02-02 00:35:226189 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:106190 request2.traffic_annotation =
6191 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226192
bncce36dca22015-04-21 22:11:236193 // CONNECT to www.example.org:443 via SPDY.
Ryan Hamilton0239aac2018-05-19 00:03:136194 spdy::SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
Raul Tambre94493c652019-03-11 17:18:356195 nullptr, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:136196 spdy::SpdySerializedFrame conn_resp1(
Raul Tambre94493c652019-03-11 17:18:356197 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
[email protected]f6c63db52013-02-02 00:35:226198
bncce36dca22015-04-21 22:11:236199 // Fetch https://www.example.org/ via HTTP.
6200 const char get1[] =
6201 "GET / HTTP/1.1\r\n"
6202 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:226203 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136204 spdy::SpdySerializedFrame wrapped_get1(
Bence Békyd74f4382018-02-20 18:26:196205 spdy_util_.ConstructSpdyDataFrame(1, get1, false));
[email protected]f6c63db52013-02-02 00:35:226206 const char resp1[] = "HTTP/1.1 200 OK\r\n"
6207 "Content-Length: 1\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136208 spdy::SpdySerializedFrame wrapped_get_resp1(
Bence Békyd74f4382018-02-20 18:26:196209 spdy_util_.ConstructSpdyDataFrame(1, resp1, false));
Ryan Hamilton0239aac2018-05-19 00:03:136210 spdy::SpdySerializedFrame wrapped_body1(
Bence Békyd74f4382018-02-20 18:26:196211 spdy_util_.ConstructSpdyDataFrame(1, "1", false));
Ryan Hamilton0239aac2018-05-19 00:03:136212 spdy::SpdySerializedFrame window_update(
bncdf80d44fd2016-07-15 20:27:416213 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:226214
bncce36dca22015-04-21 22:11:236215 // Fetch https://www.example.org/2 via HTTP.
6216 const char get2[] =
6217 "GET /2 HTTP/1.1\r\n"
6218 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:226219 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136220 spdy::SpdySerializedFrame wrapped_get2(
Bence Békyd74f4382018-02-20 18:26:196221 spdy_util_.ConstructSpdyDataFrame(1, get2, false));
[email protected]f6c63db52013-02-02 00:35:226222 const char resp2[] = "HTTP/1.1 200 OK\r\n"
6223 "Content-Length: 2\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136224 spdy::SpdySerializedFrame wrapped_get_resp2(
Bence Békyd74f4382018-02-20 18:26:196225 spdy_util_.ConstructSpdyDataFrame(1, resp2, false));
Ryan Hamilton0239aac2018-05-19 00:03:136226 spdy::SpdySerializedFrame wrapped_body2(
Bence Békyd74f4382018-02-20 18:26:196227 spdy_util_.ConstructSpdyDataFrame(1, "22", false));
[email protected]f6c63db52013-02-02 00:35:226228
6229 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:416230 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
6231 CreateMockWrite(wrapped_get2, 5),
[email protected]f6c63db52013-02-02 00:35:226232 };
6233
6234 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:416235 CreateMockRead(conn_resp1, 1, ASYNC),
6236 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
bnceb9aa7112017-01-05 01:03:466237 CreateMockRead(wrapped_body1, 4, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:416238 CreateMockRead(wrapped_get_resp2, 6, ASYNC),
bnceb9aa7112017-01-05 01:03:466239 CreateMockRead(wrapped_body2, 7, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:416240 MockRead(ASYNC, 0, 8),
[email protected]f6c63db52013-02-02 00:35:226241 };
6242
Ryan Sleevib8d7ea02018-05-07 20:01:016243 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
mmenke11eb5152015-06-09 14:50:506244 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:226245
6246 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:366247 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:506248 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:226249 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:506250 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:226251
6252 TestCompletionCallback callback;
6253
bnc87dcefc2017-05-25 12:47:586254 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:196255 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206256 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016257 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:226258
6259 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016260 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:226261
6262 LoadTimingInfo load_timing_info;
6263 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6264 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
6265
6266 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526267 ASSERT_TRUE(response);
6268 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:226269 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6270
6271 std::string response_data;
Victor Costan9c7302b2018-08-27 16:39:446272 scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(256);
[email protected]90499482013-06-01 00:39:506273 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:226274 trans.reset();
6275
bnc87dcefc2017-05-25 12:47:586276 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:196277 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206278 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016279 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:226280
[email protected]f6c63db52013-02-02 00:35:226281 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016282 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:226283
6284 LoadTimingInfo load_timing_info2;
6285 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
6286 TestLoadTimingReused(load_timing_info2);
6287
6288 // The requests should have the same ID.
6289 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
6290
[email protected]90499482013-06-01 00:39:506291 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:226292}
6293
6294// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
6295// Proxy to different servers.
bncd16676a2016-07-20 16:23:016296TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) {
[email protected]f6c63db52013-02-02 00:35:226297 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496298 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6299 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:516300 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076301 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:096302 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:506303 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:226304
6305 HttpRequestInfo request1;
6306 request1.method = "GET";
bncce36dca22015-04-21 22:11:236307 request1.url = GURL("http://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:226308 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:106309 request1.traffic_annotation =
6310 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226311
6312 HttpRequestInfo request2;
6313 request2.method = "GET";
bncce36dca22015-04-21 22:11:236314 request2.url = GURL("http://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:226315 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:106316 request2.traffic_annotation =
6317 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226318
bncce36dca22015-04-21 22:11:236319 // http://www.example.org/
Ryan Hamilton0239aac2018-05-19 00:03:136320 spdy::SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:236321 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
Ryan Hamilton0239aac2018-05-19 00:03:136322 spdy::SpdySerializedFrame get1(
bnc42331402016-07-25 13:36:156323 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
Ryan Hamilton0239aac2018-05-19 00:03:136324 spdy::SpdySerializedFrame get_resp1(
Raul Tambre94493c652019-03-11 17:18:356325 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:136326 spdy::SpdySerializedFrame body1(
6327 spdy_util_.ConstructSpdyDataFrame(1, "1", true));
rdsmithebb50aa2015-11-12 03:44:386328 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]f6c63db52013-02-02 00:35:226329
bncce36dca22015-04-21 22:11:236330 // http://mail.example.org/
Ryan Hamilton0239aac2018-05-19 00:03:136331 spdy::SpdyHeaderBlock headers2(
bncce36dca22015-04-21 22:11:236332 spdy_util_.ConstructGetHeaderBlockForProxy("http://mail.example.org/"));
Ryan Hamilton0239aac2018-05-19 00:03:136333 spdy::SpdySerializedFrame get2(
bnc42331402016-07-25 13:36:156334 spdy_util_.ConstructSpdyHeaders(3, std::move(headers2), LOWEST, true));
Ryan Hamilton0239aac2018-05-19 00:03:136335 spdy::SpdySerializedFrame get_resp2(
Raul Tambre94493c652019-03-11 17:18:356336 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
Ryan Hamilton0239aac2018-05-19 00:03:136337 spdy::SpdySerializedFrame body2(
6338 spdy_util_.ConstructSpdyDataFrame(3, "22", true));
[email protected]f6c63db52013-02-02 00:35:226339
6340 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:416341 CreateMockWrite(get1, 0), CreateMockWrite(get2, 3),
[email protected]f6c63db52013-02-02 00:35:226342 };
6343
6344 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:416345 CreateMockRead(get_resp1, 1, ASYNC),
6346 CreateMockRead(body1, 2, ASYNC),
6347 CreateMockRead(get_resp2, 4, ASYNC),
6348 CreateMockRead(body2, 5, ASYNC),
6349 MockRead(ASYNC, 0, 6),
[email protected]f6c63db52013-02-02 00:35:226350 };
6351
Ryan Sleevib8d7ea02018-05-07 20:01:016352 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
mmenke11eb5152015-06-09 14:50:506353 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:226354
6355 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:366356 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:506357 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:226358
6359 TestCompletionCallback callback;
6360
bnc87dcefc2017-05-25 12:47:586361 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:196362 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206363 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016364 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:226365
6366 LoadTimingInfo load_timing_info;
6367 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6368 TestLoadTimingNotReused(load_timing_info,
6369 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6370
6371 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526372 ASSERT_TRUE(response);
6373 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:026374 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]f6c63db52013-02-02 00:35:226375
6376 std::string response_data;
Victor Costan9c7302b2018-08-27 16:39:446377 scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(256);
mmenke11eb5152015-06-09 14:50:506378 rv = trans->Read(buf.get(), 256, callback.callback());
6379 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:226380 // Delete the first request, so the second one can reuse the socket.
6381 trans.reset();
6382
bnc691fda62016-08-12 00:43:166383 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206384 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016385 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:226386
6387 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:166388 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:226389 TestLoadTimingReused(load_timing_info2);
6390
6391 // The requests should have the same ID.
6392 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
6393
bnc691fda62016-08-12 00:43:166394 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:506395 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:226396}
6397
Matt Menke2436b2f2018-12-11 18:07:116398// Test that an HTTP/2 CONNECT through an HTTPS Proxy to a HTTP/2 server and a
6399// direct (non-proxied) request to the proxy server are not pooled, as that
6400// would break socket pool isolation.
6401TEST_F(HttpNetworkTransactionTest, SpdyProxyIsolation1) {
6402 ProxyConfig proxy_config;
6403 proxy_config.set_auto_detect(true);
6404 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
6405
6406 CapturingProxyResolver capturing_proxy_resolver;
6407 session_deps_.proxy_resolution_service =
6408 std::make_unique<ProxyResolutionService>(
6409 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
6410 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
6411 std::make_unique<CapturingProxyResolverFactory>(
6412 &capturing_proxy_resolver),
6413 nullptr);
6414
6415 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6416
6417 SpdyTestUtil spdy_util1;
6418 // CONNECT to www.example.org:443 via HTTP/2.
6419 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
Raul Tambre94493c652019-03-11 17:18:356420 nullptr, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
Matt Menke2436b2f2018-12-11 18:07:116421 // fetch https://www.example.org/ via HTTP/2.
6422 const char kMyUrl[] = "https://www.example.org/";
6423 spdy::SpdySerializedFrame get(spdy_util1.ConstructSpdyGet(kMyUrl, 1, LOWEST));
6424 spdy::SpdySerializedFrame wrapped_get(
6425 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
6426 spdy::SpdySerializedFrame conn_resp(
Raul Tambre94493c652019-03-11 17:18:356427 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Matt Menke2436b2f2018-12-11 18:07:116428 spdy::SpdySerializedFrame get_resp(
Raul Tambre94493c652019-03-11 17:18:356429 spdy_util1.ConstructSpdyGetReply(nullptr, 0, 1));
Matt Menke2436b2f2018-12-11 18:07:116430 spdy::SpdySerializedFrame wrapped_get_resp(
6431 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
6432 spdy::SpdySerializedFrame body(spdy_util1.ConstructSpdyDataFrame(1, true));
6433 spdy::SpdySerializedFrame wrapped_body(
6434 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
6435 spdy::SpdySerializedFrame window_update_get_resp(
6436 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
6437 spdy::SpdySerializedFrame window_update_body(
6438 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
6439
6440 MockWrite spdy_writes1[] = {
6441 CreateMockWrite(connect, 0),
6442 CreateMockWrite(wrapped_get, 2),
6443 CreateMockWrite(window_update_get_resp, 6),
6444 CreateMockWrite(window_update_body, 7),
6445 };
6446
6447 MockRead spdy_reads1[] = {
6448 CreateMockRead(conn_resp, 1, ASYNC),
6449 MockRead(ASYNC, ERR_IO_PENDING, 3),
6450 CreateMockRead(wrapped_get_resp, 4, ASYNC),
6451 CreateMockRead(wrapped_body, 5, ASYNC),
6452 MockRead(ASYNC, 0, 8),
6453 };
6454
6455 SequencedSocketData spdy_data1(spdy_reads1, spdy_writes1);
6456 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data1);
6457
6458 // Fetch https://proxy:70/ via HTTP/2. Needs a new SpdyTestUtil, since it uses
6459 // a new pipe.
6460 SpdyTestUtil spdy_util2;
6461 spdy::SpdySerializedFrame req(
6462 spdy_util2.ConstructSpdyGet("https://proxy:70/", 1, LOWEST));
6463 MockWrite spdy_writes2[] = {CreateMockWrite(req, 0)};
6464
6465 spdy::SpdySerializedFrame resp(
6466 spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
6467 spdy::SpdySerializedFrame data(spdy_util2.ConstructSpdyDataFrame(1, true));
6468 MockRead spdy_reads2[] = {
6469 CreateMockRead(resp, 1),
6470 CreateMockRead(data, 2),
6471 MockRead(ASYNC, 0, 3),
6472 };
6473 SequencedSocketData spdy_data2(spdy_reads2, spdy_writes2);
6474 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data2);
6475
6476 SSLSocketDataProvider ssl(ASYNC, OK);
6477 ssl.next_proto = kProtoHTTP2;
6478 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6479 SSLSocketDataProvider ssl2(ASYNC, OK);
6480 ssl2.next_proto = kProtoHTTP2;
6481 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6482 SSLSocketDataProvider ssl3(ASYNC, OK);
6483 ssl3.next_proto = kProtoHTTP2;
6484 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
6485
6486 TestCompletionCallback callback;
6487 std::string response_data;
6488
6489 // Make a request using proxy:70 as a HTTP/2 proxy.
6490 capturing_proxy_resolver.set_proxy_server(
6491 ProxyServer(ProxyServer::SCHEME_HTTPS, HostPortPair("proxy", 70)));
6492 HttpRequestInfo request1;
6493 request1.method = "GET";
6494 request1.url = GURL("https://www.example.org/");
6495 request1.traffic_annotation =
6496 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6497
6498 HttpNetworkTransaction trans1(LOWEST, session.get());
6499 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
6500 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6501
6502 // Allow the SpdyProxyClientSocket's write callback to complete.
6503 base::RunLoop().RunUntilIdle();
6504 // Now allow the read of the response to complete.
6505 spdy_data1.Resume();
6506 rv = callback.WaitForResult();
6507 EXPECT_THAT(rv, IsOk());
6508
6509 const HttpResponseInfo* response = trans1.GetResponseInfo();
6510 ASSERT_TRUE(response);
6511 ASSERT_TRUE(response->headers);
6512 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
6513
6514 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
6515 EXPECT_EQ(kUploadData, response_data);
6516 RunUntilIdle();
6517
6518 // Make a direct HTTP/2 request to proxy:70.
6519 capturing_proxy_resolver.set_proxy_server(ProxyServer::Direct());
6520 HttpRequestInfo request2;
6521 request2.method = "GET";
6522 request2.url = GURL("https://proxy:70/");
6523 request2.traffic_annotation =
6524 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6525 HttpNetworkTransaction trans2(LOWEST, session.get());
6526 EXPECT_THAT(callback.GetResult(trans2.Start(&request2, callback.callback(),
6527 NetLogWithSource())),
6528 IsOk());
6529 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
6530}
6531
6532// Same as above, but reverse request order, since the code to check for an
6533// existing session is different for tunnels and direct connections.
6534TEST_F(HttpNetworkTransactionTest, SpdyProxyIsolation2) {
6535 // Configure against https proxy server "myproxy:80".
6536 ProxyConfig proxy_config;
6537 proxy_config.set_auto_detect(true);
6538 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
6539
6540 CapturingProxyResolver capturing_proxy_resolver;
6541 session_deps_.proxy_resolution_service =
6542 std::make_unique<ProxyResolutionService>(
6543 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
6544 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
6545 std::make_unique<CapturingProxyResolverFactory>(
6546 &capturing_proxy_resolver),
6547 nullptr);
6548
6549 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6550 // Fetch https://proxy:70/ via HTTP/2.
6551 SpdyTestUtil spdy_util1;
6552 spdy::SpdySerializedFrame req(
6553 spdy_util1.ConstructSpdyGet("https://proxy:70/", 1, LOWEST));
6554 MockWrite spdy_writes1[] = {CreateMockWrite(req, 0)};
6555
6556 spdy::SpdySerializedFrame resp(
6557 spdy_util1.ConstructSpdyGetReply(nullptr, 0, 1));
6558 spdy::SpdySerializedFrame data(spdy_util1.ConstructSpdyDataFrame(1, true));
6559 MockRead spdy_reads1[] = {
6560 CreateMockRead(resp, 1),
6561 CreateMockRead(data, 2),
6562 MockRead(ASYNC, 0, 3),
6563 };
6564 SequencedSocketData spdy_data1(spdy_reads1, spdy_writes1);
6565 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data1);
6566
6567 SpdyTestUtil spdy_util2;
6568 // CONNECT to www.example.org:443 via HTTP/2.
6569 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
6570 nullptr, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
6571 // fetch https://www.example.org/ via HTTP/2.
6572 const char kMyUrl[] = "https://www.example.org/";
6573 spdy::SpdySerializedFrame get(spdy_util2.ConstructSpdyGet(kMyUrl, 1, LOWEST));
6574 spdy::SpdySerializedFrame wrapped_get(
6575 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
6576 spdy::SpdySerializedFrame conn_resp(
6577 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
6578 spdy::SpdySerializedFrame get_resp(
6579 spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
6580 spdy::SpdySerializedFrame wrapped_get_resp(
6581 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
6582 spdy::SpdySerializedFrame body(spdy_util2.ConstructSpdyDataFrame(1, true));
6583 spdy::SpdySerializedFrame wrapped_body(
6584 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
6585 spdy::SpdySerializedFrame window_update_get_resp(
6586 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
6587 spdy::SpdySerializedFrame window_update_body(
6588 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
6589
6590 MockWrite spdy_writes2[] = {
6591 CreateMockWrite(connect, 0),
6592 CreateMockWrite(wrapped_get, 2),
6593 CreateMockWrite(window_update_get_resp, 6),
6594 CreateMockWrite(window_update_body, 7),
6595 };
6596
6597 MockRead spdy_reads2[] = {
6598 CreateMockRead(conn_resp, 1, ASYNC),
6599 MockRead(ASYNC, ERR_IO_PENDING, 3),
6600 CreateMockRead(wrapped_get_resp, 4, ASYNC),
6601 CreateMockRead(wrapped_body, 5, ASYNC),
6602 MockRead(ASYNC, 0, 8),
6603 };
6604
6605 SequencedSocketData spdy_data2(spdy_reads2, spdy_writes2);
6606 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data2);
6607
6608 SSLSocketDataProvider ssl(ASYNC, OK);
6609 ssl.next_proto = kProtoHTTP2;
6610 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6611 SSLSocketDataProvider ssl2(ASYNC, OK);
6612 ssl2.next_proto = kProtoHTTP2;
6613 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6614 SSLSocketDataProvider ssl3(ASYNC, OK);
6615 ssl3.next_proto = kProtoHTTP2;
6616 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
6617
6618 TestCompletionCallback callback;
6619 std::string response_data;
6620
6621 // Make a direct HTTP/2 request to proxy:70.
6622 capturing_proxy_resolver.set_proxy_server(ProxyServer::Direct());
6623 HttpRequestInfo request1;
6624 request1.method = "GET";
6625 request1.url = GURL("https://proxy:70/");
6626 request1.traffic_annotation =
6627 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6628 HttpNetworkTransaction trans1(LOWEST, session.get());
6629 EXPECT_THAT(callback.GetResult(trans1.Start(&request1, callback.callback(),
6630 NetLogWithSource())),
6631 IsOk());
6632 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
6633 RunUntilIdle();
6634
6635 // Make a request using proxy:70 as a HTTP/2 proxy.
6636 capturing_proxy_resolver.set_proxy_server(
6637 ProxyServer(ProxyServer::SCHEME_HTTPS, HostPortPair("proxy", 70)));
6638 HttpRequestInfo request2;
6639 request2.method = "GET";
6640 request2.url = GURL("https://www.example.org/");
6641 request2.traffic_annotation =
6642 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6643
6644 HttpNetworkTransaction trans2(LOWEST, session.get());
6645 int rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
6646 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6647
6648 // Allow the SpdyProxyClientSocket's write callback to complete.
6649 base::RunLoop().RunUntilIdle();
6650 // Now allow the read of the response to complete.
6651 spdy_data2.Resume();
6652 rv = callback.WaitForResult();
6653 EXPECT_THAT(rv, IsOk());
6654
6655 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
6656 ASSERT_TRUE(response2);
6657 ASSERT_TRUE(response2->headers);
6658 EXPECT_EQ("HTTP/1.1 200", response2->headers->GetStatusLine());
6659
6660 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
6661 EXPECT_EQ(kUploadData, response_data);
6662}
6663
[email protected]2df19bb2010-08-25 20:13:466664// Test the challenge-response-retry sequence through an HTTPS Proxy
bncd16676a2016-07-20 16:23:016665TEST_F(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:466666 HttpRequestInfo request;
6667 request.method = "GET";
bncce36dca22015-04-21 22:11:236668 request.url = GURL("http://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:466669 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:296670 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:106671 request.traffic_annotation =
6672 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:466673
[email protected]79cb5c12011-09-12 13:12:046674 // Configure against https proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496675 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6676 "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:516677 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076678 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:096679 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276680
[email protected]2df19bb2010-08-25 20:13:466681 // Since we have proxy, should use full url
6682 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:166683 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
6684 "Host: www.example.org\r\n"
6685 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:466686
bnc691fda62016-08-12 00:43:166687 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:236688 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:166689 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
6690 "Host: www.example.org\r\n"
6691 "Proxy-Connection: keep-alive\r\n"
6692 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:466693 };
6694
6695 // The proxy responds to the GET with a 407, using a persistent
6696 // connection.
6697 MockRead data_reads1[] = {
6698 // No credentials.
6699 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
6700 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6701 MockRead("Proxy-Connection: keep-alive\r\n"),
6702 MockRead("Content-Length: 0\r\n\r\n"),
6703
6704 MockRead("HTTP/1.1 200 OK\r\n"),
6705 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6706 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066707 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:466708 };
6709
Ryan Sleevib8d7ea02018-05-07 20:01:016710 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:076711 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:066712 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076713 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:466714
[email protected]49639fa2011-12-20 23:22:416715 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:466716
bnc691fda62016-08-12 00:43:166717 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506718
bnc691fda62016-08-12 00:43:166719 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:016720 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:466721
6722 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016723 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:466724
[email protected]58e32bb2013-01-21 18:23:256725 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:166726 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:256727 TestLoadTimingNotReused(load_timing_info,
6728 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6729
bnc691fda62016-08-12 00:43:166730 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526731 ASSERT_TRUE(response);
6732 ASSERT_TRUE(response->headers);
[email protected]2df19bb2010-08-25 20:13:466733 EXPECT_EQ(407, response->headers->response_code());
6734 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
asanka098c0092016-06-16 20:18:436735 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:466736
[email protected]49639fa2011-12-20 23:22:416737 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:466738
bnc691fda62016-08-12 00:43:166739 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:016740 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:466741
6742 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016743 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:466744
[email protected]58e32bb2013-01-21 18:23:256745 load_timing_info = LoadTimingInfo();
bnc691fda62016-08-12 00:43:166746 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:256747 // Retrying with HTTP AUTH is considered to be reusing a socket.
6748 TestLoadTimingReused(load_timing_info);
6749
bnc691fda62016-08-12 00:43:166750 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526751 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:466752
6753 EXPECT_TRUE(response->headers->IsKeepAlive());
6754 EXPECT_EQ(200, response->headers->response_code());
6755 EXPECT_EQ(100, response->headers->GetContentLength());
6756 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6757
6758 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:526759 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:466760}
6761
[email protected]23e482282013-06-14 16:08:026762void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:086763 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:426764 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:086765 request.method = "GET";
bncce36dca22015-04-21 22:11:236766 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:106767 request.traffic_annotation =
6768 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]c744cf22009-02-27 07:28:086769
[email protected]cb9bf6ca2011-01-28 13:15:276770 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496771 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6772 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:096773 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276774
[email protected]c744cf22009-02-27 07:28:086775 // Since we have proxy, should try to establish tunnel.
6776 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:176777 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
6778 "Host: www.example.org:443\r\n"
6779 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:086780 };
6781
6782 MockRead data_reads[] = {
mmenked39192ee2015-12-09 00:57:236783 status, MockRead("Content-Length: 10\r\n\r\n"),
6784 // No response body because the test stops reading here.
6785 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]c744cf22009-02-27 07:28:086786 };
6787
Ryan Sleevib8d7ea02018-05-07 20:01:016788 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:076789 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:086790
[email protected]49639fa2011-12-20 23:22:416791 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:086792
bnc691fda62016-08-12 00:43:166793 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506794
tfarina42834112016-09-22 13:38:206795 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016796 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]c744cf22009-02-27 07:28:086797
6798 rv = callback.WaitForResult();
6799 EXPECT_EQ(expected_status, rv);
6800}
6801
[email protected]23e482282013-06-14 16:08:026802void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:236803 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:086804 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:426805 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:086806}
6807
bncd16676a2016-07-20 16:23:016808TEST_F(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:086809 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
6810}
6811
bncd16676a2016-07-20 16:23:016812TEST_F(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:086813 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
6814}
6815
bncd16676a2016-07-20 16:23:016816TEST_F(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:086817 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
6818}
6819
bncd16676a2016-07-20 16:23:016820TEST_F(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:086821 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
6822}
6823
bncd16676a2016-07-20 16:23:016824TEST_F(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:086825 ConnectStatusHelper(
6826 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
6827}
6828
bncd16676a2016-07-20 16:23:016829TEST_F(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:086830 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
6831}
6832
bncd16676a2016-07-20 16:23:016833TEST_F(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:086834 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
6835}
6836
bncd16676a2016-07-20 16:23:016837TEST_F(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:086838 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
6839}
6840
bncd16676a2016-07-20 16:23:016841TEST_F(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:086842 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
6843}
6844
bncd16676a2016-07-20 16:23:016845TEST_F(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:086846 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
6847}
6848
bncd16676a2016-07-20 16:23:016849TEST_F(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:086850 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
6851}
6852
bncd16676a2016-07-20 16:23:016853TEST_F(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:086854 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
6855}
6856
bncd16676a2016-07-20 16:23:016857TEST_F(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:086858 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
6859}
6860
bncd16676a2016-07-20 16:23:016861TEST_F(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:086862 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
6863}
6864
bncd16676a2016-07-20 16:23:016865TEST_F(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:086866 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
6867}
6868
bncd16676a2016-07-20 16:23:016869TEST_F(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:086870 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
6871}
6872
bncd16676a2016-07-20 16:23:016873TEST_F(HttpNetworkTransactionTest, ConnectStatus308) {
[email protected]0a17aab32014-04-24 03:32:376874 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
6875}
6876
bncd16676a2016-07-20 16:23:016877TEST_F(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:086878 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
6879}
6880
bncd16676a2016-07-20 16:23:016881TEST_F(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:086882 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
6883}
6884
bncd16676a2016-07-20 16:23:016885TEST_F(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:086886 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
6887}
6888
bncd16676a2016-07-20 16:23:016889TEST_F(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:086890 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
6891}
6892
bncd16676a2016-07-20 16:23:016893TEST_F(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:086894 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
6895}
6896
bncd16676a2016-07-20 16:23:016897TEST_F(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:086898 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
6899}
6900
bncd16676a2016-07-20 16:23:016901TEST_F(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:086902 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
6903}
6904
bncd16676a2016-07-20 16:23:016905TEST_F(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:086906 ConnectStatusHelperWithExpectedStatus(
6907 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:546908 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:086909}
6910
bncd16676a2016-07-20 16:23:016911TEST_F(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:086912 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
6913}
6914
bncd16676a2016-07-20 16:23:016915TEST_F(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:086916 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
6917}
6918
bncd16676a2016-07-20 16:23:016919TEST_F(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:086920 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
6921}
6922
bncd16676a2016-07-20 16:23:016923TEST_F(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:086924 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
6925}
6926
bncd16676a2016-07-20 16:23:016927TEST_F(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:086928 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
6929}
6930
bncd16676a2016-07-20 16:23:016931TEST_F(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:086932 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
6933}
6934
bncd16676a2016-07-20 16:23:016935TEST_F(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:086936 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
6937}
6938
bncd16676a2016-07-20 16:23:016939TEST_F(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:086940 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
6941}
6942
bncd16676a2016-07-20 16:23:016943TEST_F(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:086944 ConnectStatusHelper(
6945 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
6946}
6947
bncd16676a2016-07-20 16:23:016948TEST_F(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:086949 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
6950}
6951
bncd16676a2016-07-20 16:23:016952TEST_F(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:086953 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
6954}
6955
bncd16676a2016-07-20 16:23:016956TEST_F(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:086957 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
6958}
6959
bncd16676a2016-07-20 16:23:016960TEST_F(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:086961 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
6962}
6963
bncd16676a2016-07-20 16:23:016964TEST_F(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:086965 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
6966}
6967
bncd16676a2016-07-20 16:23:016968TEST_F(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:086969 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
6970}
6971
bncd16676a2016-07-20 16:23:016972TEST_F(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:086973 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
6974}
6975
[email protected]038e9a32008-10-08 22:40:166976// Test the flow when both the proxy server AND origin server require
6977// authentication. Again, this uses basic auth for both since that is
6978// the simplest to mock.
bncd16676a2016-07-20 16:23:016979TEST_F(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:276980 HttpRequestInfo request;
6981 request.method = "GET";
bncce36dca22015-04-21 22:11:236982 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:106983 request.traffic_annotation =
6984 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:276985
[email protected]038e9a32008-10-08 22:40:166986 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496987 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6988 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:096989 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:076990
bnc691fda62016-08-12 00:43:166991 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]038e9a32008-10-08 22:40:166992
[email protected]f9ee6b52008-11-08 06:46:236993 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236994 MockWrite(
6995 "GET http://www.example.org/ HTTP/1.1\r\n"
6996 "Host: www.example.org\r\n"
6997 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236998 };
6999
[email protected]038e9a32008-10-08 22:40:167000 MockRead data_reads1[] = {
7001 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
7002 // Give a couple authenticate options (only the middle one is actually
7003 // supported).
[email protected]22927ad2009-09-21 19:56:197004 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:167005 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7006 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
7007 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7008 // Large content-length -- won't matter, as connection will be reset.
7009 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067010 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:167011 };
7012
bnc691fda62016-08-12 00:43:167013 // After calling trans.RestartWithAuth() the first time, this is the
[email protected]038e9a32008-10-08 22:40:167014 // request we should be issuing -- the final header line contains the
7015 // proxy's credentials.
7016 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237017 MockWrite(
7018 "GET http://www.example.org/ HTTP/1.1\r\n"
7019 "Host: www.example.org\r\n"
7020 "Proxy-Connection: keep-alive\r\n"
7021 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:167022 };
7023
7024 // Now the proxy server lets the request pass through to origin server.
7025 // The origin server responds with a 401.
7026 MockRead data_reads2[] = {
7027 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7028 // Note: We are using the same realm-name as the proxy server. This is
7029 // completely valid, as realms are unique across hosts.
7030 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7031 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7032 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067033 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:167034 };
7035
bnc691fda62016-08-12 00:43:167036 // After calling trans.RestartWithAuth() the second time, we should send
[email protected]038e9a32008-10-08 22:40:167037 // the credentials for both the proxy and origin server.
7038 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237039 MockWrite(
7040 "GET http://www.example.org/ HTTP/1.1\r\n"
7041 "Host: www.example.org\r\n"
7042 "Proxy-Connection: keep-alive\r\n"
7043 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
7044 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:167045 };
7046
7047 // Lastly we get the desired content.
7048 MockRead data_reads3[] = {
7049 MockRead("HTTP/1.0 200 OK\r\n"),
7050 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7051 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067052 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:167053 };
7054
Ryan Sleevib8d7ea02018-05-07 20:01:017055 StaticSocketDataProvider data1(data_reads1, data_writes1);
7056 StaticSocketDataProvider data2(data_reads2, data_writes2);
7057 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]bb88e1d32013-05-03 23:11:077058 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7059 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7060 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:167061
[email protected]49639fa2011-12-20 23:22:417062 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:167063
tfarina42834112016-09-22 13:38:207064 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017065 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:167066
7067 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017068 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:167069
bnc691fda62016-08-12 00:43:167070 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527071 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047072 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:167073
[email protected]49639fa2011-12-20 23:22:417074 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:167075
bnc691fda62016-08-12 00:43:167076 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:017077 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:167078
7079 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017080 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:167081
bnc691fda62016-08-12 00:43:167082 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527083 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047084 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:167085
[email protected]49639fa2011-12-20 23:22:417086 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:167087
bnc691fda62016-08-12 00:43:167088 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
7089 callback3.callback());
robpercival214763f2016-07-01 23:27:017090 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:167091
7092 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017093 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:167094
bnc691fda62016-08-12 00:43:167095 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527096 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:167097 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:167098}
[email protected]4ddaf2502008-10-23 18:26:197099
[email protected]ea9dc9a2009-09-05 00:43:327100// For the NTLM implementation using SSPI, we skip the NTLM tests since we
7101// can't hook into its internals to cause it to generate predictable NTLM
7102// authorization headers.
7103#if defined(NTLM_PORTABLE)
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377104// The NTLM authentication unit tests are based on known test data from the
7105// [MS-NLMP] Specification [1]. These tests are primarily of the authentication
7106// flow rather than the implementation of the NTLM protocol. See net/ntlm
7107// for the implementation and testing of the protocol.
7108//
7109// [1] https://msdn.microsoft.com/en-us/library/cc236621.aspx
[email protected]385a4672009-03-11 22:21:297110
7111// Enter the correct password and authenticate successfully.
Zentaro Kavanagh1890a3d2018-01-29 19:52:557112TEST_F(HttpNetworkTransactionTest, NTLMAuthV2) {
[email protected]1c773ea12009-04-28 19:58:427113 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:247114 request.method = "GET";
Zentaro Kavanagh1890a3d2018-01-29 19:52:557115 request.url = GURL("https://server/kids/login.aspx");
Ramin Halavatib5e433e2018-02-07 07:41:107116 request.traffic_annotation =
7117 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2217aa22013-10-11 03:03:547118
7119 // Ensure load is not disrupted by flags which suppress behaviour specific
7120 // to other auth schemes.
7121 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:247122
Zentaro Kavanagh6ccee512017-09-28 18:34:097123 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
7124 MockGetMSTime, MockGenerateRandom, MockGetHostName);
danakj1fd259a02016-04-16 03:17:097125 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277126
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377127 // Generate the NTLM messages based on known test data.
7128 std::string negotiate_msg;
7129 std::string challenge_msg;
7130 std::string authenticate_msg;
7131 base::Base64Encode(
7132 base::StringPiece(
7133 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
Avi Drissman4365a4782018-12-28 19:26:247134 base::size(ntlm::test::kExpectedNegotiateMsg)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377135 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:557136 base::Base64Encode(
7137 base::StringPiece(
7138 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
Avi Drissman4365a4782018-12-28 19:26:247139 base::size(ntlm::test::kChallengeMsgFromSpecV2)),
Zentaro Kavanagh1890a3d2018-01-29 19:52:557140 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377141 base::Base64Encode(
7142 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:097143 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557144 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
Avi Drissman4365a4782018-12-28 19:26:247145 base::size(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557146 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377147 &authenticate_msg);
7148
[email protected]3f918782009-02-28 01:29:247149 MockWrite data_writes1[] = {
Zentaro Kavanagh1890a3d2018-01-29 19:52:557150 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
7151 "Host: server\r\n"
7152 "Connection: keep-alive\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:247153 };
7154
7155 MockRead data_reads1[] = {
7156 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:047157 // Negotiate and NTLM are often requested together. However, we only want
7158 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
7159 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:247160 MockRead("WWW-Authenticate: NTLM\r\n"),
7161 MockRead("Connection: close\r\n"),
7162 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:367163 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:247164 // Missing content -- won't matter, as connection will be reset.
[email protected]3f918782009-02-28 01:29:247165 };
7166
7167 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:167168 // After restarting with a null identity, this is the
7169 // request we should be issuing -- the final header line contains a Type
7170 // 1 message.
7171 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557172 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167173 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377174 "Authorization: NTLM "),
7175 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:247176
bnc691fda62016-08-12 00:43:167177 // After calling trans.RestartWithAuth(), we should send a Type 3 message
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377178 // (using correct credentials). The second request continues on the
7179 // same connection.
bnc691fda62016-08-12 00:43:167180 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557181 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167182 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377183 "Authorization: NTLM "),
7184 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:247185 };
7186
7187 MockRead data_reads2[] = {
Bence Béky1e4ef192017-09-18 19:58:027188 // The origin server responds with a Type 2 message.
7189 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377190 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
7191 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky1e4ef192017-09-18 19:58:027192 MockRead("Content-Type: text/html\r\n\r\n"),
7193 MockRead("You are not authorized to view this page\r\n"),
[email protected]3f918782009-02-28 01:29:247194
Bence Béky1e4ef192017-09-18 19:58:027195 // Lastly we get the desired content.
7196 MockRead("HTTP/1.1 200 OK\r\n"),
7197 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
7198 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
[email protected]3f918782009-02-28 01:29:247199 };
7200
Ryan Sleevib8d7ea02018-05-07 20:01:017201 StaticSocketDataProvider data1(data_reads1, data_writes1);
7202 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:077203 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7204 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:247205
Bence Béky83eb3512017-09-05 12:56:097206 SSLSocketDataProvider ssl1(ASYNC, OK);
7207 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
7208 SSLSocketDataProvider ssl2(ASYNC, OK);
7209 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
7210
[email protected]49639fa2011-12-20 23:22:417211 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:247212
bnc691fda62016-08-12 00:43:167213 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:507214
tfarina42834112016-09-22 13:38:207215 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017216 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:247217
7218 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017219 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:247220
bnc691fda62016-08-12 00:43:167221 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227222
bnc691fda62016-08-12 00:43:167223 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527224 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047225 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:247226
[email protected]49639fa2011-12-20 23:22:417227 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:257228
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377229 rv = trans.RestartWithAuth(
7230 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
7231 callback2.callback());
robpercival214763f2016-07-01 23:27:017232 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:257233
7234 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017235 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:257236
bnc691fda62016-08-12 00:43:167237 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:257238
bnc691fda62016-08-12 00:43:167239 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527240 ASSERT_TRUE(response);
7241 EXPECT_FALSE(response->auth_challenge);
[email protected]10af5fe72011-01-31 16:17:257242
[email protected]49639fa2011-12-20 23:22:417243 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:247244
bnc691fda62016-08-12 00:43:167245 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:017246 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:247247
[email protected]0757e7702009-03-27 04:00:227248 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017249 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:247250
bnc691fda62016-08-12 00:43:167251 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527252 ASSERT_TRUE(response);
7253 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:027254 EXPECT_EQ(14, response->headers->GetContentLength());
7255
7256 std::string response_data;
7257 rv = ReadTransaction(&trans, &response_data);
7258 EXPECT_THAT(rv, IsOk());
7259 EXPECT_EQ("Please Login\r\n", response_data);
7260
7261 EXPECT_TRUE(data1.AllReadDataConsumed());
7262 EXPECT_TRUE(data1.AllWriteDataConsumed());
7263 EXPECT_TRUE(data2.AllReadDataConsumed());
7264 EXPECT_TRUE(data2.AllWriteDataConsumed());
[email protected]3f918782009-02-28 01:29:247265}
7266
[email protected]385a4672009-03-11 22:21:297267// Enter a wrong password, and then the correct one.
Zentaro Kavanagh1890a3d2018-01-29 19:52:557268TEST_F(HttpNetworkTransactionTest, NTLMAuthV2WrongThenRightPassword) {
[email protected]1c773ea12009-04-28 19:58:427269 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:297270 request.method = "GET";
Zentaro Kavanagh1890a3d2018-01-29 19:52:557271 request.url = GURL("https://server/kids/login.aspx");
Ramin Halavatib5e433e2018-02-07 07:41:107272 request.traffic_annotation =
7273 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]385a4672009-03-11 22:21:297274
Zentaro Kavanagh6ccee512017-09-28 18:34:097275 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
7276 MockGetMSTime, MockGenerateRandom, MockGetHostName);
danakj1fd259a02016-04-16 03:17:097277 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277278
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377279 // Generate the NTLM messages based on known test data.
7280 std::string negotiate_msg;
7281 std::string challenge_msg;
7282 std::string authenticate_msg;
7283 base::Base64Encode(
7284 base::StringPiece(
7285 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
Avi Drissman4365a4782018-12-28 19:26:247286 base::size(ntlm::test::kExpectedNegotiateMsg)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377287 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:557288 base::Base64Encode(
7289 base::StringPiece(
7290 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
Avi Drissman4365a4782018-12-28 19:26:247291 base::size(ntlm::test::kChallengeMsgFromSpecV2)),
Zentaro Kavanagh1890a3d2018-01-29 19:52:557292 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377293 base::Base64Encode(
7294 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:097295 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557296 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
Avi Drissman4365a4782018-12-28 19:26:247297 base::size(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557298 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377299 &authenticate_msg);
7300
7301 // The authenticate message when |kWrongPassword| is sent.
7302 std::string wrong_password_authenticate_msg(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557303 "TlRMTVNTUAADAAAAGAAYAFgAAACKAIoAcAAAAAwADAD6AAAACAAIAAYBAAAQABAADgEAAAAA"
7304 "AABYAAAAA4IIAAAAAAAAAAAAAPknEYqtJQtusopDRSfYzAAAAAAAAAAAAAAAAAAAAAAAAAAA"
7305 "AAAAAOtVz38osnFdRRggUQHUJ3EBAQAAAAAAAIALyP0A1NIBqqqqqqqqqqoAAAAAAgAMAEQA"
7306 "bwBtAGEAaQBuAAEADABTAGUAcgB2AGUAcgAGAAQAAgAAAAoAEAAAAAAAAAAAAAAAAAAAAAAA"
7307 "CQAWAEgAVABUAFAALwBzAGUAcgB2AGUAcgAAAAAAAAAAAEQAbwBtAGEAaQBuAFUAcwBlAHIA"
7308 "QwBPAE0AUABVAFQARQBSAA==");
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377309
Zentaro Kavanagh1890a3d2018-01-29 19:52:557310 // Sanity check that it's the same length as the correct authenticate message
7311 // and that it's different.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377312 ASSERT_EQ(authenticate_msg.length(),
7313 wrong_password_authenticate_msg.length());
Zentaro Kavanagh1890a3d2018-01-29 19:52:557314 ASSERT_NE(authenticate_msg, wrong_password_authenticate_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377315
[email protected]385a4672009-03-11 22:21:297316 MockWrite data_writes1[] = {
Zentaro Kavanagh1890a3d2018-01-29 19:52:557317 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
7318 "Host: server\r\n"
7319 "Connection: keep-alive\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297320 };
7321
7322 MockRead data_reads1[] = {
7323 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:047324 // Negotiate and NTLM are often requested together. However, we only want
7325 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
7326 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:297327 MockRead("WWW-Authenticate: NTLM\r\n"),
7328 MockRead("Connection: close\r\n"),
7329 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:367330 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297331 // Missing content -- won't matter, as connection will be reset.
[email protected]385a4672009-03-11 22:21:297332 };
7333
7334 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:167335 // After restarting with a null identity, this is the
7336 // request we should be issuing -- the final header line contains a Type
7337 // 1 message.
7338 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557339 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167340 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377341 "Authorization: NTLM "),
7342 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297343
bnc691fda62016-08-12 00:43:167344 // After calling trans.RestartWithAuth(), we should send a Type 3 message
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377345 // (using incorrect credentials). The second request continues on the
7346 // same connection.
bnc691fda62016-08-12 00:43:167347 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557348 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167349 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377350 "Authorization: NTLM "),
7351 MockWrite(wrong_password_authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297352 };
7353
7354 MockRead data_reads2[] = {
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377355 // The origin server responds with a Type 2 message.
7356 MockRead("HTTP/1.1 401 Access Denied\r\n"),
7357 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
7358 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
7359 MockRead("Content-Type: text/html\r\n\r\n"),
7360 MockRead("You are not authorized to view this page\r\n"),
[email protected]385a4672009-03-11 22:21:297361
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377362 // Wrong password.
7363 MockRead("HTTP/1.1 401 Access Denied\r\n"),
7364 MockRead("WWW-Authenticate: NTLM\r\n"), MockRead("Connection: close\r\n"),
7365 MockRead("Content-Length: 42\r\n"),
7366 MockRead("Content-Type: text/html\r\n\r\n"),
7367 // Missing content -- won't matter, as connection will be reset.
[email protected]385a4672009-03-11 22:21:297368 };
7369
7370 MockWrite data_writes3[] = {
bnc691fda62016-08-12 00:43:167371 // After restarting with a null identity, this is the
7372 // request we should be issuing -- the final header line contains a Type
7373 // 1 message.
7374 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557375 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167376 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377377 "Authorization: NTLM "),
7378 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297379
bnc691fda62016-08-12 00:43:167380 // After calling trans.RestartWithAuth(), we should send a Type 3 message
7381 // (the credentials for the origin server). The second request continues
7382 // on the same connection.
7383 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557384 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167385 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377386 "Authorization: NTLM "),
7387 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297388 };
7389
7390 MockRead data_reads3[] = {
Bence Béky1e4ef192017-09-18 19:58:027391 // The origin server responds with a Type 2 message.
7392 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377393 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
7394 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky1e4ef192017-09-18 19:58:027395 MockRead("Content-Type: text/html\r\n\r\n"),
7396 MockRead("You are not authorized to view this page\r\n"),
[email protected]385a4672009-03-11 22:21:297397
Bence Béky1e4ef192017-09-18 19:58:027398 // Lastly we get the desired content.
7399 MockRead("HTTP/1.1 200 OK\r\n"),
7400 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
7401 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
[email protected]385a4672009-03-11 22:21:297402 };
7403
Ryan Sleevib8d7ea02018-05-07 20:01:017404 StaticSocketDataProvider data1(data_reads1, data_writes1);
7405 StaticSocketDataProvider data2(data_reads2, data_writes2);
7406 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]bb88e1d32013-05-03 23:11:077407 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7408 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7409 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:297410
Bence Béky83eb3512017-09-05 12:56:097411 SSLSocketDataProvider ssl1(ASYNC, OK);
7412 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
7413 SSLSocketDataProvider ssl2(ASYNC, OK);
7414 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
7415 SSLSocketDataProvider ssl3(ASYNC, OK);
7416 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
7417
[email protected]49639fa2011-12-20 23:22:417418 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:297419
bnc691fda62016-08-12 00:43:167420 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:507421
tfarina42834112016-09-22 13:38:207422 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017423 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:297424
7425 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017426 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:297427
bnc691fda62016-08-12 00:43:167428 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:297429
bnc691fda62016-08-12 00:43:167430 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527431 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047432 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:297433
[email protected]49639fa2011-12-20 23:22:417434 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:297435
[email protected]0757e7702009-03-27 04:00:227436 // Enter the wrong password.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377437 rv = trans.RestartWithAuth(
7438 AuthCredentials(ntlm::test::kDomainUserCombined, kWrongPassword),
7439 callback2.callback());
robpercival214763f2016-07-01 23:27:017440 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:297441
[email protected]10af5fe72011-01-31 16:17:257442 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017443 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:297444
bnc691fda62016-08-12 00:43:167445 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:417446 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:167447 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:017448 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:257449 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017450 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167451 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227452
bnc691fda62016-08-12 00:43:167453 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527454 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047455 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:227456
[email protected]49639fa2011-12-20 23:22:417457 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:227458
7459 // Now enter the right password.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377460 rv = trans.RestartWithAuth(
7461 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
7462 callback4.callback());
robpercival214763f2016-07-01 23:27:017463 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:257464
7465 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:017466 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:257467
bnc691fda62016-08-12 00:43:167468 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:257469
[email protected]49639fa2011-12-20 23:22:417470 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:257471
7472 // One more roundtrip
bnc691fda62016-08-12 00:43:167473 rv = trans.RestartWithAuth(AuthCredentials(), callback5.callback());
robpercival214763f2016-07-01 23:27:017474 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:227475
7476 rv = callback5.WaitForResult();
robpercival214763f2016-07-01 23:27:017477 EXPECT_THAT(rv, IsOk());
[email protected]0757e7702009-03-27 04:00:227478
bnc691fda62016-08-12 00:43:167479 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527480 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:027481 EXPECT_EQ(14, response->headers->GetContentLength());
7482
7483 std::string response_data;
7484 rv = ReadTransaction(&trans, &response_data);
7485 EXPECT_THAT(rv, IsOk());
7486 EXPECT_EQ("Please Login\r\n", response_data);
7487
7488 EXPECT_TRUE(data1.AllReadDataConsumed());
7489 EXPECT_TRUE(data1.AllWriteDataConsumed());
7490 EXPECT_TRUE(data2.AllReadDataConsumed());
7491 EXPECT_TRUE(data2.AllWriteDataConsumed());
7492 EXPECT_TRUE(data3.AllReadDataConsumed());
7493 EXPECT_TRUE(data3.AllWriteDataConsumed());
[email protected]385a4672009-03-11 22:21:297494}
Bence Béky83eb3512017-09-05 12:56:097495
Bence Béky3238f2e12017-09-22 22:44:497496// Server requests NTLM authentication, which is not supported over HTTP/2.
7497// Subsequent request with authorization header should be sent over HTTP/1.1.
Bence Béky83eb3512017-09-05 12:56:097498TEST_F(HttpNetworkTransactionTest, NTLMOverHttp2) {
Zentaro Kavanagh6ccee512017-09-28 18:34:097499 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
7500 MockGetMSTime, MockGenerateRandom, MockGetHostName);
Bence Béky83eb3512017-09-05 12:56:097501
Zentaro Kavanagh1890a3d2018-01-29 19:52:557502 const char* kUrl = "https://server/kids/login.aspx";
Bence Béky83eb3512017-09-05 12:56:097503
7504 HttpRequestInfo request;
7505 request.method = "GET";
7506 request.url = GURL(kUrl);
Ramin Halavatib5e433e2018-02-07 07:41:107507 request.traffic_annotation =
7508 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Béky83eb3512017-09-05 12:56:097509
7510 // First request without credentials.
Ryan Hamilton0239aac2018-05-19 00:03:137511 spdy::SpdyHeaderBlock request_headers0(
7512 spdy_util_.ConstructGetHeaderBlock(kUrl));
7513 spdy::SpdySerializedFrame request0(spdy_util_.ConstructSpdyHeaders(
Bence Béky83eb3512017-09-05 12:56:097514 1, std::move(request_headers0), LOWEST, true));
7515
Ryan Hamilton0239aac2018-05-19 00:03:137516 spdy::SpdyHeaderBlock response_headers0;
7517 response_headers0[spdy::kHttp2StatusHeader] = "401";
Bence Béky83eb3512017-09-05 12:56:097518 response_headers0["www-authenticate"] = "NTLM";
Ryan Hamilton0239aac2018-05-19 00:03:137519 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyResponseHeaders(
Bence Béky83eb3512017-09-05 12:56:097520 1, std::move(response_headers0), true));
7521
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377522 // Stream 1 is closed.
7523 spdy_util_.UpdateWithStreamDestruction(1);
7524
7525 // Generate the NTLM messages based on known test data.
7526 std::string negotiate_msg;
7527 std::string challenge_msg;
7528 std::string authenticate_msg;
7529 base::Base64Encode(
7530 base::StringPiece(
7531 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
Avi Drissman4365a4782018-12-28 19:26:247532 base::size(ntlm::test::kExpectedNegotiateMsg)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377533 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:557534 base::Base64Encode(
7535 base::StringPiece(
7536 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
Avi Drissman4365a4782018-12-28 19:26:247537 base::size(ntlm::test::kChallengeMsgFromSpecV2)),
Zentaro Kavanagh1890a3d2018-01-29 19:52:557538 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377539 base::Base64Encode(
7540 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:097541 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557542 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
Avi Drissman4365a4782018-12-28 19:26:247543 base::size(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557544 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377545 &authenticate_msg);
7546
7547 // Retry with authorization header.
Ryan Hamilton0239aac2018-05-19 00:03:137548 spdy::SpdyHeaderBlock request_headers1(
7549 spdy_util_.ConstructGetHeaderBlock(kUrl));
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377550 request_headers1["authorization"] = std::string("NTLM ") + negotiate_msg;
Ryan Hamilton0239aac2018-05-19 00:03:137551 spdy::SpdySerializedFrame request1(spdy_util_.ConstructSpdyHeaders(
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377552 3, std::move(request_headers1), LOWEST, true));
7553
Ryan Hamilton0239aac2018-05-19 00:03:137554 spdy::SpdySerializedFrame rst(
7555 spdy_util_.ConstructSpdyRstStream(3, spdy::ERROR_CODE_HTTP_1_1_REQUIRED));
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377556
Bence Béky3238f2e12017-09-22 22:44:497557 MockWrite writes0[] = {CreateMockWrite(request0, 0)};
7558 MockRead reads0[] = {CreateMockRead(resp, 1), MockRead(ASYNC, 0, 2)};
Bence Béky83eb3512017-09-05 12:56:097559
7560 // Retry yet again using HTTP/1.1.
7561 MockWrite writes1[] = {
7562 // After restarting with a null identity, this is the
7563 // request we should be issuing -- the final header line contains a Type
7564 // 1 message.
7565 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557566 "Host: server\r\n"
Bence Béky83eb3512017-09-05 12:56:097567 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377568 "Authorization: NTLM "),
7569 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
Bence Béky83eb3512017-09-05 12:56:097570
7571 // After calling trans.RestartWithAuth(), we should send a Type 3 message
7572 // (the credentials for the origin server). The second request continues
7573 // on the same connection.
7574 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557575 "Host: server\r\n"
Bence Béky83eb3512017-09-05 12:56:097576 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377577 "Authorization: NTLM "),
7578 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
Bence Béky83eb3512017-09-05 12:56:097579 };
7580
7581 MockRead reads1[] = {
7582 // The origin server responds with a Type 2 message.
7583 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377584 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
7585 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky83eb3512017-09-05 12:56:097586 MockRead("Content-Type: text/html\r\n\r\n"),
7587 MockRead("You are not authorized to view this page\r\n"),
7588
7589 // Lastly we get the desired content.
7590 MockRead("HTTP/1.1 200 OK\r\n"),
7591 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
Bence Béky1e4ef192017-09-18 19:58:027592 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
Bence Béky83eb3512017-09-05 12:56:097593 };
Ryan Sleevib8d7ea02018-05-07 20:01:017594 SequencedSocketData data0(reads0, writes0);
7595 StaticSocketDataProvider data1(reads1, writes1);
Bence Béky83eb3512017-09-05 12:56:097596 session_deps_.socket_factory->AddSocketDataProvider(&data0);
7597 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7598
7599 SSLSocketDataProvider ssl0(ASYNC, OK);
7600 ssl0.next_proto = kProtoHTTP2;
7601 SSLSocketDataProvider ssl1(ASYNC, OK);
7602 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl0);
7603 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
7604
7605 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7606 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
7607
7608 TestCompletionCallback callback1;
7609 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
7610 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7611
7612 rv = callback1.WaitForResult();
7613 EXPECT_THAT(rv, IsOk());
7614
7615 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
7616
7617 const HttpResponseInfo* response = trans.GetResponseInfo();
7618 ASSERT_TRUE(response);
7619 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
7620
7621 TestCompletionCallback callback2;
7622
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377623 rv = trans.RestartWithAuth(
7624 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
7625 callback2.callback());
Bence Béky83eb3512017-09-05 12:56:097626 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7627
7628 rv = callback2.WaitForResult();
7629 EXPECT_THAT(rv, IsOk());
7630
7631 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
7632
7633 response = trans.GetResponseInfo();
7634 ASSERT_TRUE(response);
7635 EXPECT_FALSE(response->auth_challenge);
7636
7637 TestCompletionCallback callback3;
7638
7639 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
7640 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7641
7642 rv = callback3.WaitForResult();
7643 EXPECT_THAT(rv, IsOk());
7644
7645 response = trans.GetResponseInfo();
7646 ASSERT_TRUE(response);
7647 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:027648 EXPECT_EQ(14, response->headers->GetContentLength());
7649
7650 std::string response_data;
7651 rv = ReadTransaction(&trans, &response_data);
7652 EXPECT_THAT(rv, IsOk());
7653 EXPECT_EQ("Please Login\r\n", response_data);
7654
7655 EXPECT_TRUE(data0.AllReadDataConsumed());
7656 EXPECT_TRUE(data0.AllWriteDataConsumed());
7657 EXPECT_TRUE(data1.AllReadDataConsumed());
7658 EXPECT_TRUE(data1.AllWriteDataConsumed());
Bence Béky83eb3512017-09-05 12:56:097659}
David Benjamin5cb91132018-04-06 05:54:497660
7661// Test that, if we have an NTLM proxy and the origin resets the connection, we
7662// do no retry forever checking for TLS version interference. This is a
7663// regression test for https://crbug.com/823387.
7664TEST_F(HttpNetworkTransactionTest, NTLMProxyTLSHandshakeReset) {
7665 // The NTLM test data expects the proxy to be named 'server'. The origin is
7666 // https://origin/.
7667 session_deps_.proxy_resolution_service =
7668 ProxyResolutionService::CreateFixedFromPacResult(
7669 "PROXY server", TRAFFIC_ANNOTATION_FOR_TESTS);
7670
7671 SSLConfig config;
David Benjamin5cb91132018-04-06 05:54:497672 session_deps_.ssl_config_service =
Ryan Sleevib8449e02018-07-15 04:31:077673 std::make_unique<TestSSLConfigService>(config);
David Benjamin5cb91132018-04-06 05:54:497674
7675 HttpRequestInfo request;
7676 request.method = "GET";
7677 request.url = GURL("https://origin/");
7678 request.traffic_annotation =
7679 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7680
7681 // Ensure load is not disrupted by flags which suppress behaviour specific
7682 // to other auth schemes.
7683 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
7684
7685 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
7686 MockGetMSTime, MockGenerateRandom, MockGetHostName);
7687 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7688
7689 // Generate the NTLM messages based on known test data.
7690 std::string negotiate_msg;
7691 std::string challenge_msg;
7692 std::string authenticate_msg;
7693 base::Base64Encode(
7694 base::StringPiece(
7695 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
Avi Drissman4365a4782018-12-28 19:26:247696 base::size(ntlm::test::kExpectedNegotiateMsg)),
David Benjamin5cb91132018-04-06 05:54:497697 &negotiate_msg);
7698 base::Base64Encode(
7699 base::StringPiece(
7700 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
Avi Drissman4365a4782018-12-28 19:26:247701 base::size(ntlm::test::kChallengeMsgFromSpecV2)),
David Benjamin5cb91132018-04-06 05:54:497702 &challenge_msg);
7703 base::Base64Encode(
7704 base::StringPiece(
7705 reinterpret_cast<const char*>(
7706 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
Avi Drissman4365a4782018-12-28 19:26:247707 base::size(
David Benjamin5cb91132018-04-06 05:54:497708 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
7709 &authenticate_msg);
7710
7711 MockWrite data_writes[] = {
7712 // The initial CONNECT request.
7713 MockWrite("CONNECT origin:443 HTTP/1.1\r\n"
7714 "Host: origin:443\r\n"
7715 "Proxy-Connection: keep-alive\r\n\r\n"),
7716
7717 // After restarting with an identity.
7718 MockWrite("CONNECT origin:443 HTTP/1.1\r\n"
7719 "Host: origin:443\r\n"
7720 "Proxy-Connection: keep-alive\r\n"
7721 "Proxy-Authorization: NTLM "),
7722 MockWrite(negotiate_msg.c_str()),
7723 // End headers.
7724 MockWrite("\r\n\r\n"),
7725
7726 // The second restart.
7727 MockWrite("CONNECT origin:443 HTTP/1.1\r\n"
7728 "Host: origin:443\r\n"
7729 "Proxy-Connection: keep-alive\r\n"
7730 "Proxy-Authorization: NTLM "),
7731 MockWrite(authenticate_msg.c_str()),
7732 // End headers.
7733 MockWrite("\r\n\r\n"),
7734 };
7735
7736 MockRead data_reads[] = {
7737 // The initial NTLM response.
7738 MockRead("HTTP/1.1 407 Access Denied\r\n"
7739 "Content-Length: 0\r\n"
7740 "Proxy-Authenticate: NTLM\r\n\r\n"),
7741
7742 // The NTLM challenge message.
7743 MockRead("HTTP/1.1 407 Access Denied\r\n"
7744 "Content-Length: 0\r\n"
7745 "Proxy-Authenticate: NTLM "),
7746 MockRead(challenge_msg.c_str()),
7747 // End headers.
7748 MockRead("\r\n\r\n"),
7749
7750 // Finally the tunnel is established.
7751 MockRead("HTTP/1.1 200 Connected\r\n\r\n"),
7752 };
7753
Ryan Sleevib8d7ea02018-05-07 20:01:017754 StaticSocketDataProvider data(data_reads, data_writes);
David Benjamin5cb91132018-04-06 05:54:497755 SSLSocketDataProvider data_ssl(ASYNC, ERR_CONNECTION_RESET);
Ryan Sleevib8d7ea02018-05-07 20:01:017756 StaticSocketDataProvider data2(data_reads, data_writes);
David Benjamin5cb91132018-04-06 05:54:497757 SSLSocketDataProvider data_ssl2(ASYNC, ERR_CONNECTION_RESET);
Steven Valdez0ef94d02018-11-19 23:28:137758 data_ssl2.expected_ssl_version_max = SSL_PROTOCOL_VERSION_TLS1_2;
David Benjamin5cb91132018-04-06 05:54:497759 session_deps_.socket_factory->AddSocketDataProvider(&data);
7760 session_deps_.socket_factory->AddSSLSocketDataProvider(&data_ssl);
7761 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7762 session_deps_.socket_factory->AddSSLSocketDataProvider(&data_ssl2);
7763
7764 // Start the transaction. The proxy responds with an NTLM authentication
7765 // request.
7766 TestCompletionCallback callback;
7767 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
7768 int rv = callback.GetResult(
7769 trans.Start(&request, callback.callback(), NetLogWithSource()));
7770
7771 EXPECT_THAT(rv, IsOk());
7772 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
7773 const HttpResponseInfo* response = trans.GetResponseInfo();
7774 ASSERT_TRUE(response);
7775 EXPECT_TRUE(CheckNTLMProxyAuth(response->auth_challenge.get()));
7776
7777 // Configure credentials. The proxy responds with the challenge message.
7778 rv = callback.GetResult(trans.RestartWithAuth(
7779 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
7780 callback.callback()));
7781 EXPECT_THAT(rv, IsOk());
7782 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
7783 response = trans.GetResponseInfo();
7784 ASSERT_TRUE(response);
7785 EXPECT_FALSE(response->auth_challenge);
7786
7787 // Restart once more. The tunnel will be established and the the SSL handshake
7788 // will reset. The TLS 1.3 version interference probe will then kick in and
7789 // restart the process. The proxy responds with another NTLM authentiation
7790 // request, but we don't need to provide credentials as the cached ones work/
7791 rv = callback.GetResult(
7792 trans.RestartWithAuth(AuthCredentials(), callback.callback()));
7793 EXPECT_THAT(rv, IsOk());
7794 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
7795 response = trans.GetResponseInfo();
7796 ASSERT_TRUE(response);
7797 EXPECT_FALSE(response->auth_challenge);
7798
7799 // The proxy responds with the NTLM challenge message.
7800 rv = callback.GetResult(
7801 trans.RestartWithAuth(AuthCredentials(), callback.callback()));
7802 EXPECT_THAT(rv, IsOk());
7803 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
7804 response = trans.GetResponseInfo();
7805 ASSERT_TRUE(response);
7806 EXPECT_FALSE(response->auth_challenge);
7807
7808 // Send the NTLM authenticate message. The tunnel is established and the
7809 // handshake resets again. We should not retry again.
7810 rv = callback.GetResult(
7811 trans.RestartWithAuth(AuthCredentials(), callback.callback()));
7812 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
7813}
7814
[email protected]ea9dc9a2009-09-05 00:43:327815#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:297816
[email protected]4ddaf2502008-10-23 18:26:197817// Test reading a server response which has only headers, and no body.
7818// After some maximum number of bytes is consumed, the transaction should
7819// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
bncd16676a2016-07-20 16:23:017820TEST_F(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:427821 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:197822 request.method = "GET";
bncce36dca22015-04-21 22:11:237823 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:107824 request.traffic_annotation =
7825 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]4ddaf2502008-10-23 18:26:197826
danakj1fd259a02016-04-16 03:17:097827 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167828 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277829
[email protected]b75b7b2f2009-10-06 00:54:537830 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:437831 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:537832 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:197833
7834 MockRead data_reads[] = {
7835 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:067836 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:197837 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:067838 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:197839 };
Ryan Sleevib8d7ea02018-05-07 20:01:017840 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:077841 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:197842
[email protected]49639fa2011-12-20 23:22:417843 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:197844
tfarina42834112016-09-22 13:38:207845 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017846 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]4ddaf2502008-10-23 18:26:197847
7848 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017849 EXPECT_THAT(rv, IsError(ERR_RESPONSE_HEADERS_TOO_BIG));
[email protected]4ddaf2502008-10-23 18:26:197850}
[email protected]f4e426b2008-11-05 00:24:497851
7852// Make sure that we don't try to reuse a TCPClientSocket when failing to
7853// establish tunnel.
7854// http://code.google.com/p/chromium/issues/detail?id=3772
bncd16676a2016-07-20 16:23:017855TEST_F(HttpNetworkTransactionTest, DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:277856 HttpRequestInfo request;
7857 request.method = "GET";
bncce36dca22015-04-21 22:11:237858 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:107859 request.traffic_annotation =
7860 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:277861
[email protected]f4e426b2008-11-05 00:24:497862 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:497863 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
7864 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]db8f44c2008-12-13 04:52:017865
danakj1fd259a02016-04-16 03:17:097866 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:497867
bnc87dcefc2017-05-25 12:47:587868 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:197869 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]f4e426b2008-11-05 00:24:497870
[email protected]f4e426b2008-11-05 00:24:497871 // Since we have proxy, should try to establish tunnel.
7872 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:177873 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7874 "Host: www.example.org:443\r\n"
7875 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:497876 };
7877
[email protected]77848d12008-11-14 00:00:227878 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:497879 // connection. Usually a proxy would return 501 (not implemented),
7880 // or 200 (tunnel established).
7881 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:237882 MockRead("HTTP/1.1 404 Not Found\r\n"),
7883 MockRead("Content-Length: 10\r\n\r\n"),
7884 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]f4e426b2008-11-05 00:24:497885 };
7886
Ryan Sleevib8d7ea02018-05-07 20:01:017887 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:077888 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:497889
[email protected]49639fa2011-12-20 23:22:417890 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:497891
tfarina42834112016-09-22 13:38:207892 int rv = trans->Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017893 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f4e426b2008-11-05 00:24:497894
7895 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017896 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]f4e426b2008-11-05 00:24:497897
[email protected]b4404c02009-04-10 16:38:527898 // Empty the current queue. This is necessary because idle sockets are
7899 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557900 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:527901
[email protected]f4e426b2008-11-05 00:24:497902 // We now check to make sure the TCPClientSocket was not added back to
7903 // the pool.
[email protected]90499482013-06-01 00:39:507904 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:497905 trans.reset();
fdoray92e35a72016-06-10 15:54:557906 base::RunLoop().RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:497907 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:507908 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:497909}
[email protected]372d34a2008-11-05 21:30:517910
[email protected]1b157c02009-04-21 01:55:407911// Make sure that we recycle a socket after reading all of the response body.
bncd16676a2016-07-20 16:23:017912TEST_F(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:427913 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:407914 request.method = "GET";
bncce36dca22015-04-21 22:11:237915 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:107916 request.traffic_annotation =
7917 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1b157c02009-04-21 01:55:407918
danakj1fd259a02016-04-16 03:17:097919 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277920
bnc691fda62016-08-12 00:43:167921 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277922
[email protected]1b157c02009-04-21 01:55:407923 MockRead data_reads[] = {
7924 // A part of the response body is received with the response headers.
7925 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
7926 // The rest of the response body is received in two parts.
7927 MockRead("lo"),
7928 MockRead(" world"),
7929 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:067930 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:407931 };
7932
Ryan Sleevib8d7ea02018-05-07 20:01:017933 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:077934 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:407935
[email protected]49639fa2011-12-20 23:22:417936 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:407937
tfarina42834112016-09-22 13:38:207938 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017939 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1b157c02009-04-21 01:55:407940
7941 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017942 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:407943
bnc691fda62016-08-12 00:43:167944 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527945 ASSERT_TRUE(response);
[email protected]1b157c02009-04-21 01:55:407946
wezca1070932016-05-26 20:30:527947 EXPECT_TRUE(response->headers);
[email protected]1b157c02009-04-21 01:55:407948 std::string status_line = response->headers->GetStatusLine();
7949 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
7950
[email protected]90499482013-06-01 00:39:507951 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:407952
7953 std::string response_data;
bnc691fda62016-08-12 00:43:167954 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017955 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:407956 EXPECT_EQ("hello world", response_data);
7957
7958 // Empty the current queue. This is necessary because idle sockets are
7959 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557960 base::RunLoop().RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:407961
7962 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507963 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:407964}
7965
[email protected]76a505b2010-08-25 06:23:007966// Make sure that we recycle a SSL socket after reading all of the response
7967// body.
bncd16676a2016-07-20 16:23:017968TEST_F(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:007969 HttpRequestInfo request;
7970 request.method = "GET";
bncce36dca22015-04-21 22:11:237971 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:107972 request.traffic_annotation =
7973 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:007974
7975 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237976 MockWrite(
7977 "GET / HTTP/1.1\r\n"
7978 "Host: www.example.org\r\n"
7979 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:007980 };
7981
7982 MockRead data_reads[] = {
7983 MockRead("HTTP/1.1 200 OK\r\n"),
7984 MockRead("Content-Length: 11\r\n\r\n"),
7985 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:067986 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:007987 };
7988
[email protected]8ddf8322012-02-23 18:08:067989 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077990 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:007991
Ryan Sleevib8d7ea02018-05-07 20:01:017992 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:077993 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:007994
[email protected]49639fa2011-12-20 23:22:417995 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:007996
danakj1fd259a02016-04-16 03:17:097997 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167998 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:007999
tfarina42834112016-09-22 13:38:208000 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:008001
robpercival214763f2016-07-01 23:27:018002 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8003 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:008004
bnc691fda62016-08-12 00:43:168005 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528006 ASSERT_TRUE(response);
8007 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:008008 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8009
[email protected]90499482013-06-01 00:39:508010 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008011
8012 std::string response_data;
bnc691fda62016-08-12 00:43:168013 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:018014 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:008015 EXPECT_EQ("hello world", response_data);
8016
8017 // Empty the current queue. This is necessary because idle sockets are
8018 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:558019 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:008020
8021 // We now check to make sure the socket was added back to the pool.
Matt Menke9d5e2c92019-02-05 01:42:238022 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008023}
8024
8025// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
8026// from the pool and make sure that we recover okay.
bncd16676a2016-07-20 16:23:018027TEST_F(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:008028 HttpRequestInfo request;
8029 request.method = "GET";
bncce36dca22015-04-21 22:11:238030 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:108031 request.traffic_annotation =
8032 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:008033
8034 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238035 MockWrite(
8036 "GET / HTTP/1.1\r\n"
8037 "Host: www.example.org\r\n"
8038 "Connection: keep-alive\r\n\r\n"),
8039 MockWrite(
8040 "GET / HTTP/1.1\r\n"
8041 "Host: www.example.org\r\n"
8042 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:008043 };
8044
8045 MockRead data_reads[] = {
mmenke911ee0222015-12-04 03:58:428046 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
8047 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
[email protected]76a505b2010-08-25 06:23:008048
[email protected]8ddf8322012-02-23 18:08:068049 SSLSocketDataProvider ssl(ASYNC, OK);
8050 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078051 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8052 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:008053
Ryan Sleevib8d7ea02018-05-07 20:01:018054 StaticSocketDataProvider data(data_reads, data_writes);
8055 StaticSocketDataProvider data2(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:078056 session_deps_.socket_factory->AddSocketDataProvider(&data);
8057 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:008058
[email protected]49639fa2011-12-20 23:22:418059 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:008060
danakj1fd259a02016-04-16 03:17:098061 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:588062 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:198063 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:008064
tfarina42834112016-09-22 13:38:208065 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:008066
robpercival214763f2016-07-01 23:27:018067 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8068 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:008069
8070 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528071 ASSERT_TRUE(response);
8072 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:008073 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8074
[email protected]90499482013-06-01 00:39:508075 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008076
8077 std::string response_data;
8078 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018079 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:008080 EXPECT_EQ("hello world", response_data);
8081
8082 // Empty the current queue. This is necessary because idle sockets are
8083 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:558084 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:008085
8086 // We now check to make sure the socket was added back to the pool.
Matt Menke9d5e2c92019-02-05 01:42:238087 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008088
8089 // Now start the second transaction, which should reuse the previous socket.
8090
bnc87dcefc2017-05-25 12:47:588091 trans =
Jeremy Roman0579ed62017-08-29 15:56:198092 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:008093
tfarina42834112016-09-22 13:38:208094 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:008095
robpercival214763f2016-07-01 23:27:018096 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8097 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:008098
8099 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528100 ASSERT_TRUE(response);
8101 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:008102 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8103
[email protected]90499482013-06-01 00:39:508104 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008105
8106 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018107 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:008108 EXPECT_EQ("hello world", response_data);
8109
8110 // Empty the current queue. This is necessary because idle sockets are
8111 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:558112 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:008113
8114 // We now check to make sure the socket was added back to the pool.
Matt Menke9d5e2c92019-02-05 01:42:238115 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008116}
8117
maksim.sisov0adf8592016-07-15 06:25:568118// Grab a socket, use it, and put it back into the pool. Then, make
8119// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:018120TEST_F(HttpNetworkTransactionTest, FlushSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:568121 HttpRequestInfo request;
8122 request.method = "GET";
8123 request.url = GURL("http://www.example.org/");
8124 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:108125 request.traffic_annotation =
8126 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
maksim.sisov0adf8592016-07-15 06:25:568127
8128 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8129
bnc691fda62016-08-12 00:43:168130 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:568131
8132 MockRead data_reads[] = {
8133 // A part of the response body is received with the response headers.
8134 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
8135 // The rest of the response body is received in two parts.
8136 MockRead("lo"), MockRead(" world"),
8137 MockRead("junk"), // Should not be read!!
8138 MockRead(SYNCHRONOUS, OK),
8139 };
8140
Ryan Sleevib8d7ea02018-05-07 20:01:018141 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
maksim.sisov0adf8592016-07-15 06:25:568142 session_deps_.socket_factory->AddSocketDataProvider(&data);
8143
8144 TestCompletionCallback callback;
8145
tfarina42834112016-09-22 13:38:208146 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:568147 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8148
8149 EXPECT_THAT(callback.GetResult(rv), IsOk());
8150
bnc691fda62016-08-12 00:43:168151 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:568152 ASSERT_TRUE(response);
8153 EXPECT_TRUE(response->headers);
8154 std::string status_line = response->headers->GetStatusLine();
8155 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
8156
8157 // Make memory critical notification and ensure the transaction still has been
8158 // operating right.
8159 base::MemoryPressureListener::NotifyMemoryPressure(
8160 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8161 base::RunLoop().RunUntilIdle();
8162
8163 // Socket should not be flushed as long as it is not idle.
8164 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
8165
8166 std::string response_data;
bnc691fda62016-08-12 00:43:168167 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:568168 EXPECT_THAT(rv, IsOk());
8169 EXPECT_EQ("hello world", response_data);
8170
8171 // Empty the current queue. This is necessary because idle sockets are
8172 // added to the connection pool asynchronously with a PostTask.
8173 base::RunLoop().RunUntilIdle();
8174
8175 // We now check to make sure the socket was added back to the pool.
8176 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
8177
8178 // Idle sockets should be flushed now.
8179 base::MemoryPressureListener::NotifyMemoryPressure(
8180 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8181 base::RunLoop().RunUntilIdle();
8182
8183 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
8184}
8185
yucliu48f235d2018-01-11 00:59:558186// Disable idle socket closing on memory pressure.
8187// Grab a socket, use it, and put it back into the pool. Then, make
8188// low memory notification and ensure the socket pool is NOT flushed.
8189TEST_F(HttpNetworkTransactionTest, NoFlushSocketPoolOnLowMemoryNotifications) {
8190 HttpRequestInfo request;
8191 request.method = "GET";
8192 request.url = GURL("http://www.example.org/");
8193 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:108194 request.traffic_annotation =
8195 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
yucliu48f235d2018-01-11 00:59:558196
8197 // Disable idle socket closing on memory pressure.
8198 session_deps_.disable_idle_sockets_close_on_memory_pressure = true;
8199 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8200
8201 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
8202
8203 MockRead data_reads[] = {
8204 // A part of the response body is received with the response headers.
8205 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
8206 // The rest of the response body is received in two parts.
8207 MockRead("lo"), MockRead(" world"),
8208 MockRead("junk"), // Should not be read!!
8209 MockRead(SYNCHRONOUS, OK),
8210 };
8211
Ryan Sleevib8d7ea02018-05-07 20:01:018212 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
yucliu48f235d2018-01-11 00:59:558213 session_deps_.socket_factory->AddSocketDataProvider(&data);
8214
8215 TestCompletionCallback callback;
8216
8217 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
8218 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8219
8220 EXPECT_THAT(callback.GetResult(rv), IsOk());
8221
8222 const HttpResponseInfo* response = trans.GetResponseInfo();
8223 ASSERT_TRUE(response);
8224 EXPECT_TRUE(response->headers);
8225 std::string status_line = response->headers->GetStatusLine();
8226 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
8227
8228 // Make memory critical notification and ensure the transaction still has been
8229 // operating right.
8230 base::MemoryPressureListener::NotifyMemoryPressure(
8231 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8232 base::RunLoop().RunUntilIdle();
8233
8234 // Socket should not be flushed as long as it is not idle.
8235 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
8236
8237 std::string response_data;
8238 rv = ReadTransaction(&trans, &response_data);
8239 EXPECT_THAT(rv, IsOk());
8240 EXPECT_EQ("hello world", response_data);
8241
8242 // Empty the current queue. This is necessary because idle sockets are
8243 // added to the connection pool asynchronously with a PostTask.
8244 base::RunLoop().RunUntilIdle();
8245
8246 // We now check to make sure the socket was added back to the pool.
8247 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
8248
8249 // Idle sockets should NOT be flushed on moderate memory pressure.
8250 base::MemoryPressureListener::NotifyMemoryPressure(
8251 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE);
8252 base::RunLoop().RunUntilIdle();
8253
8254 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
8255
8256 // Idle sockets should NOT be flushed on critical memory pressure.
8257 base::MemoryPressureListener::NotifyMemoryPressure(
8258 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8259 base::RunLoop().RunUntilIdle();
8260
8261 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
8262}
8263
maksim.sisov0adf8592016-07-15 06:25:568264// Grab an SSL socket, use it, and put it back into the pool. Then, make
8265// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:018266TEST_F(HttpNetworkTransactionTest, FlushSSLSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:568267 HttpRequestInfo request;
8268 request.method = "GET";
8269 request.url = GURL("https://www.example.org/");
8270 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:108271 request.traffic_annotation =
8272 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
maksim.sisov0adf8592016-07-15 06:25:568273
8274 MockWrite data_writes[] = {
8275 MockWrite("GET / HTTP/1.1\r\n"
8276 "Host: www.example.org\r\n"
8277 "Connection: keep-alive\r\n\r\n"),
8278 };
8279
8280 MockRead data_reads[] = {
8281 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
8282 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
8283
8284 SSLSocketDataProvider ssl(ASYNC, OK);
8285 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8286
Ryan Sleevib8d7ea02018-05-07 20:01:018287 StaticSocketDataProvider data(data_reads, data_writes);
maksim.sisov0adf8592016-07-15 06:25:568288 session_deps_.socket_factory->AddSocketDataProvider(&data);
8289
8290 TestCompletionCallback callback;
8291
8292 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168293 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:568294
Matt Menke9d5e2c92019-02-05 01:42:238295 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
tfarina42834112016-09-22 13:38:208296 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:568297
8298 EXPECT_THAT(callback.GetResult(rv), IsOk());
8299
bnc691fda62016-08-12 00:43:168300 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:568301 ASSERT_TRUE(response);
8302 ASSERT_TRUE(response->headers);
8303 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8304
8305 // Make memory critical notification and ensure the transaction still has been
8306 // operating right.
8307 base::MemoryPressureListener::NotifyMemoryPressure(
8308 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8309 base::RunLoop().RunUntilIdle();
8310
Matt Menke9d5e2c92019-02-05 01:42:238311 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
maksim.sisov0adf8592016-07-15 06:25:568312
8313 std::string response_data;
bnc691fda62016-08-12 00:43:168314 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:568315 EXPECT_THAT(rv, IsOk());
8316 EXPECT_EQ("hello world", response_data);
8317
8318 // Empty the current queue. This is necessary because idle sockets are
8319 // added to the connection pool asynchronously with a PostTask.
8320 base::RunLoop().RunUntilIdle();
8321
8322 // We now check to make sure the socket was added back to the pool.
Matt Menke9d5e2c92019-02-05 01:42:238323 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
maksim.sisov0adf8592016-07-15 06:25:568324
8325 // Make memory notification once again and ensure idle socket is closed.
8326 base::MemoryPressureListener::NotifyMemoryPressure(
8327 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8328 base::RunLoop().RunUntilIdle();
8329
Matt Menke9d5e2c92019-02-05 01:42:238330 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
maksim.sisov0adf8592016-07-15 06:25:568331}
8332
[email protected]b4404c02009-04-10 16:38:528333// Make sure that we recycle a socket after a zero-length response.
8334// http://crbug.com/9880
bncd16676a2016-07-20 16:23:018335TEST_F(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:428336 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:528337 request.method = "GET";
bncce36dca22015-04-21 22:11:238338 request.url = GURL(
8339 "http://www.example.org/csi?v=3&s=web&action=&"
8340 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
8341 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
8342 "rt=prt.2642,ol.2649,xjs.2951");
Ramin Halavatib5e433e2018-02-07 07:41:108343 request.traffic_annotation =
8344 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]b4404c02009-04-10 16:38:528345
danakj1fd259a02016-04-16 03:17:098346 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:278347
[email protected]b4404c02009-04-10 16:38:528348 MockRead data_reads[] = {
8349 MockRead("HTTP/1.1 204 No Content\r\n"
8350 "Content-Length: 0\r\n"
8351 "Content-Type: text/html\r\n\r\n"),
8352 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:068353 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:528354 };
8355
Ryan Sleevib8d7ea02018-05-07 20:01:018356 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:078357 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:528358
mmenkecc2298e2015-12-07 18:20:188359 // Transaction must be created after the MockReads, so it's destroyed before
8360 // them.
bnc691fda62016-08-12 00:43:168361 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkecc2298e2015-12-07 18:20:188362
[email protected]49639fa2011-12-20 23:22:418363 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:528364
tfarina42834112016-09-22 13:38:208365 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018366 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]b4404c02009-04-10 16:38:528367
8368 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018369 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:528370
bnc691fda62016-08-12 00:43:168371 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528372 ASSERT_TRUE(response);
[email protected]b4404c02009-04-10 16:38:528373
wezca1070932016-05-26 20:30:528374 EXPECT_TRUE(response->headers);
[email protected]b4404c02009-04-10 16:38:528375 std::string status_line = response->headers->GetStatusLine();
8376 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
8377
[email protected]90499482013-06-01 00:39:508378 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:528379
8380 std::string response_data;
bnc691fda62016-08-12 00:43:168381 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:018382 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:528383 EXPECT_EQ("", response_data);
8384
8385 // Empty the current queue. This is necessary because idle sockets are
8386 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:558387 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:528388
8389 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:508390 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:528391}
8392
bncd16676a2016-07-20 16:23:018393TEST_F(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
danakj1fd259a02016-04-16 03:17:098394 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:228395 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:198396 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:228397 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:278398
[email protected]1c773ea12009-04-28 19:58:428399 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:518400 // Transaction 1: a GET request that succeeds. The socket is recycled
8401 // after use.
8402 request[0].method = "GET";
8403 request[0].url = GURL("http://www.google.com/");
8404 request[0].load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:108405 request[0].traffic_annotation =
8406 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]372d34a2008-11-05 21:30:518407 // Transaction 2: a POST request. Reuses the socket kept alive from
8408 // transaction 1. The first attempts fails when writing the POST data.
8409 // This causes the transaction to retry with a new socket. The second
8410 // attempt succeeds.
8411 request[1].method = "POST";
8412 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:278413 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:518414 request[1].load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:108415 request[1].traffic_annotation =
8416 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]372d34a2008-11-05 21:30:518417
danakj1fd259a02016-04-16 03:17:098418 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:518419
8420 // The first socket is used for transaction 1 and the first attempt of
8421 // transaction 2.
8422
8423 // The response of transaction 1.
8424 MockRead data_reads1[] = {
8425 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
8426 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068427 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:518428 };
8429 // The mock write results of transaction 1 and the first attempt of
8430 // transaction 2.
8431 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:068432 MockWrite(SYNCHRONOUS, 64), // GET
8433 MockWrite(SYNCHRONOUS, 93), // POST
8434 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:518435 };
Ryan Sleevib8d7ea02018-05-07 20:01:018436 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]372d34a2008-11-05 21:30:518437
8438 // The second socket is used for the second attempt of transaction 2.
8439
8440 // The response of transaction 2.
8441 MockRead data_reads2[] = {
8442 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
8443 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:068444 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:518445 };
8446 // The mock write results of the second attempt of transaction 2.
8447 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:068448 MockWrite(SYNCHRONOUS, 93), // POST
8449 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:518450 };
Ryan Sleevib8d7ea02018-05-07 20:01:018451 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]372d34a2008-11-05 21:30:518452
[email protected]bb88e1d32013-05-03 23:11:078453 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8454 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:518455
thestig9d3bb0c2015-01-24 00:49:518456 const char* const kExpectedResponseData[] = {
[email protected]372d34a2008-11-05 21:30:518457 "hello world", "welcome"
8458 };
8459
8460 for (int i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:168461 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]372d34a2008-11-05 21:30:518462
[email protected]49639fa2011-12-20 23:22:418463 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:518464
tfarina42834112016-09-22 13:38:208465 int rv = trans.Start(&request[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018466 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]372d34a2008-11-05 21:30:518467
8468 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018469 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:518470
bnc691fda62016-08-12 00:43:168471 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528472 ASSERT_TRUE(response);
[email protected]372d34a2008-11-05 21:30:518473
wezca1070932016-05-26 20:30:528474 EXPECT_TRUE(response->headers);
[email protected]372d34a2008-11-05 21:30:518475 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8476
8477 std::string response_data;
bnc691fda62016-08-12 00:43:168478 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:018479 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:518480 EXPECT_EQ(kExpectedResponseData[i], response_data);
8481 }
8482}
[email protected]f9ee6b52008-11-08 06:46:238483
8484// Test the request-challenge-retry sequence for basic auth when there is
8485// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:168486// it fails the identity from the URL is used to answer the challenge.
bncd16676a2016-07-20 16:23:018487TEST_F(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:428488 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238489 request.method = "GET";
bncce36dca22015-04-21 22:11:238490 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:418491 request.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:108492 request.traffic_annotation =
8493 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]a97cca42009-08-14 01:00:298494
danakj1fd259a02016-04-16 03:17:098495 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168496 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278497
[email protected]a97cca42009-08-14 01:00:298498 // The password contains an escaped character -- for this test to pass it
8499 // will need to be unescaped by HttpNetworkTransaction.
8500 EXPECT_EQ("b%40r", request.url.password());
8501
[email protected]f9ee6b52008-11-08 06:46:238502 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238503 MockWrite(
8504 "GET / HTTP/1.1\r\n"
8505 "Host: www.example.org\r\n"
8506 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238507 };
8508
8509 MockRead data_reads1[] = {
8510 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8511 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8512 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068513 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238514 };
8515
[email protected]2262e3a2012-05-22 16:08:168516 // After the challenge above, the transaction will be restarted using the
8517 // identity from the url (foo, b@r) to answer the challenge.
8518 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238519 MockWrite(
8520 "GET / HTTP/1.1\r\n"
8521 "Host: www.example.org\r\n"
8522 "Connection: keep-alive\r\n"
8523 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:168524 };
8525
8526 MockRead data_reads2[] = {
8527 MockRead("HTTP/1.0 200 OK\r\n"),
8528 MockRead("Content-Length: 100\r\n\r\n"),
8529 MockRead(SYNCHRONOUS, OK),
8530 };
8531
Ryan Sleevib8d7ea02018-05-07 20:01:018532 StaticSocketDataProvider data1(data_reads1, data_writes1);
8533 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:078534 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8535 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:238536
[email protected]49639fa2011-12-20 23:22:418537 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:208538 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018539 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238540 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018541 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168542 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:168543
8544 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:168545 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:018546 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:168547 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018548 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168549 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:228550
bnc691fda62016-08-12 00:43:168551 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528552 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:168553
8554 // There is no challenge info, since the identity in URL worked.
wezca1070932016-05-26 20:30:528555 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:168556
8557 EXPECT_EQ(100, response->headers->GetContentLength());
8558
8559 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:558560 base::RunLoop().RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:168561}
8562
8563// Test the request-challenge-retry sequence for basic auth when there is an
8564// incorrect identity in the URL. The identity from the URL should be used only
8565// once.
bncd16676a2016-07-20 16:23:018566TEST_F(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:168567 HttpRequestInfo request;
8568 request.method = "GET";
8569 // Note: the URL has a username:password in it. The password "baz" is
8570 // wrong (should be "bar").
bncce36dca22015-04-21 22:11:238571 request.url = GURL("http://foo:[email protected]/");
[email protected]2262e3a2012-05-22 16:08:168572
8573 request.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:108574 request.traffic_annotation =
8575 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2262e3a2012-05-22 16:08:168576
danakj1fd259a02016-04-16 03:17:098577 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168578 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2262e3a2012-05-22 16:08:168579
8580 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238581 MockWrite(
8582 "GET / HTTP/1.1\r\n"
8583 "Host: www.example.org\r\n"
8584 "Connection: keep-alive\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:168585 };
8586
8587 MockRead data_reads1[] = {
8588 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8589 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8590 MockRead("Content-Length: 10\r\n\r\n"),
8591 MockRead(SYNCHRONOUS, ERR_FAILED),
8592 };
8593
8594 // After the challenge above, the transaction will be restarted using the
8595 // identity from the url (foo, baz) to answer the challenge.
8596 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238597 MockWrite(
8598 "GET / HTTP/1.1\r\n"
8599 "Host: www.example.org\r\n"
8600 "Connection: keep-alive\r\n"
8601 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:168602 };
8603
8604 MockRead data_reads2[] = {
8605 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8606 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8607 MockRead("Content-Length: 10\r\n\r\n"),
8608 MockRead(SYNCHRONOUS, ERR_FAILED),
8609 };
8610
8611 // After the challenge above, the transaction will be restarted using the
8612 // identity supplied by the user (foo, bar) to answer the challenge.
8613 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:238614 MockWrite(
8615 "GET / HTTP/1.1\r\n"
8616 "Host: www.example.org\r\n"
8617 "Connection: keep-alive\r\n"
8618 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:168619 };
8620
8621 MockRead data_reads3[] = {
8622 MockRead("HTTP/1.0 200 OK\r\n"),
8623 MockRead("Content-Length: 100\r\n\r\n"),
8624 MockRead(SYNCHRONOUS, OK),
8625 };
8626
Ryan Sleevib8d7ea02018-05-07 20:01:018627 StaticSocketDataProvider data1(data_reads1, data_writes1);
8628 StaticSocketDataProvider data2(data_reads2, data_writes2);
8629 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]bb88e1d32013-05-03 23:11:078630 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8631 session_deps_.socket_factory->AddSocketDataProvider(&data2);
8632 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:168633
8634 TestCompletionCallback callback1;
8635
tfarina42834112016-09-22 13:38:208636 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018637 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:168638
8639 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018640 EXPECT_THAT(rv, IsOk());
[email protected]2262e3a2012-05-22 16:08:168641
bnc691fda62016-08-12 00:43:168642 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:168643 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:168644 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:018645 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:168646 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018647 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168648 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:168649
bnc691fda62016-08-12 00:43:168650 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528651 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:168652 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
8653
8654 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:168655 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:018656 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:168657 rv = callback3.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 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528662 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:168663
8664 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:528665 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:168666
8667 EXPECT_EQ(100, response->headers->GetContentLength());
8668
[email protected]ea9dc9a2009-09-05 00:43:328669 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:558670 base::RunLoop().RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:328671}
8672
[email protected]2217aa22013-10-11 03:03:548673
8674// Test the request-challenge-retry sequence for basic auth when there is a
8675// correct identity in the URL, but its use is being suppressed. The identity
8676// from the URL should never be used.
bncd16676a2016-07-20 16:23:018677TEST_F(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
[email protected]2217aa22013-10-11 03:03:548678 HttpRequestInfo request;
8679 request.method = "GET";
bncce36dca22015-04-21 22:11:238680 request.url = GURL("http://foo:[email protected]/");
[email protected]2217aa22013-10-11 03:03:548681 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
Ramin Halavatib5e433e2018-02-07 07:41:108682 request.traffic_annotation =
8683 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2217aa22013-10-11 03:03:548684
danakj1fd259a02016-04-16 03:17:098685 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168686 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2217aa22013-10-11 03:03:548687
8688 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238689 MockWrite(
8690 "GET / HTTP/1.1\r\n"
8691 "Host: www.example.org\r\n"
8692 "Connection: keep-alive\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:548693 };
8694
8695 MockRead data_reads1[] = {
8696 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8697 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8698 MockRead("Content-Length: 10\r\n\r\n"),
8699 MockRead(SYNCHRONOUS, ERR_FAILED),
8700 };
8701
8702 // After the challenge above, the transaction will be restarted using the
8703 // identity supplied by the user, not the one in the URL, to answer the
8704 // challenge.
8705 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:238706 MockWrite(
8707 "GET / HTTP/1.1\r\n"
8708 "Host: www.example.org\r\n"
8709 "Connection: keep-alive\r\n"
8710 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:548711 };
8712
8713 MockRead data_reads3[] = {
8714 MockRead("HTTP/1.0 200 OK\r\n"),
8715 MockRead("Content-Length: 100\r\n\r\n"),
8716 MockRead(SYNCHRONOUS, OK),
8717 };
8718
Ryan Sleevib8d7ea02018-05-07 20:01:018719 StaticSocketDataProvider data1(data_reads1, data_writes1);
8720 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]2217aa22013-10-11 03:03:548721 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8722 session_deps_.socket_factory->AddSocketDataProvider(&data3);
8723
8724 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:208725 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018726 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:548727 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018728 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168729 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:548730
bnc691fda62016-08-12 00:43:168731 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528732 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:548733 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
8734
8735 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:168736 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:018737 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:548738 rv = callback3.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 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528743 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:548744
8745 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:528746 EXPECT_FALSE(response->auth_challenge);
[email protected]2217aa22013-10-11 03:03:548747 EXPECT_EQ(100, response->headers->GetContentLength());
8748
8749 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:558750 base::RunLoop().RunUntilIdle();
[email protected]2217aa22013-10-11 03:03:548751}
8752
[email protected]f9ee6b52008-11-08 06:46:238753// Test that previously tried username/passwords for a realm get re-used.
bncd16676a2016-07-20 16:23:018754TEST_F(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
danakj1fd259a02016-04-16 03:17:098755 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:238756
8757 // Transaction 1: authenticate (foo, bar) on MyRealm1
8758 {
[email protected]1c773ea12009-04-28 19:58:428759 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238760 request.method = "GET";
bncce36dca22015-04-21 22:11:238761 request.url = GURL("http://www.example.org/x/y/z");
Ramin Halavatib5e433e2018-02-07 07:41:108762 request.traffic_annotation =
8763 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238764
bnc691fda62016-08-12 00:43:168765 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278766
[email protected]f9ee6b52008-11-08 06:46:238767 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238768 MockWrite(
8769 "GET /x/y/z HTTP/1.1\r\n"
8770 "Host: www.example.org\r\n"
8771 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238772 };
8773
8774 MockRead data_reads1[] = {
8775 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8776 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8777 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068778 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238779 };
8780
8781 // Resend with authorization (username=foo, password=bar)
8782 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238783 MockWrite(
8784 "GET /x/y/z HTTP/1.1\r\n"
8785 "Host: www.example.org\r\n"
8786 "Connection: keep-alive\r\n"
8787 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238788 };
8789
8790 // Sever accepts the authorization.
8791 MockRead data_reads2[] = {
8792 MockRead("HTTP/1.0 200 OK\r\n"),
8793 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068794 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238795 };
8796
Ryan Sleevib8d7ea02018-05-07 20:01:018797 StaticSocketDataProvider data1(data_reads1, data_writes1);
8798 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:078799 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8800 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:238801
[email protected]49639fa2011-12-20 23:22:418802 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238803
tfarina42834112016-09-22 13:38:208804 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018805 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238806
8807 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018808 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238809
bnc691fda62016-08-12 00:43:168810 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528811 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:048812 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:238813
[email protected]49639fa2011-12-20 23:22:418814 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:238815
bnc691fda62016-08-12 00:43:168816 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
8817 callback2.callback());
robpercival214763f2016-07-01 23:27:018818 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238819
8820 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018821 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238822
bnc691fda62016-08-12 00:43:168823 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528824 ASSERT_TRUE(response);
8825 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238826 EXPECT_EQ(100, response->headers->GetContentLength());
8827 }
8828
8829 // ------------------------------------------------------------------------
8830
8831 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
8832 {
[email protected]1c773ea12009-04-28 19:58:428833 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238834 request.method = "GET";
8835 // Note that Transaction 1 was at /x/y/z, so this is in the same
8836 // protection space as MyRealm1.
bncce36dca22015-04-21 22:11:238837 request.url = GURL("http://www.example.org/x/y/a/b");
Ramin Halavatib5e433e2018-02-07 07:41:108838 request.traffic_annotation =
8839 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238840
bnc691fda62016-08-12 00:43:168841 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278842
[email protected]f9ee6b52008-11-08 06:46:238843 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238844 MockWrite(
8845 "GET /x/y/a/b HTTP/1.1\r\n"
8846 "Host: www.example.org\r\n"
8847 "Connection: keep-alive\r\n"
8848 // Send preemptive authorization for MyRealm1
8849 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238850 };
8851
8852 // The server didn't like the preemptive authorization, and
8853 // challenges us for a different realm (MyRealm2).
8854 MockRead data_reads1[] = {
8855 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8856 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
8857 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068858 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238859 };
8860
8861 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
8862 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238863 MockWrite(
8864 "GET /x/y/a/b HTTP/1.1\r\n"
8865 "Host: www.example.org\r\n"
8866 "Connection: keep-alive\r\n"
8867 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238868 };
8869
8870 // Sever accepts the authorization.
8871 MockRead data_reads2[] = {
8872 MockRead("HTTP/1.0 200 OK\r\n"),
8873 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068874 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238875 };
8876
Ryan Sleevib8d7ea02018-05-07 20:01:018877 StaticSocketDataProvider data1(data_reads1, data_writes1);
8878 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:078879 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8880 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:238881
[email protected]49639fa2011-12-20 23:22:418882 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238883
tfarina42834112016-09-22 13:38:208884 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018885 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238886
8887 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018888 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238889
bnc691fda62016-08-12 00:43:168890 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528891 ASSERT_TRUE(response);
8892 ASSERT_TRUE(response->auth_challenge);
[email protected]79cb5c12011-09-12 13:12:048893 EXPECT_FALSE(response->auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:438894 EXPECT_EQ("http://www.example.org",
8895 response->auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:048896 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
aberentbba302d2015-12-03 10:20:198897 EXPECT_EQ(kBasicAuthScheme, response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:238898
[email protected]49639fa2011-12-20 23:22:418899 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:238900
bnc691fda62016-08-12 00:43:168901 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
8902 callback2.callback());
robpercival214763f2016-07-01 23:27:018903 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238904
8905 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018906 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238907
bnc691fda62016-08-12 00:43:168908 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528909 ASSERT_TRUE(response);
8910 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238911 EXPECT_EQ(100, response->headers->GetContentLength());
8912 }
8913
8914 // ------------------------------------------------------------------------
8915
8916 // Transaction 3: Resend a request in MyRealm's protection space --
8917 // succeed with preemptive authorization.
8918 {
[email protected]1c773ea12009-04-28 19:58:428919 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238920 request.method = "GET";
bncce36dca22015-04-21 22:11:238921 request.url = GURL("http://www.example.org/x/y/z2");
Ramin Halavatib5e433e2018-02-07 07:41:108922 request.traffic_annotation =
8923 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238924
bnc691fda62016-08-12 00:43:168925 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278926
[email protected]f9ee6b52008-11-08 06:46:238927 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238928 MockWrite(
8929 "GET /x/y/z2 HTTP/1.1\r\n"
8930 "Host: www.example.org\r\n"
8931 "Connection: keep-alive\r\n"
8932 // The authorization for MyRealm1 gets sent preemptively
8933 // (since the url is in the same protection space)
8934 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238935 };
8936
8937 // Sever accepts the preemptive authorization
8938 MockRead data_reads1[] = {
8939 MockRead("HTTP/1.0 200 OK\r\n"),
8940 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068941 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238942 };
8943
Ryan Sleevib8d7ea02018-05-07 20:01:018944 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:078945 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:238946
[email protected]49639fa2011-12-20 23:22:418947 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238948
tfarina42834112016-09-22 13:38:208949 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018950 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238951
8952 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018953 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238954
bnc691fda62016-08-12 00:43:168955 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528956 ASSERT_TRUE(response);
[email protected]f9ee6b52008-11-08 06:46:238957
wezca1070932016-05-26 20:30:528958 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238959 EXPECT_EQ(100, response->headers->GetContentLength());
8960 }
8961
8962 // ------------------------------------------------------------------------
8963
8964 // Transaction 4: request another URL in MyRealm (however the
8965 // url is not known to belong to the protection space, so no pre-auth).
8966 {
[email protected]1c773ea12009-04-28 19:58:428967 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238968 request.method = "GET";
bncce36dca22015-04-21 22:11:238969 request.url = GURL("http://www.example.org/x/1");
Ramin Halavatib5e433e2018-02-07 07:41:108970 request.traffic_annotation =
8971 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238972
bnc691fda62016-08-12 00:43:168973 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278974
[email protected]f9ee6b52008-11-08 06:46:238975 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238976 MockWrite(
8977 "GET /x/1 HTTP/1.1\r\n"
8978 "Host: www.example.org\r\n"
8979 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238980 };
8981
8982 MockRead data_reads1[] = {
8983 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8984 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8985 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068986 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238987 };
8988
8989 // Resend with authorization from MyRealm's cache.
8990 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238991 MockWrite(
8992 "GET /x/1 HTTP/1.1\r\n"
8993 "Host: www.example.org\r\n"
8994 "Connection: keep-alive\r\n"
8995 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238996 };
8997
8998 // Sever accepts the authorization.
8999 MockRead data_reads2[] = {
9000 MockRead("HTTP/1.0 200 OK\r\n"),
9001 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069002 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:239003 };
9004
Ryan Sleevib8d7ea02018-05-07 20:01:019005 StaticSocketDataProvider data1(data_reads1, data_writes1);
9006 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:079007 session_deps_.socket_factory->AddSocketDataProvider(&data1);
9008 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:239009
[email protected]49639fa2011-12-20 23:22:419010 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:239011
tfarina42834112016-09-22 13:38:209012 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019013 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:239014
9015 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019016 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:239017
bnc691fda62016-08-12 00:43:169018 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:419019 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:169020 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:019021 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:229022 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:019023 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:169024 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:229025
bnc691fda62016-08-12 00:43:169026 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529027 ASSERT_TRUE(response);
9028 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:239029 EXPECT_EQ(100, response->headers->GetContentLength());
9030 }
9031
9032 // ------------------------------------------------------------------------
9033
9034 // Transaction 5: request a URL in MyRealm, but the server rejects the
9035 // cached identity. Should invalidate and re-prompt.
9036 {
[email protected]1c773ea12009-04-28 19:58:429037 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:239038 request.method = "GET";
bncce36dca22015-04-21 22:11:239039 request.url = GURL("http://www.example.org/p/q/t");
Ramin Halavatib5e433e2018-02-07 07:41:109040 request.traffic_annotation =
9041 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:239042
bnc691fda62016-08-12 00:43:169043 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279044
[email protected]f9ee6b52008-11-08 06:46:239045 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239046 MockWrite(
9047 "GET /p/q/t HTTP/1.1\r\n"
9048 "Host: www.example.org\r\n"
9049 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:239050 };
9051
9052 MockRead data_reads1[] = {
9053 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
9054 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9055 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069056 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:239057 };
9058
9059 // Resend with authorization from cache for MyRealm.
9060 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:239061 MockWrite(
9062 "GET /p/q/t HTTP/1.1\r\n"
9063 "Host: www.example.org\r\n"
9064 "Connection: keep-alive\r\n"
9065 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:239066 };
9067
9068 // Sever rejects the authorization.
9069 MockRead data_reads2[] = {
9070 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
9071 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9072 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069073 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:239074 };
9075
9076 // At this point we should prompt for new credentials for MyRealm.
9077 // Restart with username=foo3, password=foo4.
9078 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:239079 MockWrite(
9080 "GET /p/q/t HTTP/1.1\r\n"
9081 "Host: www.example.org\r\n"
9082 "Connection: keep-alive\r\n"
9083 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:239084 };
9085
9086 // Sever accepts the authorization.
9087 MockRead data_reads3[] = {
9088 MockRead("HTTP/1.0 200 OK\r\n"),
9089 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069090 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:239091 };
9092
Ryan Sleevib8d7ea02018-05-07 20:01:019093 StaticSocketDataProvider data1(data_reads1, data_writes1);
9094 StaticSocketDataProvider data2(data_reads2, data_writes2);
9095 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]bb88e1d32013-05-03 23:11:079096 session_deps_.socket_factory->AddSocketDataProvider(&data1);
9097 session_deps_.socket_factory->AddSocketDataProvider(&data2);
9098 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:239099
[email protected]49639fa2011-12-20 23:22:419100 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:239101
tfarina42834112016-09-22 13:38:209102 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019103 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:239104
9105 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019106 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:239107
bnc691fda62016-08-12 00:43:169108 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:419109 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:169110 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:019111 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:229112 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:019113 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:169114 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:229115
bnc691fda62016-08-12 00:43:169116 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529117 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:049118 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:239119
[email protected]49639fa2011-12-20 23:22:419120 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:239121
bnc691fda62016-08-12 00:43:169122 rv = trans.RestartWithAuth(AuthCredentials(kFoo3, kBar3),
9123 callback3.callback());
robpercival214763f2016-07-01 23:27:019124 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:239125
[email protected]0757e7702009-03-27 04:00:229126 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:019127 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:239128
bnc691fda62016-08-12 00:43:169129 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529130 ASSERT_TRUE(response);
9131 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:239132 EXPECT_EQ(100, response->headers->GetContentLength());
9133 }
9134}
[email protected]89ceba9a2009-03-21 03:46:069135
[email protected]3c32c5f2010-05-18 15:18:129136// Tests that nonce count increments when multiple auth attempts
9137// are started with the same nonce.
bncd16676a2016-07-20 16:23:019138TEST_F(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:449139 HttpAuthHandlerDigest::Factory* digest_factory =
9140 new HttpAuthHandlerDigest::Factory();
9141 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
9142 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
9143 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:079144 session_deps_.http_auth_handler_factory.reset(digest_factory);
danakj1fd259a02016-04-16 03:17:099145 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:129146
9147 // Transaction 1: authenticate (foo, bar) on MyRealm1
9148 {
[email protected]3c32c5f2010-05-18 15:18:129149 HttpRequestInfo request;
9150 request.method = "GET";
bncce36dca22015-04-21 22:11:239151 request.url = GURL("http://www.example.org/x/y/z");
Ramin Halavatib5e433e2018-02-07 07:41:109152 request.traffic_annotation =
9153 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3c32c5f2010-05-18 15:18:129154
bnc691fda62016-08-12 00:43:169155 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279156
[email protected]3c32c5f2010-05-18 15:18:129157 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239158 MockWrite(
9159 "GET /x/y/z HTTP/1.1\r\n"
9160 "Host: www.example.org\r\n"
9161 "Connection: keep-alive\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:129162 };
9163
9164 MockRead data_reads1[] = {
9165 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
9166 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
9167 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069168 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:129169 };
9170
9171 // Resend with authorization (username=foo, password=bar)
9172 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:239173 MockWrite(
9174 "GET /x/y/z HTTP/1.1\r\n"
9175 "Host: www.example.org\r\n"
9176 "Connection: keep-alive\r\n"
9177 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
9178 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
9179 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
9180 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:129181 };
9182
9183 // Sever accepts the authorization.
9184 MockRead data_reads2[] = {
zmo9528c9f42015-08-04 22:12:089185 MockRead("HTTP/1.0 200 OK\r\n"),
9186 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:129187 };
9188
Ryan Sleevib8d7ea02018-05-07 20:01:019189 StaticSocketDataProvider data1(data_reads1, data_writes1);
9190 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:079191 session_deps_.socket_factory->AddSocketDataProvider(&data1);
9192 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:129193
[email protected]49639fa2011-12-20 23:22:419194 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:129195
tfarina42834112016-09-22 13:38:209196 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019197 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:129198
9199 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019200 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:129201
bnc691fda62016-08-12 00:43:169202 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529203 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:049204 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:129205
[email protected]49639fa2011-12-20 23:22:419206 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:129207
bnc691fda62016-08-12 00:43:169208 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
9209 callback2.callback());
robpercival214763f2016-07-01 23:27:019210 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:129211
9212 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:019213 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:129214
bnc691fda62016-08-12 00:43:169215 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529216 ASSERT_TRUE(response);
9217 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:129218 }
9219
9220 // ------------------------------------------------------------------------
9221
9222 // Transaction 2: Request another resource in digestive's protection space.
9223 // This will preemptively add an Authorization header which should have an
9224 // "nc" value of 2 (as compared to 1 in the first use.
9225 {
[email protected]3c32c5f2010-05-18 15:18:129226 HttpRequestInfo request;
9227 request.method = "GET";
9228 // Note that Transaction 1 was at /x/y/z, so this is in the same
9229 // protection space as digest.
bncce36dca22015-04-21 22:11:239230 request.url = GURL("http://www.example.org/x/y/a/b");
Ramin Halavatib5e433e2018-02-07 07:41:109231 request.traffic_annotation =
9232 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3c32c5f2010-05-18 15:18:129233
bnc691fda62016-08-12 00:43:169234 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279235
[email protected]3c32c5f2010-05-18 15:18:129236 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239237 MockWrite(
9238 "GET /x/y/a/b HTTP/1.1\r\n"
9239 "Host: www.example.org\r\n"
9240 "Connection: keep-alive\r\n"
9241 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
9242 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
9243 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
9244 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:129245 };
9246
9247 // Sever accepts the authorization.
9248 MockRead data_reads1[] = {
9249 MockRead("HTTP/1.0 200 OK\r\n"),
9250 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069251 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:129252 };
9253
Ryan Sleevib8d7ea02018-05-07 20:01:019254 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:079255 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:129256
[email protected]49639fa2011-12-20 23:22:419257 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:129258
tfarina42834112016-09-22 13:38:209259 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019260 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:129261
9262 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019263 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:129264
bnc691fda62016-08-12 00:43:169265 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529266 ASSERT_TRUE(response);
9267 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:129268 }
9269}
9270
[email protected]89ceba9a2009-03-21 03:46:069271// Test the ResetStateForRestart() private method.
bncd16676a2016-07-20 16:23:019272TEST_F(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:069273 // Create a transaction (the dependencies aren't important).
danakj1fd259a02016-04-16 03:17:099274 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169275 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]89ceba9a2009-03-21 03:46:069276
9277 // Setup some state (which we expect ResetStateForRestart() will clear).
Victor Costan9c7302b2018-08-27 16:39:449278 trans.read_buf_ = base::MakeRefCounted<IOBuffer>(15);
bnc691fda62016-08-12 00:43:169279 trans.read_buf_len_ = 15;
9280 trans.request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:069281
9282 // Setup state in response_
bnc691fda62016-08-12 00:43:169283 HttpResponseInfo* response = &trans.response_;
[email protected]0877e3d2009-10-17 22:29:579284 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:089285 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:579286 response->response_time = base::Time::Now();
9287 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:069288
9289 { // Setup state for response_.vary_data
9290 HttpRequestInfo request;
9291 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
9292 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:279293 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:439294 request.extra_headers.SetHeader("Foo", "1");
9295 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:509296 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:069297 }
9298
9299 // Cause the above state to be reset.
bnc691fda62016-08-12 00:43:169300 trans.ResetStateForRestart();
[email protected]89ceba9a2009-03-21 03:46:069301
9302 // Verify that the state that needed to be reset, has been reset.
bnc691fda62016-08-12 00:43:169303 EXPECT_FALSE(trans.read_buf_);
9304 EXPECT_EQ(0, trans.read_buf_len_);
9305 EXPECT_TRUE(trans.request_headers_.IsEmpty());
wezca1070932016-05-26 20:30:529306 EXPECT_FALSE(response->auth_challenge);
9307 EXPECT_FALSE(response->headers);
[email protected]34f40942010-10-04 00:34:049308 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:089309 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:579310 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:069311}
9312
[email protected]bacff652009-03-31 17:50:339313// Test HTTPS connections to a site with a bad certificate
bncd16676a2016-07-20 16:23:019314TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:339315 HttpRequestInfo request;
9316 request.method = "GET";
bncce36dca22015-04-21 22:11:239317 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109318 request.traffic_annotation =
9319 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]bacff652009-03-31 17:50:339320
danakj1fd259a02016-04-16 03:17:099321 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169322 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279323
[email protected]bacff652009-03-31 17:50:339324 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239325 MockWrite(
9326 "GET / HTTP/1.1\r\n"
9327 "Host: www.example.org\r\n"
9328 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:339329 };
9330
9331 MockRead data_reads[] = {
9332 MockRead("HTTP/1.0 200 OK\r\n"),
9333 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9334 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069335 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:339336 };
9337
[email protected]5ecc992a42009-11-11 01:41:599338 StaticSocketDataProvider ssl_bad_certificate;
Ryan Sleevib8d7ea02018-05-07 20:01:019339 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069340 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
9341 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:339342
[email protected]bb88e1d32013-05-03 23:11:079343 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
9344 session_deps_.socket_factory->AddSocketDataProvider(&data);
9345 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
9346 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:339347
[email protected]49639fa2011-12-20 23:22:419348 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:339349
tfarina42834112016-09-22 13:38:209350 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019351 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:339352
9353 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019354 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:339355
bnc691fda62016-08-12 00:43:169356 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:019357 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:339358
9359 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019360 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:339361
bnc691fda62016-08-12 00:43:169362 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:339363
wezca1070932016-05-26 20:30:529364 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:339365 EXPECT_EQ(100, response->headers->GetContentLength());
9366}
9367
9368// Test HTTPS connections to a site with a bad certificate, going through a
9369// proxy
bncd16676a2016-07-20 16:23:019370TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
Ramin Halavatica8d5252018-03-12 05:33:499371 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9372 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]bacff652009-03-31 17:50:339373
9374 HttpRequestInfo request;
9375 request.method = "GET";
bncce36dca22015-04-21 22:11:239376 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109377 request.traffic_annotation =
9378 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]bacff652009-03-31 17:50:339379
9380 MockWrite proxy_writes[] = {
rsleevidb16bb02015-11-12 23:47:179381 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9382 "Host: www.example.org:443\r\n"
9383 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:339384 };
9385
9386 MockRead proxy_reads[] = {
9387 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069388 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:339389 };
9390
9391 MockWrite data_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"),
9395 MockWrite("GET / HTTP/1.1\r\n"
9396 "Host: www.example.org\r\n"
9397 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:339398 };
9399
9400 MockRead data_reads[] = {
9401 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
9402 MockRead("HTTP/1.0 200 OK\r\n"),
9403 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9404 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069405 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:339406 };
9407
Ryan Sleevib8d7ea02018-05-07 20:01:019408 StaticSocketDataProvider ssl_bad_certificate(proxy_reads, proxy_writes);
9409 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069410 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
9411 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:339412
[email protected]bb88e1d32013-05-03 23:11:079413 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
9414 session_deps_.socket_factory->AddSocketDataProvider(&data);
9415 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
9416 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:339417
[email protected]49639fa2011-12-20 23:22:419418 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:339419
9420 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:079421 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:339422
danakj1fd259a02016-04-16 03:17:099423 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169424 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bacff652009-03-31 17:50:339425
tfarina42834112016-09-22 13:38:209426 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019427 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:339428
9429 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019430 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:339431
bnc691fda62016-08-12 00:43:169432 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:019433 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:339434
9435 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019436 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:339437
bnc691fda62016-08-12 00:43:169438 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:339439
wezca1070932016-05-26 20:30:529440 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:339441 EXPECT_EQ(100, response->headers->GetContentLength());
9442 }
9443}
9444
[email protected]2df19bb2010-08-25 20:13:469445
9446// Test HTTPS connections to a site, going through an HTTPS proxy
bncd16676a2016-07-20 16:23:019447TEST_F(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:599448 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499449 ProxyResolutionService::CreateFixedFromPacResult(
9450 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519451 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079452 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:469453
9454 HttpRequestInfo request;
9455 request.method = "GET";
bncce36dca22015-04-21 22:11:239456 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109457 request.traffic_annotation =
9458 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:469459
9460 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179461 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9462 "Host: www.example.org:443\r\n"
9463 "Proxy-Connection: keep-alive\r\n\r\n"),
9464 MockWrite("GET / HTTP/1.1\r\n"
9465 "Host: www.example.org\r\n"
9466 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:469467 };
9468
9469 MockRead data_reads[] = {
9470 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
9471 MockRead("HTTP/1.1 200 OK\r\n"),
9472 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9473 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069474 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:469475 };
9476
Ryan Sleevib8d7ea02018-05-07 20:01:019477 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069478 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
9479 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:469480
[email protected]bb88e1d32013-05-03 23:11:079481 session_deps_.socket_factory->AddSocketDataProvider(&data);
9482 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
9483 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:469484
[email protected]49639fa2011-12-20 23:22:419485 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:469486
danakj1fd259a02016-04-16 03:17:099487 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169488 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:469489
tfarina42834112016-09-22 13:38:209490 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019491 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:469492
9493 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019494 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:169495 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:469496
wezca1070932016-05-26 20:30:529497 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:469498
tbansal2ecbbc72016-10-06 17:15:479499 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:469500 EXPECT_TRUE(response->headers->IsKeepAlive());
9501 EXPECT_EQ(200, response->headers->response_code());
9502 EXPECT_EQ(100, response->headers->GetContentLength());
9503 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:209504
9505 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169506 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209507 TestLoadTimingNotReusedWithPac(load_timing_info,
9508 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:469509}
9510
Eric Roman74103c72019-02-21 00:23:129511// Test that an HTTPS Proxy can redirect a CONNECT request for main frames.
bncd16676a2016-07-20 16:23:019512TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:599513 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499514 ProxyResolutionService::CreateFixedFromPacResult(
9515 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519516 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079517 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:299518
Matt Menkeecfecfc72019-02-05 19:15:289519 base::TimeTicks start_time = base::TimeTicks::Now();
9520 const base::TimeDelta kTimeIncrement = base::TimeDelta::FromSeconds(4);
9521 session_deps_.host_resolver->set_ondemand_mode(true);
9522
[email protected]511f6f52010-12-17 03:58:299523 HttpRequestInfo request;
Eric Roman74103c72019-02-21 00:23:129524 request.load_flags = LOAD_MAIN_FRAME_DEPRECATED;
[email protected]511f6f52010-12-17 03:58:299525 request.method = "GET";
bncce36dca22015-04-21 22:11:239526 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109527 request.traffic_annotation =
9528 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299529
9530 MockWrite data_writes[] = {
Matt Menkeecfecfc72019-02-05 19:15:289531 MockWrite(ASYNC, 0,
9532 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:179533 "Host: www.example.org:443\r\n"
9534 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:299535 };
9536
9537 MockRead data_reads[] = {
Matt Menkeecfecfc72019-02-05 19:15:289538 // Pause on first read.
9539 MockRead(ASYNC, ERR_IO_PENDING, 1),
9540 MockRead(ASYNC, 2, "HTTP/1.1 302 Redirect\r\n"),
9541 MockRead(ASYNC, 3, "Location: http://login.example.com/\r\n"),
9542 MockRead(ASYNC, 4, "Content-Length: 0\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:299543 };
9544
Matt Menkeecfecfc72019-02-05 19:15:289545 SequencedSocketData data(MockConnect(ASYNC, OK), data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069546 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:299547
[email protected]bb88e1d32013-05-03 23:11:079548 session_deps_.socket_factory->AddSocketDataProvider(&data);
9549 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:299550
[email protected]49639fa2011-12-20 23:22:419551 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:299552
danakj1fd259a02016-04-16 03:17:099553 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169554 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:299555
tfarina42834112016-09-22 13:38:209556 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019557 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Matt Menkeecfecfc72019-02-05 19:15:289558 EXPECT_TRUE(session_deps_.host_resolver->has_pending_requests());
9559
9560 // Host resolution takes |kTimeIncrement|.
9561 FastForwardBy(kTimeIncrement);
9562 // Resolving the current request with |ResolveNow| will cause the pending
9563 // request to instantly complete, and the async connect will start as well.
9564 session_deps_.host_resolver->ResolveOnlyRequestNow();
9565
9566 // Connecting takes |kTimeIncrement|.
9567 FastForwardBy(kTimeIncrement);
9568 data.RunUntilPaused();
9569
9570 // The server takes |kTimeIncrement| to respond.
9571 FastForwardBy(kTimeIncrement);
9572 data.Resume();
[email protected]511f6f52010-12-17 03:58:299573
9574 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019575 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:169576 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:299577
wezca1070932016-05-26 20:30:529578 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:299579
9580 EXPECT_EQ(302, response->headers->response_code());
9581 std::string url;
9582 EXPECT_TRUE(response->headers->IsRedirect(&url));
9583 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:209584
[email protected]029c83b62013-01-24 05:28:209585 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169586 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209587
9588 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:199589 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:209590
Matt Menkeecfecfc72019-02-05 19:15:289591 // In the case of redirects from proxies, just as with all responses from
9592 // proxies, DNS and SSL times reflect timing to look up the destination's
9593 // name, and negotiate an SSL connection to it (Neither of which are done in
9594 // this case), which the DNS and SSL times for the proxy are all included in
9595 // connect_start / connect_end. See
Eric Roman74103c72019-02-21 00:23:129596 // HttpNetworkTransaction::OnHttpsProxyTunnelResponseRedirect
Matt Menkeecfecfc72019-02-05 19:15:289597
9598 EXPECT_TRUE(load_timing_info.connect_timing.dns_start.is_null());
9599 EXPECT_TRUE(load_timing_info.connect_timing.dns_end.is_null());
9600 EXPECT_TRUE(load_timing_info.connect_timing.ssl_start.is_null());
9601 EXPECT_TRUE(load_timing_info.connect_timing.ssl_end.is_null());
9602
9603 EXPECT_EQ(start_time, load_timing_info.proxy_resolve_start);
9604 EXPECT_EQ(start_time, load_timing_info.proxy_resolve_end);
9605 EXPECT_EQ(start_time, load_timing_info.connect_timing.connect_start);
9606 EXPECT_EQ(start_time + 3 * kTimeIncrement,
9607 load_timing_info.connect_timing.connect_end);
[email protected]029c83b62013-01-24 05:28:209608
9609 EXPECT_TRUE(load_timing_info.send_start.is_null());
9610 EXPECT_TRUE(load_timing_info.send_end.is_null());
9611 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:299612}
9613
Eric Roman74103c72019-02-21 00:23:129614// Test that an HTTPS Proxy cannot redirect a CONNECT request for subresources.
9615TEST_F(HttpNetworkTransactionTest,
9616 RedirectOfHttpsConnectSubresourceViaHttpsProxy) {
9617 base::HistogramTester histograms;
9618 session_deps_.proxy_resolution_service =
9619 ProxyResolutionService::CreateFixedFromPacResult(
9620 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
9621 TestNetLog net_log;
9622 session_deps_.net_log = &net_log;
9623
9624 HttpRequestInfo request;
9625 request.method = "GET";
9626 request.url = GURL("https://www.example.org/");
9627 request.traffic_annotation =
9628 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9629
9630 MockWrite data_writes[] = {
9631 MockWrite(ASYNC, 0,
9632 "CONNECT www.example.org:443 HTTP/1.1\r\n"
9633 "Host: www.example.org:443\r\n"
9634 "Proxy-Connection: keep-alive\r\n\r\n"),
9635 };
9636
9637 MockRead data_reads[] = {
9638 MockRead(ASYNC, 1, "HTTP/1.1 302 Redirect\r\n"),
9639 MockRead(ASYNC, 2, "Location: http://login.example.com/\r\n"),
9640 MockRead(ASYNC, 3, "Content-Length: 0\r\n\r\n"),
9641 };
9642
9643 SequencedSocketData data(MockConnect(ASYNC, OK), data_reads, data_writes);
9644 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
9645
9646 session_deps_.socket_factory->AddSocketDataProvider(&data);
9647 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
9648
9649 TestCompletionCallback callback;
9650
9651 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9652 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
9653
9654 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
9655 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9656
9657 rv = callback.WaitForResult();
9658 EXPECT_THAT(rv, IsError(ERR_HTTPS_PROXY_TUNNEL_RESPONSE_REDIRECT));
9659
9660 histograms.ExpectUniqueSample(
9661 "Net.Proxy.RedirectDuringConnect",
9662 HttpNetworkTransaction::kSubresourceByExplicitProxy, 1);
9663}
9664
9665// Test that an HTTPS Proxy which was auto-detected cannot redirect a CONNECT
9666// request for main frames.
9667TEST_F(HttpNetworkTransactionTest,
9668 RedirectOfHttpsConnectViaAutoDetectedHttpsProxy) {
9669 base::HistogramTester histograms;
9670 session_deps_.proxy_resolution_service =
9671 ProxyResolutionService::CreateFixedFromAutoDetectedPacResult(
9672 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
9673 TestNetLog net_log;
9674 session_deps_.net_log = &net_log;
9675
9676 HttpRequestInfo request;
9677 request.load_flags = LOAD_MAIN_FRAME_DEPRECATED;
9678 request.method = "GET";
9679 request.url = GURL("https://www.example.org/");
9680 request.traffic_annotation =
9681 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9682
9683 MockWrite data_writes[] = {
9684 MockWrite(ASYNC, 0,
9685 "CONNECT www.example.org:443 HTTP/1.1\r\n"
9686 "Host: www.example.org:443\r\n"
9687 "Proxy-Connection: keep-alive\r\n\r\n"),
9688 };
9689
9690 MockRead data_reads[] = {
9691 MockRead(ASYNC, 1, "HTTP/1.1 302 Redirect\r\n"),
9692 MockRead(ASYNC, 2, "Location: http://login.example.com/\r\n"),
9693 MockRead(ASYNC, 3, "Content-Length: 0\r\n\r\n"),
9694 };
9695
9696 SequencedSocketData data(MockConnect(ASYNC, OK), data_reads, data_writes);
9697 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
9698
9699 session_deps_.socket_factory->AddSocketDataProvider(&data);
9700 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
9701
9702 TestCompletionCallback callback;
9703
9704 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9705 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
9706
9707 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
9708 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9709
9710 rv = callback.WaitForResult();
9711 EXPECT_THAT(rv, IsError(ERR_HTTPS_PROXY_TUNNEL_RESPONSE_REDIRECT));
9712
9713 histograms.ExpectUniqueSample(
9714 "Net.Proxy.RedirectDuringConnect",
9715 HttpNetworkTransaction::kMainFrameByAutoDetectedProxy, 1);
9716}
9717
9718// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request for main
9719// frames.
bncd16676a2016-07-20 16:23:019720TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
Eric Roman74103c72019-02-21 00:23:129721 base::HistogramTester histograms;
Ramin Halavatica8d5252018-03-12 05:33:499722 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9723 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Matt Menkeecfecfc72019-02-05 19:15:289724 TestNetLog net_log;
9725 session_deps_.net_log = &net_log;
9726
9727 base::TimeTicks start_time = base::TimeTicks::Now();
9728 const base::TimeDelta kTimeIncrement = base::TimeDelta::FromSeconds(4);
9729 session_deps_.host_resolver->set_ondemand_mode(true);
[email protected]511f6f52010-12-17 03:58:299730
9731 HttpRequestInfo request;
9732 request.method = "GET";
Eric Roman74103c72019-02-21 00:23:129733 request.load_flags = LOAD_MAIN_FRAME_DEPRECATED;
bncce36dca22015-04-21 22:11:239734 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109735 request.traffic_annotation =
9736 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299737
Ryan Hamilton0239aac2018-05-19 00:03:139738 spdy::SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
Raul Tambre94493c652019-03-11 17:18:359739 nullptr, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:139740 spdy::SpdySerializedFrame goaway(
9741 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:299742 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:419743 CreateMockWrite(conn, 0, SYNCHRONOUS),
Matt Menkeecfecfc72019-02-05 19:15:289744 CreateMockWrite(goaway, 3, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:299745 };
9746
9747 static const char* const kExtraHeaders[] = {
9748 "location",
9749 "http://login.example.com/",
9750 };
Ryan Hamilton0239aac2018-05-19 00:03:139751 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
Avi Drissman4365a4782018-12-28 19:26:249752 "302", kExtraHeaders, base::size(kExtraHeaders) / 2, 1));
[email protected]511f6f52010-12-17 03:58:299753 MockRead data_reads[] = {
Matt Menkeecfecfc72019-02-05 19:15:289754 // Pause on first read.
9755 MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(resp, 2),
9756 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:299757 };
9758
Matt Menkeecfecfc72019-02-05 19:15:289759 SequencedSocketData data(MockConnect(ASYNC, OK), data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069760 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:369761 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:299762
[email protected]bb88e1d32013-05-03 23:11:079763 session_deps_.socket_factory->AddSocketDataProvider(&data);
9764 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:299765
[email protected]49639fa2011-12-20 23:22:419766 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:299767
danakj1fd259a02016-04-16 03:17:099768 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169769 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:299770
tfarina42834112016-09-22 13:38:209771 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019772 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Matt Menkeecfecfc72019-02-05 19:15:289773 EXPECT_TRUE(session_deps_.host_resolver->has_pending_requests());
[email protected]511f6f52010-12-17 03:58:299774
Matt Menkeecfecfc72019-02-05 19:15:289775 // Host resolution takes |kTimeIncrement|.
9776 FastForwardBy(kTimeIncrement);
9777 // Resolving the current request with |ResolveNow| will cause the pending
9778 // request to instantly complete, and the async connect will start as well.
9779 session_deps_.host_resolver->ResolveOnlyRequestNow();
9780
9781 // Connecting takes |kTimeIncrement|.
9782 FastForwardBy(kTimeIncrement);
9783 data.RunUntilPaused();
9784
9785 FastForwardBy(kTimeIncrement);
9786 data.Resume();
[email protected]511f6f52010-12-17 03:58:299787 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019788 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:169789 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:299790
wezca1070932016-05-26 20:30:529791 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:299792
9793 EXPECT_EQ(302, response->headers->response_code());
9794 std::string url;
9795 EXPECT_TRUE(response->headers->IsRedirect(&url));
9796 EXPECT_EQ("http://login.example.com/", url);
Matt Menkeecfecfc72019-02-05 19:15:289797
9798 LoadTimingInfo load_timing_info;
9799 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
9800
9801 EXPECT_FALSE(load_timing_info.socket_reused);
9802 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
9803
9804 // No proxy resolution times, since there's no PAC script.
9805 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
9806 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
9807
9808 // In the case of redirects from proxies, just as with all responses from
9809 // proxies, DNS and SSL times reflect timing to look up the destination's
9810 // name, and negotiate an SSL connection to it (Neither of which are done in
9811 // this case), which the DNS and SSL times for the proxy are all included in
9812 // connect_start / connect_end. See
Eric Roman74103c72019-02-21 00:23:129813 // HttpNetworkTransaction::OnHttpsProxyTunnelResponseRedirect.
Matt Menkeecfecfc72019-02-05 19:15:289814
9815 EXPECT_TRUE(load_timing_info.connect_timing.dns_start.is_null());
9816 EXPECT_TRUE(load_timing_info.connect_timing.dns_end.is_null());
9817 EXPECT_TRUE(load_timing_info.connect_timing.ssl_start.is_null());
9818 EXPECT_TRUE(load_timing_info.connect_timing.ssl_end.is_null());
9819
9820 EXPECT_EQ(start_time, load_timing_info.connect_timing.connect_start);
9821 EXPECT_EQ(start_time + 3 * kTimeIncrement,
9822 load_timing_info.connect_timing.connect_end);
9823
9824 EXPECT_TRUE(load_timing_info.send_start.is_null());
9825 EXPECT_TRUE(load_timing_info.send_end.is_null());
9826 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
Eric Roman74103c72019-02-21 00:23:129827
9828 histograms.ExpectUniqueSample(
9829 "Net.Proxy.RedirectDuringConnect",
9830 HttpNetworkTransaction::kMainFrameByExplicitProxy, 1);
[email protected]511f6f52010-12-17 03:58:299831}
9832
[email protected]4eddbc732012-08-09 05:40:179833// Test that an HTTPS proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:019834TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaHttpsProxy) {
Ramin Halavatica8d5252018-03-12 05:33:499835 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9836 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299837
9838 HttpRequestInfo request;
9839 request.method = "GET";
bncce36dca22015-04-21 22:11:239840 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109841 request.traffic_annotation =
9842 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299843
9844 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179845 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9846 "Host: www.example.org:443\r\n"
9847 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:299848 };
9849
9850 MockRead data_reads[] = {
9851 MockRead("HTTP/1.1 404 Not Found\r\n"),
9852 MockRead("Content-Length: 23\r\n\r\n"),
9853 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:069854 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:299855 };
9856
Ryan Sleevib8d7ea02018-05-07 20:01:019857 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069858 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:299859
[email protected]bb88e1d32013-05-03 23:11:079860 session_deps_.socket_factory->AddSocketDataProvider(&data);
9861 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:299862
[email protected]49639fa2011-12-20 23:22:419863 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:299864
danakj1fd259a02016-04-16 03:17:099865 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169866 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:299867
tfarina42834112016-09-22 13:38:209868 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019869 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:299870
9871 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019872 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:299873
ttuttle960fcbf2016-04-19 13:26:329874 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:299875}
9876
[email protected]4eddbc732012-08-09 05:40:179877// Test that a SPDY proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:019878TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaSpdyProxy) {
Ramin Halavatica8d5252018-03-12 05:33:499879 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9880 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299881
9882 HttpRequestInfo request;
9883 request.method = "GET";
bncce36dca22015-04-21 22:11:239884 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109885 request.traffic_annotation =
9886 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299887
Ryan Hamilton0239aac2018-05-19 00:03:139888 spdy::SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
Raul Tambre94493c652019-03-11 17:18:359889 nullptr, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:139890 spdy::SpdySerializedFrame rst(
9891 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:299892 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:419893 CreateMockWrite(conn, 0), CreateMockWrite(rst, 3),
[email protected]511f6f52010-12-17 03:58:299894 };
9895
9896 static const char* const kExtraHeaders[] = {
9897 "location",
9898 "http://login.example.com/",
9899 };
Ryan Hamilton0239aac2018-05-19 00:03:139900 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
Avi Drissman4365a4782018-12-28 19:26:249901 "404", kExtraHeaders, base::size(kExtraHeaders) / 2, 1));
Ryan Hamilton0239aac2018-05-19 00:03:139902 spdy::SpdySerializedFrame body(
Bence Békyd74f4382018-02-20 18:26:199903 spdy_util_.ConstructSpdyDataFrame(1, "The host does not exist", true));
[email protected]511f6f52010-12-17 03:58:299904 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:419905 CreateMockRead(resp, 1), CreateMockRead(body, 2),
rch8e6c6c42015-05-01 14:05:139906 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:299907 };
9908
Ryan Sleevib8d7ea02018-05-07 20:01:019909 SequencedSocketData data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069910 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:369911 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:299912
[email protected]bb88e1d32013-05-03 23:11:079913 session_deps_.socket_factory->AddSocketDataProvider(&data);
9914 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:299915
[email protected]49639fa2011-12-20 23:22:419916 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:299917
danakj1fd259a02016-04-16 03:17:099918 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169919 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:299920
tfarina42834112016-09-22 13:38:209921 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019922 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:299923
9924 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019925 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:299926
ttuttle960fcbf2016-04-19 13:26:329927 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:299928}
9929
[email protected]0c5fb722012-02-28 11:50:359930// Test the request-challenge-retry sequence for basic auth, through
9931// a SPDY proxy over a single SPDY session.
bncd16676a2016-07-20 16:23:019932TEST_F(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:359933 HttpRequestInfo request;
9934 request.method = "GET";
bncce36dca22015-04-21 22:11:239935 request.url = GURL("https://www.example.org/");
[email protected]0c5fb722012-02-28 11:50:359936 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:299937 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:109938 request.traffic_annotation =
9939 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0c5fb722012-02-28 11:50:359940
9941 // Configure against https proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:599942 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499943 ProxyResolutionService::CreateFixedFromPacResult(
9944 "HTTPS myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519945 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:079946 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:099947 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:359948
9949 // Since we have proxy, should try to establish tunnel.
Ryan Hamilton0239aac2018-05-19 00:03:139950 spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyConnect(
Raul Tambre94493c652019-03-11 17:18:359951 nullptr, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:139952 spdy::SpdySerializedFrame rst(
9953 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
rdsmithebb50aa2015-11-12 03:44:389954 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]0c5fb722012-02-28 11:50:359955
bnc691fda62016-08-12 00:43:169956 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0c5fb722012-02-28 11:50:359957 // be issuing -- the final header line contains the credentials.
9958 const char* const kAuthCredentials[] = {
9959 "proxy-authorization", "Basic Zm9vOmJhcg==",
9960 };
Ryan Hamilton0239aac2018-05-19 00:03:139961 spdy::SpdySerializedFrame connect2(spdy_util_.ConstructSpdyConnect(
Avi Drissman4365a4782018-12-28 19:26:249962 kAuthCredentials, base::size(kAuthCredentials) / 2, 3, LOWEST,
bncce36dca22015-04-21 22:11:239963 HostPortPair("www.example.org", 443)));
9964 // fetch https://www.example.org/ via HTTP
9965 const char get[] =
9966 "GET / HTTP/1.1\r\n"
9967 "Host: www.example.org\r\n"
9968 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:139969 spdy::SpdySerializedFrame wrapped_get(
Bence Békyd74f4382018-02-20 18:26:199970 spdy_util_.ConstructSpdyDataFrame(3, get, false));
[email protected]0c5fb722012-02-28 11:50:359971
9972 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:419973 CreateMockWrite(req, 0, ASYNC), CreateMockWrite(rst, 2, ASYNC),
9974 CreateMockWrite(connect2, 3), CreateMockWrite(wrapped_get, 5),
[email protected]0c5fb722012-02-28 11:50:359975 };
9976
9977 // The proxy responds to the connect with a 407, using a persistent
9978 // connection.
thestig9d3bb0c2015-01-24 00:49:519979 const char kAuthStatus[] = "407";
[email protected]0c5fb722012-02-28 11:50:359980 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:359981 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
9982 };
Ryan Hamilton0239aac2018-05-19 00:03:139983 spdy::SpdySerializedFrame conn_auth_resp(spdy_util_.ConstructSpdyReplyError(
Avi Drissman4365a4782018-12-28 19:26:249984 kAuthStatus, kAuthChallenge, base::size(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:359985
Ryan Hamilton0239aac2018-05-19 00:03:139986 spdy::SpdySerializedFrame conn_resp(
Raul Tambre94493c652019-03-11 17:18:359987 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
[email protected]0c5fb722012-02-28 11:50:359988 const char resp[] = "HTTP/1.1 200 OK\r\n"
9989 "Content-Length: 5\r\n\r\n";
9990
Ryan Hamilton0239aac2018-05-19 00:03:139991 spdy::SpdySerializedFrame wrapped_get_resp(
Bence Békyd74f4382018-02-20 18:26:199992 spdy_util_.ConstructSpdyDataFrame(3, resp, false));
Ryan Hamilton0239aac2018-05-19 00:03:139993 spdy::SpdySerializedFrame wrapped_body(
Bence Békyd74f4382018-02-20 18:26:199994 spdy_util_.ConstructSpdyDataFrame(3, "hello", false));
[email protected]0c5fb722012-02-28 11:50:359995 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:419996 CreateMockRead(conn_auth_resp, 1, ASYNC),
9997 CreateMockRead(conn_resp, 4, ASYNC),
9998 CreateMockRead(wrapped_get_resp, 6, ASYNC),
9999 CreateMockRead(wrapped_body, 7, ASYNC),
rch8e6c6c42015-05-01 14:05:1310000 MockRead(ASYNC, OK, 8), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:3510001 };
10002
Ryan Sleevib8d7ea02018-05-07 20:01:0110003 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0710004 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:3510005 // Negotiate SPDY to the proxy
10006 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610007 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0710008 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:3510009 // Vanilla SSL to the server
10010 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710011 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:3510012
10013 TestCompletionCallback callback1;
10014
bnc87dcefc2017-05-25 12:47:5810015 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1910016 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0c5fb722012-02-28 11:50:3510017
10018 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0110019 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:3510020
10021 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0110022 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:4610023 TestNetLogEntry::List entries;
[email protected]0c5fb722012-02-28 11:50:3510024 log.GetEntries(&entries);
10025 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0010026 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
10027 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:3510028 ExpectLogContainsSomewhere(
10029 entries, pos,
mikecirone8b85c432016-09-08 19:11:0010030 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
10031 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:3510032
10033 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210034 ASSERT_TRUE(response);
10035 ASSERT_TRUE(response->headers);
[email protected]0c5fb722012-02-28 11:50:3510036 EXPECT_EQ(407, response->headers->response_code());
10037 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
wezca1070932016-05-26 20:30:5210038 EXPECT_TRUE(response->auth_challenge);
asanka098c0092016-06-16 20:18:4310039 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]0c5fb722012-02-28 11:50:3510040
10041 TestCompletionCallback callback2;
10042
10043 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
10044 callback2.callback());
robpercival214763f2016-07-01 23:27:0110045 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:3510046
10047 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0110048 EXPECT_THAT(rv, IsOk());
[email protected]0c5fb722012-02-28 11:50:3510049
10050 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210051 ASSERT_TRUE(response);
[email protected]0c5fb722012-02-28 11:50:3510052
10053 EXPECT_TRUE(response->headers->IsKeepAlive());
10054 EXPECT_EQ(200, response->headers->response_code());
10055 EXPECT_EQ(5, response->headers->GetContentLength());
10056 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10057
10058 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:5210059 EXPECT_FALSE(response->auth_challenge);
[email protected]0c5fb722012-02-28 11:50:3510060
[email protected]029c83b62013-01-24 05:28:2010061 LoadTimingInfo load_timing_info;
10062 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10063 TestLoadTimingNotReusedWithPac(load_timing_info,
10064 CONNECT_TIMING_HAS_SSL_TIMES);
10065
[email protected]0c5fb722012-02-28 11:50:3510066 trans.reset();
10067 session->CloseAllConnections();
10068}
10069
[email protected]7c6f7ba2012-04-03 04:09:2910070// Test that an explicitly trusted SPDY proxy can push a resource from an
10071// origin that is different from that of its associated resource.
bncd16676a2016-07-20 16:23:0110072TEST_F(HttpNetworkTransactionTest, CrossOriginSPDYProxyPush) {
tbansal28e68f82016-02-04 02:56:1510073 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:1910074 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:1510075 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
10076 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]7c6f7ba2012-04-03 04:09:2910077 HttpRequestInfo request;
10078 HttpRequestInfo push_request;
Ramin Halavatib5e433e2018-02-07 07:41:1010079 request.traffic_annotation =
10080 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7c6f7ba2012-04-03 04:09:2910081
[email protected]7c6f7ba2012-04-03 04:09:2910082 request.method = "GET";
bncce36dca22015-04-21 22:11:2310083 request.url = GURL("http://www.example.org/");
[email protected]7c6f7ba2012-04-03 04:09:2910084 push_request.method = "GET";
10085 push_request.url = GURL("http://www.another-origin.com/foo.dat");
Ramin Halavatib5e433e2018-02-07 07:41:1010086 push_request.traffic_annotation =
10087 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7c6f7ba2012-04-03 04:09:2910088
tbansal28e68f82016-02-04 02:56:1510089 // Configure against https proxy server "myproxy:443".
Lily Houghton8c2f97d2018-01-22 05:06:5910090 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910091 ProxyResolutionService::CreateFixedFromPacResult(
10092 "HTTPS myproxy:443", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110093 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710094 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:5010095
Eric Roman3d8546a2018-09-10 17:00:5210096 session_deps_.proxy_resolution_service->SetProxyDelegate(
10097 proxy_delegate.get());
[email protected]61b4efc2012-04-27 18:12:5010098
danakj1fd259a02016-04-16 03:17:0910099 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:2910100
Ryan Hamilton0239aac2018-05-19 00:03:1310101 spdy::SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:4510102 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1310103 spdy::SpdySerializedFrame stream2_priority(
tombergan5d22c182017-01-11 02:05:3510104 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
[email protected]7c6f7ba2012-04-03 04:09:2910105
10106 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4110107 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:3510108 CreateMockWrite(stream2_priority, 3, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:2910109 };
10110
Ryan Hamilton0239aac2018-05-19 00:03:1310111 spdy::SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
Raul Tambre94493c652019-03-11 17:18:3510112 nullptr, 0, 2, 1, "http://www.another-origin.com/foo.dat"));
Bence Béky7bf94362018-01-10 13:19:3610113
Ryan Hamilton0239aac2018-05-19 00:03:1310114 spdy::SpdySerializedFrame stream1_reply(
Raul Tambre94493c652019-03-11 17:18:3510115 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:2910116
Ryan Hamilton0239aac2018-05-19 00:03:1310117 spdy::SpdySerializedFrame stream1_body(
10118 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:2910119
Ryan Hamilton0239aac2018-05-19 00:03:1310120 spdy::SpdySerializedFrame stream2_body(
Bence Békyd74f4382018-02-20 18:26:1910121 spdy_util_.ConstructSpdyDataFrame(2, "pushed", true));
[email protected]7c6f7ba2012-04-03 04:09:2910122
10123 MockRead spdy_reads[] = {
Bence Béky7bf94362018-01-10 13:19:3610124 CreateMockRead(stream2_syn, 1, ASYNC),
10125 CreateMockRead(stream1_reply, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:3510126 CreateMockRead(stream1_body, 4, ASYNC),
10127 CreateMockRead(stream2_body, 5, ASYNC),
10128 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
[email protected]7c6f7ba2012-04-03 04:09:2910129 };
10130
Ryan Sleevib8d7ea02018-05-07 20:01:0110131 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0710132 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:2910133 // Negotiate SPDY to the proxy
10134 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610135 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0710136 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:2910137
bnc87dcefc2017-05-25 12:47:5810138 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1910139 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7c6f7ba2012-04-03 04:09:2910140 TestCompletionCallback callback;
10141 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0110142 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:2910143
10144 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110145 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:2910146 const HttpResponseInfo* response = trans->GetResponseInfo();
10147
bnc87dcefc2017-05-25 12:47:5810148 auto push_trans =
Jeremy Roman0579ed62017-08-29 15:56:1910149 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]90499482013-06-01 00:39:5010150 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0110151 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:2910152
10153 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110154 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:2910155 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
10156
wezca1070932016-05-26 20:30:5210157 ASSERT_TRUE(response);
[email protected]7c6f7ba2012-04-03 04:09:2910158 EXPECT_TRUE(response->headers->IsKeepAlive());
10159
10160 EXPECT_EQ(200, response->headers->response_code());
10161 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10162
10163 std::string response_data;
10164 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:0110165 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:2910166 EXPECT_EQ("hello!", response_data);
10167
[email protected]029c83b62013-01-24 05:28:2010168 LoadTimingInfo load_timing_info;
10169 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10170 TestLoadTimingNotReusedWithPac(load_timing_info,
10171 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
10172
[email protected]7c6f7ba2012-04-03 04:09:2910173 // Verify the pushed stream.
wezca1070932016-05-26 20:30:5210174 EXPECT_TRUE(push_response->headers);
[email protected]7c6f7ba2012-04-03 04:09:2910175 EXPECT_EQ(200, push_response->headers->response_code());
10176
10177 rv = ReadTransaction(push_trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:0110178 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:2910179 EXPECT_EQ("pushed", response_data);
10180
[email protected]029c83b62013-01-24 05:28:2010181 LoadTimingInfo push_load_timing_info;
10182 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
10183 TestLoadTimingReusedWithPac(push_load_timing_info);
10184 // The transactions should share a socket ID, despite being for different
10185 // origins.
10186 EXPECT_EQ(load_timing_info.socket_log_id,
10187 push_load_timing_info.socket_log_id);
10188
[email protected]7c6f7ba2012-04-03 04:09:2910189 trans.reset();
10190 push_trans.reset();
10191 session->CloseAllConnections();
10192}
10193
[email protected]8c843192012-04-05 07:15:0010194// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
bncd16676a2016-07-20 16:23:0110195TEST_F(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:1510196 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:1910197 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:1510198 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
10199 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]8c843192012-04-05 07:15:0010200 HttpRequestInfo request;
10201
10202 request.method = "GET";
bncce36dca22015-04-21 22:11:2310203 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010204 request.traffic_annotation =
10205 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c843192012-04-05 07:15:0010206
Ramin Halavatica8d5252018-03-12 05:33:4910207 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
10208 "https://myproxy:443", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110209 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710210 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:5010211
10212 // Enable cross-origin push.
Eric Roman3d8546a2018-09-10 17:00:5210213 session_deps_.proxy_resolution_service->SetProxyDelegate(
10214 proxy_delegate.get());
[email protected]61b4efc2012-04-27 18:12:5010215
danakj1fd259a02016-04-16 03:17:0910216 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:0010217
Ryan Hamilton0239aac2018-05-19 00:03:1310218 spdy::SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:4510219 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
[email protected]8c843192012-04-05 07:15:0010220
Ryan Hamilton0239aac2018-05-19 00:03:1310221 spdy::SpdySerializedFrame push_rst(
10222 spdy_util_.ConstructSpdyRstStream(2, spdy::ERROR_CODE_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:0010223
10224 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4110225 CreateMockWrite(stream1_syn, 0, ASYNC), CreateMockWrite(push_rst, 3),
[email protected]8c843192012-04-05 07:15:0010226 };
10227
Ryan Hamilton0239aac2018-05-19 00:03:1310228 spdy::SpdySerializedFrame stream1_reply(
Raul Tambre94493c652019-03-11 17:18:3510229 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
[email protected]8c843192012-04-05 07:15:0010230
Ryan Hamilton0239aac2018-05-19 00:03:1310231 spdy::SpdySerializedFrame stream1_body(
10232 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]8c843192012-04-05 07:15:0010233
Ryan Hamilton0239aac2018-05-19 00:03:1310234 spdy::SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
Raul Tambre94493c652019-03-11 17:18:3510235 nullptr, 0, 2, 1, "https://www.another-origin.com/foo.dat"));
[email protected]8c843192012-04-05 07:15:0010236
10237 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4110238 CreateMockRead(stream1_reply, 1, ASYNC),
10239 CreateMockRead(stream2_syn, 2, ASYNC),
10240 CreateMockRead(stream1_body, 4, ASYNC),
mmenkee24011922015-12-17 22:12:5910241 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
[email protected]8c843192012-04-05 07:15:0010242 };
10243
Ryan Sleevib8d7ea02018-05-07 20:01:0110244 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0710245 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:0010246 // Negotiate SPDY to the proxy
10247 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610248 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0710249 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:0010250
bnc87dcefc2017-05-25 12:47:5810251 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1910252 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]8c843192012-04-05 07:15:0010253 TestCompletionCallback callback;
10254 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0110255 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c843192012-04-05 07:15:0010256
10257 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110258 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:0010259 const HttpResponseInfo* response = trans->GetResponseInfo();
10260
wezca1070932016-05-26 20:30:5210261 ASSERT_TRUE(response);
[email protected]8c843192012-04-05 07:15:0010262 EXPECT_TRUE(response->headers->IsKeepAlive());
10263
10264 EXPECT_EQ(200, response->headers->response_code());
10265 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10266
10267 std::string response_data;
10268 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:0110269 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:0010270 EXPECT_EQ("hello!", response_data);
10271
10272 trans.reset();
10273 session->CloseAllConnections();
10274}
10275
tbansal8ef1d3e2016-02-03 04:05:4210276// Test that an explicitly trusted SPDY proxy can push same-origin HTTPS
10277// resources.
bncd16676a2016-07-20 16:23:0110278TEST_F(HttpNetworkTransactionTest, SameOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:1510279 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:1910280 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:1510281 proxy_delegate->set_trusted_spdy_proxy(
10282 net::ProxyServer::FromURI("myproxy:70", net::ProxyServer::SCHEME_HTTP));
10283
tbansal8ef1d3e2016-02-03 04:05:4210284 HttpRequestInfo request;
10285
10286 request.method = "GET";
10287 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010288 request.traffic_annotation =
10289 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal8ef1d3e2016-02-03 04:05:4210290
10291 // Configure against https proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:4910292 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
10293 "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal8ef1d3e2016-02-03 04:05:4210294 BoundTestNetLog log;
10295 session_deps_.net_log = log.bound().net_log();
10296
10297 // Enable cross-origin push.
Eric Roman3d8546a2018-09-10 17:00:5210298 session_deps_.proxy_resolution_service->SetProxyDelegate(
10299 proxy_delegate.get());
tbansal8ef1d3e2016-02-03 04:05:4210300
danakj1fd259a02016-04-16 03:17:0910301 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
tbansal8ef1d3e2016-02-03 04:05:4210302
Ryan Hamilton0239aac2018-05-19 00:03:1310303 spdy::SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:4510304 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1310305 spdy::SpdySerializedFrame stream2_priority(
tombergan5d22c182017-01-11 02:05:3510306 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
tbansal8ef1d3e2016-02-03 04:05:4210307
10308 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4110309 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:3510310 CreateMockWrite(stream2_priority, 3, ASYNC),
tbansal8ef1d3e2016-02-03 04:05:4210311 };
10312
Ryan Hamilton0239aac2018-05-19 00:03:1310313 spdy::SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:1510314 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:4210315
Ryan Hamilton0239aac2018-05-19 00:03:1310316 spdy::SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
Bence Béky096cf052017-08-08 23:55:3310317 nullptr, 0, 2, 1, "http://www.example.org/foo.dat"));
bnc38dcd392016-02-09 23:19:4910318
Ryan Hamilton0239aac2018-05-19 00:03:1310319 spdy::SpdySerializedFrame stream1_body(
10320 spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:4210321
Ryan Hamilton0239aac2018-05-19 00:03:1310322 spdy::SpdySerializedFrame stream2_reply(
bnc42331402016-07-25 13:36:1510323 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:4210324
Ryan Hamilton0239aac2018-05-19 00:03:1310325 spdy::SpdySerializedFrame stream2_body(
10326 spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:4210327
10328 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4110329 CreateMockRead(stream1_reply, 1, ASYNC),
10330 CreateMockRead(stream2_syn, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:3510331 CreateMockRead(stream1_body, 4, ASYNC),
10332 CreateMockRead(stream2_body, 5, ASYNC),
10333 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
tbansal8ef1d3e2016-02-03 04:05:4210334 };
10335
Ryan Sleevib8d7ea02018-05-07 20:01:0110336 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
tbansal8ef1d3e2016-02-03 04:05:4210337 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
10338 // Negotiate SPDY to the proxy
10339 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610340 proxy.next_proto = kProtoHTTP2;
tbansal8ef1d3e2016-02-03 04:05:4210341 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
10342
bnc87dcefc2017-05-25 12:47:5810343 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1910344 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tbansal8ef1d3e2016-02-03 04:05:4210345 TestCompletionCallback callback;
10346 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0110347 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
tbansal8ef1d3e2016-02-03 04:05:4210348
10349 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110350 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:4210351 const HttpResponseInfo* response = trans->GetResponseInfo();
10352
wezca1070932016-05-26 20:30:5210353 ASSERT_TRUE(response);
tbansal8ef1d3e2016-02-03 04:05:4210354 EXPECT_TRUE(response->headers->IsKeepAlive());
10355
10356 EXPECT_EQ(200, response->headers->response_code());
10357 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10358
10359 std::string response_data;
10360 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:0110361 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:4210362 EXPECT_EQ("hello!", response_data);
10363
10364 trans.reset();
10365 session->CloseAllConnections();
10366}
10367
[email protected]2df19bb2010-08-25 20:13:4610368// Test HTTPS connections to a site with a bad certificate, going through an
10369// HTTPS proxy
bncd16676a2016-07-20 16:23:0110370TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
Ramin Halavatica8d5252018-03-12 05:33:4910371 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
10372 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:4610373
10374 HttpRequestInfo request;
10375 request.method = "GET";
bncce36dca22015-04-21 22:11:2310376 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010377 request.traffic_annotation =
10378 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:4610379
10380 // Attempt to fetch the URL from a server with a bad cert
10381 MockWrite bad_cert_writes[] = {
rsleevidb16bb02015-11-12 23:47:1710382 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
10383 "Host: www.example.org:443\r\n"
10384 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:4610385 };
10386
10387 MockRead bad_cert_reads[] = {
10388 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610389 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:4610390 };
10391
10392 // Attempt to fetch the URL with a good cert
10393 MockWrite good_data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1710394 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
10395 "Host: www.example.org:443\r\n"
10396 "Proxy-Connection: keep-alive\r\n\r\n"),
10397 MockWrite("GET / HTTP/1.1\r\n"
10398 "Host: www.example.org\r\n"
10399 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:4610400 };
10401
10402 MockRead good_cert_reads[] = {
10403 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
10404 MockRead("HTTP/1.0 200 OK\r\n"),
10405 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10406 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610407 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:4610408 };
10409
Ryan Sleevib8d7ea02018-05-07 20:01:0110410 StaticSocketDataProvider ssl_bad_certificate(bad_cert_reads, bad_cert_writes);
10411 StaticSocketDataProvider data(good_cert_reads, good_data_writes);
[email protected]8ddf8322012-02-23 18:08:0610412 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
10413 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:4610414
10415 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:0710416 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10417 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
10418 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:4610419
10420 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:0710421 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10422 session_deps_.socket_factory->AddSocketDataProvider(&data);
10423 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:4610424
[email protected]49639fa2011-12-20 23:22:4110425 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:4610426
danakj1fd259a02016-04-16 03:17:0910427 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610428 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:4610429
tfarina42834112016-09-22 13:38:2010430 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110431 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:4610432
10433 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110434 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]2df19bb2010-08-25 20:13:4610435
bnc691fda62016-08-12 00:43:1610436 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:0110437 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:4610438
10439 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110440 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:4610441
bnc691fda62016-08-12 00:43:1610442 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:4610443
wezca1070932016-05-26 20:30:5210444 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:4610445 EXPECT_EQ(100, response->headers->GetContentLength());
10446}
10447
bncd16676a2016-07-20 16:23:0110448TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:4210449 HttpRequestInfo request;
10450 request.method = "GET";
bncce36dca22015-04-21 22:11:2310451 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:4310452 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
10453 "Chromium Ultra Awesome X Edition");
Ramin Halavatib5e433e2018-02-07 07:41:1010454 request.traffic_annotation =
10455 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210456
danakj1fd259a02016-04-16 03:17:0910457 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610458 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710459
[email protected]1c773ea12009-04-28 19:58:4210460 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310461 MockWrite(
10462 "GET / HTTP/1.1\r\n"
10463 "Host: www.example.org\r\n"
10464 "Connection: keep-alive\r\n"
10465 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210466 };
10467
10468 // Lastly, the server responds with the actual content.
10469 MockRead data_reads[] = {
10470 MockRead("HTTP/1.0 200 OK\r\n"),
10471 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10472 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610473 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210474 };
10475
Ryan Sleevib8d7ea02018-05-07 20:01:0110476 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710477 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210478
[email protected]49639fa2011-12-20 23:22:4110479 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210480
tfarina42834112016-09-22 13:38:2010481 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110482 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210483
10484 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110485 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210486}
10487
bncd16676a2016-07-20 16:23:0110488TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
Matt Menked732ea42019-03-08 12:05:0010489 // Test user agent values, used both for the request header of the original
10490 // request, and the value returned by the HttpUserAgentSettings. nullptr means
10491 // no request header / no HttpUserAgentSettings object.
10492 const char* kTestUserAgents[] = {nullptr, "", "Foopy"};
[email protected]da81f132010-08-18 23:39:2910493
Matt Menked732ea42019-03-08 12:05:0010494 for (const char* setting_user_agent : kTestUserAgents) {
10495 if (!setting_user_agent) {
10496 session_deps_.http_user_agent_settings.reset();
10497 } else {
10498 session_deps_.http_user_agent_settings =
10499 std::make_unique<StaticHttpUserAgentSettings>(
10500 std::string() /* accept-language */, setting_user_agent);
10501 }
10502 session_deps_.proxy_resolution_service =
10503 ProxyResolutionService::CreateFixed("myproxy:70",
10504 TRAFFIC_ANNOTATION_FOR_TESTS);
10505 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10506 for (const char* request_user_agent : kTestUserAgents) {
10507 HttpRequestInfo request;
10508 request.method = "GET";
10509 request.url = GURL("https://www.example.org/");
10510 if (request_user_agent) {
10511 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
10512 request_user_agent);
10513 }
10514 request.traffic_annotation =
10515 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710516
Matt Menked732ea42019-03-08 12:05:0010517 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]da81f132010-08-18 23:39:2910518
Matt Menked732ea42019-03-08 12:05:0010519 std::string expected_request;
10520 if (!setting_user_agent || strlen(setting_user_agent) == 0) {
10521 expected_request =
10522 "CONNECT www.example.org:443 HTTP/1.1\r\n"
10523 "Host: www.example.org:443\r\n"
10524 "Proxy-Connection: keep-alive\r\n\r\n";
10525 } else {
10526 expected_request = base::StringPrintf(
10527 "CONNECT www.example.org:443 HTTP/1.1\r\n"
10528 "Host: www.example.org:443\r\n"
10529 "Proxy-Connection: keep-alive\r\n"
10530 "User-Agent: %s\r\n\r\n",
10531 setting_user_agent);
10532 }
10533 MockWrite data_writes[] = {
10534 MockWrite(expected_request.c_str()),
10535 };
10536 MockRead data_reads[] = {
10537 // Return an error, so the transaction stops here (this test isn't
10538 // interested in the rest).
10539 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
10540 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
10541 MockRead("Proxy-Connection: close\r\n\r\n"),
10542 };
[email protected]da81f132010-08-18 23:39:2910543
Matt Menked732ea42019-03-08 12:05:0010544 StaticSocketDataProvider data(data_reads, data_writes);
10545 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:2910546
Matt Menked732ea42019-03-08 12:05:0010547 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:2910548
Matt Menked732ea42019-03-08 12:05:0010549 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
10550 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10551
10552 rv = callback.WaitForResult();
10553 EXPECT_THAT(rv, IsOk());
10554 }
10555 }
[email protected]da81f132010-08-18 23:39:2910556}
10557
bncd16676a2016-07-20 16:23:0110558TEST_F(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:4210559 HttpRequestInfo request;
10560 request.method = "GET";
bncce36dca22015-04-21 22:11:2310561 request.url = GURL("http://www.example.org/");
[email protected]c10450102011-06-27 09:06:1610562 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
10563 "http://the.previous.site.com/");
Ramin Halavatib5e433e2018-02-07 07:41:1010564 request.traffic_annotation =
10565 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210566
danakj1fd259a02016-04-16 03:17:0910567 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610568 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710569
[email protected]1c773ea12009-04-28 19:58:4210570 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310571 MockWrite(
10572 "GET / HTTP/1.1\r\n"
10573 "Host: www.example.org\r\n"
10574 "Connection: keep-alive\r\n"
10575 "Referer: http://the.previous.site.com/\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210576 };
10577
10578 // Lastly, the server responds with the actual content.
10579 MockRead data_reads[] = {
10580 MockRead("HTTP/1.0 200 OK\r\n"),
10581 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10582 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610583 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210584 };
10585
Ryan Sleevib8d7ea02018-05-07 20:01:0110586 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710587 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210588
[email protected]49639fa2011-12-20 23:22:4110589 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210590
tfarina42834112016-09-22 13:38:2010591 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110592 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210593
10594 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110595 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210596}
10597
bncd16676a2016-07-20 16:23:0110598TEST_F(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:4210599 HttpRequestInfo request;
10600 request.method = "POST";
bncce36dca22015-04-21 22:11:2310601 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010602 request.traffic_annotation =
10603 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210604
danakj1fd259a02016-04-16 03:17:0910605 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610606 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710607
[email protected]1c773ea12009-04-28 19:58:4210608 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310609 MockWrite(
10610 "POST / HTTP/1.1\r\n"
10611 "Host: www.example.org\r\n"
10612 "Connection: keep-alive\r\n"
10613 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210614 };
10615
10616 // Lastly, the server responds with the actual content.
10617 MockRead data_reads[] = {
10618 MockRead("HTTP/1.0 200 OK\r\n"),
10619 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10620 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610621 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210622 };
10623
Ryan Sleevib8d7ea02018-05-07 20:01:0110624 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710625 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210626
[email protected]49639fa2011-12-20 23:22:4110627 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210628
tfarina42834112016-09-22 13:38:2010629 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110630 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210631
10632 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110633 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210634}
10635
bncd16676a2016-07-20 16:23:0110636TEST_F(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:4210637 HttpRequestInfo request;
10638 request.method = "PUT";
bncce36dca22015-04-21 22:11:2310639 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010640 request.traffic_annotation =
10641 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210642
danakj1fd259a02016-04-16 03:17:0910643 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610644 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710645
[email protected]1c773ea12009-04-28 19:58:4210646 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310647 MockWrite(
10648 "PUT / HTTP/1.1\r\n"
10649 "Host: www.example.org\r\n"
10650 "Connection: keep-alive\r\n"
10651 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210652 };
10653
10654 // Lastly, the server responds with the actual content.
10655 MockRead data_reads[] = {
10656 MockRead("HTTP/1.0 200 OK\r\n"),
10657 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10658 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610659 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210660 };
10661
Ryan Sleevib8d7ea02018-05-07 20:01:0110662 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710663 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210664
[email protected]49639fa2011-12-20 23:22:4110665 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210666
tfarina42834112016-09-22 13:38:2010667 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110668 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210669
10670 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110671 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210672}
10673
bncd16676a2016-07-20 16:23:0110674TEST_F(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:4210675 HttpRequestInfo request;
10676 request.method = "HEAD";
bncce36dca22015-04-21 22:11:2310677 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010678 request.traffic_annotation =
10679 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210680
danakj1fd259a02016-04-16 03:17:0910681 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610682 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710683
[email protected]1c773ea12009-04-28 19:58:4210684 MockWrite data_writes[] = {
csharrisonf473dd192015-08-18 13:54:1310685 MockWrite("HEAD / HTTP/1.1\r\n"
10686 "Host: www.example.org\r\n"
10687 "Connection: keep-alive\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210688 };
10689
10690 // Lastly, the server responds with the actual content.
10691 MockRead data_reads[] = {
10692 MockRead("HTTP/1.0 200 OK\r\n"),
10693 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10694 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610695 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210696 };
10697
Ryan Sleevib8d7ea02018-05-07 20:01:0110698 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710699 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210700
[email protected]49639fa2011-12-20 23:22:4110701 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210702
tfarina42834112016-09-22 13:38:2010703 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110704 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210705
10706 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110707 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210708}
10709
bncd16676a2016-07-20 16:23:0110710TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:4210711 HttpRequestInfo request;
10712 request.method = "GET";
bncce36dca22015-04-21 22:11:2310713 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:4210714 request.load_flags = LOAD_BYPASS_CACHE;
Ramin Halavatib5e433e2018-02-07 07:41:1010715 request.traffic_annotation =
10716 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210717
danakj1fd259a02016-04-16 03:17:0910718 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610719 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710720
[email protected]1c773ea12009-04-28 19:58:4210721 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310722 MockWrite(
10723 "GET / HTTP/1.1\r\n"
10724 "Host: www.example.org\r\n"
10725 "Connection: keep-alive\r\n"
10726 "Pragma: no-cache\r\n"
10727 "Cache-Control: no-cache\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210728 };
10729
10730 // Lastly, the server responds with the actual content.
10731 MockRead data_reads[] = {
10732 MockRead("HTTP/1.0 200 OK\r\n"),
10733 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10734 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610735 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210736 };
10737
Ryan Sleevib8d7ea02018-05-07 20:01:0110738 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710739 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210740
[email protected]49639fa2011-12-20 23:22:4110741 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210742
tfarina42834112016-09-22 13:38:2010743 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110744 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210745
10746 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110747 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210748}
10749
bncd16676a2016-07-20 16:23:0110750TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:4210751 HttpRequestInfo request;
10752 request.method = "GET";
bncce36dca22015-04-21 22:11:2310753 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:4210754 request.load_flags = LOAD_VALIDATE_CACHE;
Ramin Halavatib5e433e2018-02-07 07:41:1010755 request.traffic_annotation =
10756 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210757
danakj1fd259a02016-04-16 03:17:0910758 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610759 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710760
[email protected]1c773ea12009-04-28 19:58:4210761 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310762 MockWrite(
10763 "GET / HTTP/1.1\r\n"
10764 "Host: www.example.org\r\n"
10765 "Connection: keep-alive\r\n"
10766 "Cache-Control: max-age=0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210767 };
10768
10769 // Lastly, the server responds with the actual content.
10770 MockRead data_reads[] = {
10771 MockRead("HTTP/1.0 200 OK\r\n"),
10772 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10773 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610774 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210775 };
10776
Ryan Sleevib8d7ea02018-05-07 20:01:0110777 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710778 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210779
[email protected]49639fa2011-12-20 23:22:4110780 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210781
tfarina42834112016-09-22 13:38:2010782 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110783 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210784
10785 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110786 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210787}
10788
bncd16676a2016-07-20 16:23:0110789TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:4210790 HttpRequestInfo request;
10791 request.method = "GET";
bncce36dca22015-04-21 22:11:2310792 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:4310793 request.extra_headers.SetHeader("FooHeader", "Bar");
Ramin Halavatib5e433e2018-02-07 07:41:1010794 request.traffic_annotation =
10795 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210796
danakj1fd259a02016-04-16 03:17:0910797 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610798 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710799
[email protected]1c773ea12009-04-28 19:58:4210800 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310801 MockWrite(
10802 "GET / HTTP/1.1\r\n"
10803 "Host: www.example.org\r\n"
10804 "Connection: keep-alive\r\n"
10805 "FooHeader: Bar\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210806 };
10807
10808 // Lastly, the server responds with the actual content.
10809 MockRead data_reads[] = {
10810 MockRead("HTTP/1.0 200 OK\r\n"),
10811 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10812 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610813 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210814 };
10815
Ryan Sleevib8d7ea02018-05-07 20:01:0110816 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710817 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210818
[email protected]49639fa2011-12-20 23:22:4110819 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210820
tfarina42834112016-09-22 13:38:2010821 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110822 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210823
10824 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110825 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210826}
10827
bncd16676a2016-07-20 16:23:0110828TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:4710829 HttpRequestInfo request;
10830 request.method = "GET";
bncce36dca22015-04-21 22:11:2310831 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:4310832 request.extra_headers.SetHeader("referer", "www.foo.com");
10833 request.extra_headers.SetHeader("hEllo", "Kitty");
10834 request.extra_headers.SetHeader("FoO", "bar");
Ramin Halavatib5e433e2018-02-07 07:41:1010835 request.traffic_annotation =
10836 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]270c6412010-03-29 22:02:4710837
danakj1fd259a02016-04-16 03:17:0910838 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610839 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710840
[email protected]270c6412010-03-29 22:02:4710841 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310842 MockWrite(
10843 "GET / HTTP/1.1\r\n"
10844 "Host: www.example.org\r\n"
10845 "Connection: keep-alive\r\n"
10846 "referer: www.foo.com\r\n"
10847 "hEllo: Kitty\r\n"
10848 "FoO: bar\r\n\r\n"),
[email protected]270c6412010-03-29 22:02:4710849 };
10850
10851 // Lastly, the server responds with the actual content.
10852 MockRead data_reads[] = {
10853 MockRead("HTTP/1.0 200 OK\r\n"),
10854 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10855 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610856 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:4710857 };
10858
Ryan Sleevib8d7ea02018-05-07 20:01:0110859 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710860 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:4710861
[email protected]49639fa2011-12-20 23:22:4110862 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:4710863
tfarina42834112016-09-22 13:38:2010864 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110865 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]270c6412010-03-29 22:02:4710866
10867 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110868 EXPECT_THAT(rv, IsOk());
[email protected]270c6412010-03-29 22:02:4710869}
10870
bncd16676a2016-07-20 16:23:0110871TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:2710872 HttpRequestInfo request;
10873 request.method = "GET";
bncce36dca22015-04-21 22:11:2310874 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010875 request.traffic_annotation =
10876 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710877
Lily Houghton8c2f97d2018-01-22 05:06:5910878 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910879 ProxyResolutionService::CreateFixedFromPacResult(
10880 "SOCKS myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110881 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710882 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:0210883
danakj1fd259a02016-04-16 03:17:0910884 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610885 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:0210886
[email protected]3cd17242009-06-23 02:59:0210887 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
10888 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
10889
10890 MockWrite data_writes[] = {
Avi Drissman4365a4782018-12-28 19:26:2410891 MockWrite(ASYNC, write_buffer, base::size(write_buffer)),
10892 MockWrite("GET / HTTP/1.1\r\n"
10893 "Host: www.example.org\r\n"
10894 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:0210895
10896 MockRead data_reads[] = {
Avi Drissman4365a4782018-12-28 19:26:2410897 MockRead(ASYNC, read_buffer, base::size(read_buffer)),
10898 MockRead("HTTP/1.0 200 OK\r\n"),
10899 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
10900 MockRead("Payload"), MockRead(SYNCHRONOUS, OK)};
[email protected]3cd17242009-06-23 02:59:0210901
Ryan Sleevib8d7ea02018-05-07 20:01:0110902 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710903 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:0210904
[email protected]49639fa2011-12-20 23:22:4110905 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:0210906
tfarina42834112016-09-22 13:38:2010907 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110908 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:0210909
10910 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110911 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0210912
bnc691fda62016-08-12 00:43:1610913 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210914 ASSERT_TRUE(response);
[email protected]3cd17242009-06-23 02:59:0210915
tbansal2ecbbc72016-10-06 17:15:4710916 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]029c83b62013-01-24 05:28:2010917 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1610918 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2010919 TestLoadTimingNotReusedWithPac(load_timing_info,
10920 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
10921
[email protected]3cd17242009-06-23 02:59:0210922 std::string response_text;
bnc691fda62016-08-12 00:43:1610923 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0110924 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0210925 EXPECT_EQ("Payload", response_text);
10926}
10927
bncd16676a2016-07-20 16:23:0110928TEST_F(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:2710929 HttpRequestInfo request;
10930 request.method = "GET";
bncce36dca22015-04-21 22:11:2310931 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010932 request.traffic_annotation =
10933 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710934
Lily Houghton8c2f97d2018-01-22 05:06:5910935 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910936 ProxyResolutionService::CreateFixedFromPacResult(
10937 "SOCKS myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110938 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710939 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:0210940
danakj1fd259a02016-04-16 03:17:0910941 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610942 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:0210943
[email protected]3cd17242009-06-23 02:59:0210944 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
10945 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
10946
10947 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310948 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
Avi Drissman4365a4782018-12-28 19:26:2410949 base::size(write_buffer)),
10950 MockWrite("GET / HTTP/1.1\r\n"
10951 "Host: www.example.org\r\n"
10952 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:0210953
10954 MockRead data_reads[] = {
Avi Drissman4365a4782018-12-28 19:26:2410955 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
10956 base::size(read_buffer)),
10957 MockRead("HTTP/1.0 200 OK\r\n"),
10958 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
10959 MockRead("Payload"), MockRead(SYNCHRONOUS, OK)};
[email protected]e0c27be2009-07-15 13:09:3510960
Ryan Sleevib8d7ea02018-05-07 20:01:0110961 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710962 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:3510963
[email protected]8ddf8322012-02-23 18:08:0610964 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710965 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:3510966
[email protected]49639fa2011-12-20 23:22:4110967 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:3510968
tfarina42834112016-09-22 13:38:2010969 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110970 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:3510971
10972 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110973 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3510974
[email protected]029c83b62013-01-24 05:28:2010975 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1610976 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2010977 TestLoadTimingNotReusedWithPac(load_timing_info,
10978 CONNECT_TIMING_HAS_SSL_TIMES);
10979
bnc691fda62016-08-12 00:43:1610980 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210981 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:4710982 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:3510983
10984 std::string response_text;
bnc691fda62016-08-12 00:43:1610985 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0110986 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3510987 EXPECT_EQ("Payload", response_text);
10988}
10989
bncd16676a2016-07-20 16:23:0110990TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:2010991 HttpRequestInfo request;
10992 request.method = "GET";
bncce36dca22015-04-21 22:11:2310993 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010994 request.traffic_annotation =
10995 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:2010996
Ramin Halavatica8d5252018-03-12 05:33:4910997 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
10998 "socks4://myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110999 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0711000 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:2011001
danakj1fd259a02016-04-16 03:17:0911002 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611003 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:2011004
11005 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
11006 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
11007
11008 MockWrite data_writes[] = {
Avi Drissman4365a4782018-12-28 19:26:2411009 MockWrite(ASYNC, write_buffer, base::size(write_buffer)),
11010 MockWrite("GET / HTTP/1.1\r\n"
11011 "Host: www.example.org\r\n"
11012 "Connection: keep-alive\r\n\r\n")};
[email protected]029c83b62013-01-24 05:28:2011013
11014 MockRead data_reads[] = {
Avi Drissman4365a4782018-12-28 19:26:2411015 MockRead(ASYNC, read_buffer, base::size(read_buffer)),
11016 MockRead("HTTP/1.0 200 OK\r\n"),
11017 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
11018 MockRead("Payload"), MockRead(SYNCHRONOUS, OK)};
[email protected]029c83b62013-01-24 05:28:2011019
Ryan Sleevib8d7ea02018-05-07 20:01:0111020 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0711021 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:2011022
11023 TestCompletionCallback callback;
11024
tfarina42834112016-09-22 13:38:2011025 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111026 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:2011027
11028 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111029 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:2011030
bnc691fda62016-08-12 00:43:1611031 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211032 ASSERT_TRUE(response);
[email protected]029c83b62013-01-24 05:28:2011033
11034 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1611035 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2011036 TestLoadTimingNotReused(load_timing_info,
11037 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
11038
11039 std::string response_text;
bnc691fda62016-08-12 00:43:1611040 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0111041 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:2011042 EXPECT_EQ("Payload", response_text);
11043}
11044
bncd16676a2016-07-20 16:23:0111045TEST_F(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:2711046 HttpRequestInfo request;
11047 request.method = "GET";
bncce36dca22015-04-21 22:11:2311048 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011049 request.traffic_annotation =
11050 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2711051
Lily Houghton8c2f97d2018-01-22 05:06:5911052 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4911053 ProxyResolutionService::CreateFixedFromPacResult(
11054 "SOCKS5 myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5111055 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0711056 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:3511057
danakj1fd259a02016-04-16 03:17:0911058 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611059 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:3511060
[email protected]e0c27be2009-07-15 13:09:3511061 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
11062 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:3711063 const char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:2311064 0x05, // Version
11065 0x01, // Command (CONNECT)
11066 0x00, // Reserved.
11067 0x03, // Address type (DOMAINNAME).
11068 0x0F, // Length of domain (15)
11069 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
11070 '.', 'o', 'r', 'g', 0x00, 0x50, // 16-bit port (80)
[email protected]f209dba2009-12-18 00:24:3711071 };
[email protected]e0c27be2009-07-15 13:09:3511072 const char kSOCKS5OkResponse[] =
11073 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
11074
11075 MockWrite data_writes[] = {
Avi Drissman4365a4782018-12-28 19:26:2411076 MockWrite(ASYNC, kSOCKS5GreetRequest, base::size(kSOCKS5GreetRequest)),
11077 MockWrite(ASYNC, kSOCKS5OkRequest, base::size(kSOCKS5OkRequest)),
11078 MockWrite("GET / HTTP/1.1\r\n"
11079 "Host: www.example.org\r\n"
11080 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:3511081
11082 MockRead data_reads[] = {
Avi Drissman4365a4782018-12-28 19:26:2411083 MockRead(ASYNC, kSOCKS5GreetResponse, base::size(kSOCKS5GreetResponse)),
11084 MockRead(ASYNC, kSOCKS5OkResponse, base::size(kSOCKS5OkResponse)),
11085 MockRead("HTTP/1.0 200 OK\r\n"),
11086 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
11087 MockRead("Payload"),
11088 MockRead(SYNCHRONOUS, OK)};
[email protected]e0c27be2009-07-15 13:09:3511089
Ryan Sleevib8d7ea02018-05-07 20:01:0111090 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0711091 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:3511092
[email protected]49639fa2011-12-20 23:22:4111093 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:3511094
tfarina42834112016-09-22 13:38:2011095 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111096 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:3511097
11098 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111099 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3511100
bnc691fda62016-08-12 00:43:1611101 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211102 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:4711103 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:3511104
[email protected]029c83b62013-01-24 05:28:2011105 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1611106 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2011107 TestLoadTimingNotReusedWithPac(load_timing_info,
11108 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
11109
[email protected]e0c27be2009-07-15 13:09:3511110 std::string response_text;
bnc691fda62016-08-12 00:43:1611111 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0111112 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3511113 EXPECT_EQ("Payload", response_text);
11114}
11115
bncd16676a2016-07-20 16:23:0111116TEST_F(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:2711117 HttpRequestInfo request;
11118 request.method = "GET";
bncce36dca22015-04-21 22:11:2311119 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011120 request.traffic_annotation =
11121 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2711122
Lily Houghton8c2f97d2018-01-22 05:06:5911123 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4911124 ProxyResolutionService::CreateFixedFromPacResult(
11125 "SOCKS5 myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5111126 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0711127 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:3511128
danakj1fd259a02016-04-16 03:17:0911129 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611130 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:3511131
[email protected]e0c27be2009-07-15 13:09:3511132 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
11133 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:3711134 const unsigned char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:2311135 0x05, // Version
11136 0x01, // Command (CONNECT)
11137 0x00, // Reserved.
11138 0x03, // Address type (DOMAINNAME).
11139 0x0F, // Length of domain (15)
11140 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
11141 '.', 'o', 'r', 'g', 0x01, 0xBB, // 16-bit port (443)
[email protected]f209dba2009-12-18 00:24:3711142 };
11143
[email protected]e0c27be2009-07-15 13:09:3511144 const char kSOCKS5OkResponse[] =
11145 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
11146
11147 MockWrite data_writes[] = {
Avi Drissman4365a4782018-12-28 19:26:2411148 MockWrite(ASYNC, kSOCKS5GreetRequest, base::size(kSOCKS5GreetRequest)),
bncce36dca22015-04-21 22:11:2311149 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
Avi Drissman4365a4782018-12-28 19:26:2411150 base::size(kSOCKS5OkRequest)),
11151 MockWrite("GET / HTTP/1.1\r\n"
11152 "Host: www.example.org\r\n"
11153 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:3511154
11155 MockRead data_reads[] = {
Avi Drissman4365a4782018-12-28 19:26:2411156 MockRead(ASYNC, kSOCKS5GreetResponse, base::size(kSOCKS5GreetResponse)),
11157 MockRead(ASYNC, kSOCKS5OkResponse, base::size(kSOCKS5OkResponse)),
11158 MockRead("HTTP/1.0 200 OK\r\n"),
11159 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
11160 MockRead("Payload"),
11161 MockRead(SYNCHRONOUS, OK)};
[email protected]3cd17242009-06-23 02:59:0211162
Ryan Sleevib8d7ea02018-05-07 20:01:0111163 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0711164 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:0211165
[email protected]8ddf8322012-02-23 18:08:0611166 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0711167 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:0211168
[email protected]49639fa2011-12-20 23:22:4111169 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:0211170
tfarina42834112016-09-22 13:38:2011171 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111172 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:0211173
11174 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111175 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0211176
bnc691fda62016-08-12 00:43:1611177 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211178 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:4711179 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]3cd17242009-06-23 02:59:0211180
[email protected]029c83b62013-01-24 05:28:2011181 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1611182 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2011183 TestLoadTimingNotReusedWithPac(load_timing_info,
11184 CONNECT_TIMING_HAS_SSL_TIMES);
11185
[email protected]3cd17242009-06-23 02:59:0211186 std::string response_text;
bnc691fda62016-08-12 00:43:1611187 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0111188 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0211189 EXPECT_EQ("Payload", response_text);
11190}
11191
[email protected]448d4ca52012-03-04 04:12:2311192namespace {
11193
[email protected]04e5be32009-06-26 20:00:3111194// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:0611195
11196struct GroupNameTest {
11197 std::string proxy_server;
11198 std::string url;
11199 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:1811200 bool ssl;
[email protected]2d731a32010-04-29 01:04:0611201};
11202
danakj1fd259a02016-04-16 03:17:0911203std::unique_ptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]bb88e1d32013-05-03 23:11:0711204 SpdySessionDependencies* session_deps_) {
danakj1fd259a02016-04-16 03:17:0911205 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:0611206
bnc525e175a2016-06-20 12:36:4011207 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311208 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2111209 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnc7dc7e1b42015-07-28 14:43:1211210 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111211 http_server_properties->SetHttp2AlternativeService(
bncaa60ff402016-06-22 19:12:4211212 url::SchemeHostPort("https", "host.with.alternate", 443),
zhongyi3d4a55e72016-04-22 20:36:4611213 alternative_service, expiration);
[email protected]2d731a32010-04-29 01:04:0611214
11215 return session;
11216}
11217
mmenkee65e7af2015-10-13 17:16:4211218int GroupNameTransactionHelper(const std::string& url,
11219 HttpNetworkSession* session) {
[email protected]2d731a32010-04-29 01:04:0611220 HttpRequestInfo request;
11221 request.method = "GET";
11222 request.url = GURL(url);
Ramin Halavatib5e433e2018-02-07 07:41:1011223 request.traffic_annotation =
11224 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d731a32010-04-29 01:04:0611225
bnc691fda62016-08-12 00:43:1611226 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
[email protected]cb9bf6ca2011-01-28 13:15:2711227
[email protected]49639fa2011-12-20 23:22:4111228 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:0611229
11230 // We do not complete this request, the dtor will clean the transaction up.
tfarina42834112016-09-22 13:38:2011231 return trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]2d731a32010-04-29 01:04:0611232}
11233
[email protected]448d4ca52012-03-04 04:12:2311234} // namespace
11235
bncd16676a2016-07-20 16:23:0111236TEST_F(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:0611237 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:2311238 {
11239 "", // unused
11240 "http://www.example.org/direct",
11241 "www.example.org:80",
11242 false,
11243 },
11244 {
11245 "", // unused
11246 "http://[2001:1418:13:1::25]/direct",
11247 "[2001:1418:13:1::25]:80",
11248 false,
11249 },
[email protected]04e5be32009-06-26 20:00:3111250
bncce36dca22015-04-21 22:11:2311251 // SSL Tests
11252 {
11253 "", // unused
11254 "https://www.example.org/direct_ssl",
11255 "ssl/www.example.org:443",
11256 true,
11257 },
11258 {
11259 "", // unused
11260 "https://[2001:1418:13:1::25]/direct",
11261 "ssl/[2001:1418:13:1::25]:443",
11262 true,
11263 },
11264 {
11265 "", // unused
bncaa60ff402016-06-22 19:12:4211266 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:2311267 "ssl/host.with.alternate:443",
11268 true,
11269 },
[email protected]2d731a32010-04-29 01:04:0611270 };
[email protected]2ff8b312010-04-26 22:20:5411271
Avi Drissman4365a4782018-12-28 19:26:2411272 for (size_t i = 0; i < base::size(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5911273 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4911274 ProxyResolutionService::CreateFixed(tests[i].proxy_server,
11275 TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:0911276 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:4011277 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:0611278
mmenkee65e7af2015-10-13 17:16:4211279 HttpNetworkSessionPeer peer(session.get());
[email protected]ab739042011-04-07 15:22:2811280 CaptureGroupNameTransportSocketPool* transport_conn_pool =
bnc87dcefc2017-05-25 12:47:5811281 new CaptureGroupNameTransportSocketPool(nullptr, nullptr);
Jeremy Roman0579ed62017-08-29 15:56:1911282 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
Matt Menked23ab952019-03-06 00:24:4011283 mock_pool_manager->SetSocketPool(ProxyServer::Direct(),
11284 base::WrapUnique(transport_conn_pool));
dchengc7eeda422015-12-26 03:56:4811285 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:0611286
11287 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:4211288 GroupNameTransactionHelper(tests[i].url, session.get()));
Matt Menke9d5e2c92019-02-05 01:42:2311289 EXPECT_EQ(tests[i].expected_group_name,
11290 transport_conn_pool->last_group_name_received());
11291 EXPECT_TRUE(transport_conn_pool->socket_requested());
[email protected]2d731a32010-04-29 01:04:0611292 }
[email protected]2d731a32010-04-29 01:04:0611293}
11294
bncd16676a2016-07-20 16:23:0111295TEST_F(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:0611296 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:2311297 {
Matt Menke4802de62019-03-08 22:47:5011298 "http_proxy",
11299 "http://www.example.org/http_proxy_normal",
11300 "www.example.org:80",
11301 false,
bncce36dca22015-04-21 22:11:2311302 },
[email protected]2d731a32010-04-29 01:04:0611303
bncce36dca22015-04-21 22:11:2311304 // SSL Tests
11305 {
Matt Menke4802de62019-03-08 22:47:5011306 "http_proxy",
11307 "https://www.example.org/http_connect_ssl",
11308 "ssl/www.example.org:443",
11309 true,
bncce36dca22015-04-21 22:11:2311310 },
[email protected]af3490e2010-10-16 21:02:2911311
bncce36dca22015-04-21 22:11:2311312 {
Matt Menke4802de62019-03-08 22:47:5011313 "http_proxy",
11314 "https://host.with.alternate/direct",
11315 "ssl/host.with.alternate:443",
11316 true,
bncce36dca22015-04-21 22:11:2311317 },
[email protected]45499252013-01-23 17:12:5611318
bncce36dca22015-04-21 22:11:2311319 {
Matt Menke4802de62019-03-08 22:47:5011320 "http_proxy",
11321 "ftp://ftp.google.com/http_proxy_normal",
11322 "ftp/ftp.google.com:21",
11323 false,
bncce36dca22015-04-21 22:11:2311324 },
[email protected]2d731a32010-04-29 01:04:0611325 };
11326
Avi Drissman4365a4782018-12-28 19:26:2411327 for (size_t i = 0; i < base::size(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5911328 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4911329 ProxyResolutionService::CreateFixed(tests[i].proxy_server,
11330 TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:0911331 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:4011332 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:0611333
mmenkee65e7af2015-10-13 17:16:4211334 HttpNetworkSessionPeer peer(session.get());
[email protected]2d731a32010-04-29 01:04:0611335
Matt Menkee8648fa2019-01-17 16:47:0711336 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
11337 HostPortPair("http_proxy", 80));
Matt Menke0754b5d02019-02-10 21:46:4311338 CaptureGroupNameTransportSocketPool* http_proxy_pool =
Raul Tambre94493c652019-03-11 17:18:3511339 new CaptureGroupNameTransportSocketPool(nullptr, nullptr);
Jeremy Roman0579ed62017-08-29 15:56:1911340 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
Matt Menked23ab952019-03-06 00:24:4011341 mock_pool_manager->SetSocketPool(proxy_server,
11342 base::WrapUnique(http_proxy_pool));
dchengc7eeda422015-12-26 03:56:4811343 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:0611344
11345 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:4211346 GroupNameTransactionHelper(tests[i].url, session.get()));
Matt Menkeaade5812019-03-02 13:38:0011347 EXPECT_EQ(tests[i].expected_group_name,
11348 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:0611349 }
[email protected]2d731a32010-04-29 01:04:0611350}
11351
bncd16676a2016-07-20 16:23:0111352TEST_F(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:0611353 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:2311354 {
Matt Menke4802de62019-03-08 22:47:5011355 "socks4://socks_proxy:1080",
11356 "http://www.example.org/socks4_direct",
11357 "www.example.org:80",
11358 false,
bncce36dca22015-04-21 22:11:2311359 },
11360 {
Matt Menke4802de62019-03-08 22:47:5011361 "socks5://socks_proxy:1080",
11362 "http://www.example.org/socks5_direct",
11363 "www.example.org:80",
11364 false,
bncce36dca22015-04-21 22:11:2311365 },
[email protected]2d731a32010-04-29 01:04:0611366
bncce36dca22015-04-21 22:11:2311367 // SSL Tests
11368 {
Matt Menke4802de62019-03-08 22:47:5011369 "socks4://socks_proxy:1080",
11370 "https://www.example.org/socks4_ssl",
11371 "ssl/www.example.org:443",
11372 true,
bncce36dca22015-04-21 22:11:2311373 },
11374 {
Matt Menke4802de62019-03-08 22:47:5011375 "socks5://socks_proxy:1080",
11376 "https://www.example.org/socks5_ssl",
11377 "ssl/www.example.org:443",
11378 true,
bncce36dca22015-04-21 22:11:2311379 },
[email protected]af3490e2010-10-16 21:02:2911380
bncce36dca22015-04-21 22:11:2311381 {
Matt Menke4802de62019-03-08 22:47:5011382 "socks4://socks_proxy:1080",
11383 "https://host.with.alternate/direct",
11384 "ssl/host.with.alternate:443",
11385 true,
bncce36dca22015-04-21 22:11:2311386 },
[email protected]04e5be32009-06-26 20:00:3111387 };
11388
Avi Drissman4365a4782018-12-28 19:26:2411389 for (size_t i = 0; i < base::size(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5911390 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4911391 ProxyResolutionService::CreateFixed(tests[i].proxy_server,
11392 TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:0911393 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:4011394 SetupSessionForGroupNameTests(&session_deps_));
[email protected]8b114dd72011-03-25 05:33:0211395
mmenkee65e7af2015-10-13 17:16:4211396 HttpNetworkSessionPeer peer(session.get());
[email protected]04e5be32009-06-26 20:00:3111397
Matt Menkee8648fa2019-01-17 16:47:0711398 ProxyServer proxy_server(
11399 ProxyServer::FromURI(tests[i].proxy_server, ProxyServer::SCHEME_HTTP));
11400 ASSERT_TRUE(proxy_server.is_valid());
Matt Menke4b412da2019-01-25 19:31:1211401 CaptureGroupNameTransportSocketPool* socks_conn_pool =
Raul Tambre94493c652019-03-11 17:18:3511402 new CaptureGroupNameTransportSocketPool(nullptr, nullptr);
Jeremy Roman0579ed62017-08-29 15:56:1911403 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
Matt Menked23ab952019-03-06 00:24:4011404 mock_pool_manager->SetSocketPool(proxy_server,
11405 base::WrapUnique(socks_conn_pool));
dchengc7eeda422015-12-26 03:56:4811406 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]04e5be32009-06-26 20:00:3111407
bnc691fda62016-08-12 00:43:1611408 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]04e5be32009-06-26 20:00:3111409
[email protected]2d731a32010-04-29 01:04:0611410 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:4211411 GroupNameTransactionHelper(tests[i].url, session.get()));
Matt Menke628d624f2019-02-09 00:40:2411412 EXPECT_EQ(tests[i].expected_group_name,
11413 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:3111414 }
11415}
11416
bncd16676a2016-07-20 16:23:0111417TEST_F(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:2711418 HttpRequestInfo request;
11419 request.method = "GET";
bncce36dca22015-04-21 22:11:2311420 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011421 request.traffic_annotation =
11422 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2711423
Ramin Halavatica8d5252018-03-12 05:33:4911424 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
11425 "myproxy:70;foobar:80", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]b59ff372009-07-15 22:04:3211426
[email protected]69719062010-01-05 20:09:2111427 // This simulates failure resolving all hostnames; that means we will fail
11428 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:0711429 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:3211430
danakj1fd259a02016-04-16 03:17:0911431 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611432 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]9172a982009-06-06 00:30:2511433
[email protected]49639fa2011-12-20 23:22:4111434 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:2511435
tfarina42834112016-09-22 13:38:2011436 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111437 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9172a982009-06-06 00:30:2511438
[email protected]9172a982009-06-06 00:30:2511439 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111440 EXPECT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]9172a982009-06-06 00:30:2511441}
11442
Miriam Gershenson2a01b162018-03-22 22:54:4711443// LOAD_BYPASS_CACHE should trigger the host cache bypass.
11444TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh) {
[email protected]cb9bf6ca2011-01-28 13:15:2711445 // Issue a request, asking to bypass the cache(s).
maksim.sisov31452af2016-07-27 06:38:1011446 HttpRequestInfo request_info;
11447 request_info.method = "GET";
Miriam Gershenson2a01b162018-03-22 22:54:4711448 request_info.load_flags = LOAD_BYPASS_CACHE;
maksim.sisov31452af2016-07-27 06:38:1011449 request_info.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011450 request_info.traffic_annotation =
11451 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2711452
[email protected]a2c2fb92009-07-18 07:31:0411453 // Select a host resolver that does caching.
Jeremy Roman0579ed62017-08-29 15:56:1911454 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
[email protected]b59ff372009-07-15 22:04:3211455
danakj1fd259a02016-04-16 03:17:0911456 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611457 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3b9cca42009-06-16 01:08:2811458
bncce36dca22015-04-21 22:11:2311459 // Warm up the host cache so it has an entry for "www.example.org".
Eric Orthf4db66a2019-02-19 21:35:3311460 int rv = session_deps_.host_resolver->LoadIntoCache(
11461 HostPortPair("www.example.org", 80), base::nullopt);
robpercival214763f2016-07-01 23:27:0111462 EXPECT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:2811463
bncce36dca22015-04-21 22:11:2311464 // Inject a failure the next time that "www.example.org" is resolved. This way
[email protected]3b9cca42009-06-16 01:08:2811465 // we can tell if the next lookup hit the cache, or the "network".
11466 // (cache --> success, "network" --> failure).
bncce36dca22015-04-21 22:11:2311467 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.example.org");
[email protected]3b9cca42009-06-16 01:08:2811468
11469 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
11470 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:0611471 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
Ryan Sleevib8d7ea02018-05-07 20:01:0111472 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711473 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:2811474
[email protected]3b9cca42009-06-16 01:08:2811475 // Run the request.
Eric Orthf4db66a2019-02-19 21:35:3311476 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2011477 rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111478 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]49639fa2011-12-20 23:22:4111479 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:2811480
11481 // If we bypassed the cache, we would have gotten a failure while resolving
bncce36dca22015-04-21 22:11:2311482 // "www.example.org".
robpercival214763f2016-07-01 23:27:0111483 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]3b9cca42009-06-16 01:08:2811484}
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());
[email protected]ab739042011-04-07 15:22:2814421 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
Tarun Bansala7635092019-02-20 10:00:5914422 50, // Max sockets for pool
14423 1, // Max sockets per group
14424 base::TimeDelta::FromSeconds(10), // unused_idle_socket_timeout
Matt Menkecb77b5402019-01-28 17:11:2314425 session_deps_.socket_factory.get(), session_deps_.host_resolver.get(),
Matt Menked732ea42019-03-08 12:05:0014426 nullptr /* proxy_delegate */, nullptr /* http_user_agent_settings */,
14427 session_deps_.cert_verifier.get(), session_deps_.channel_id_service.get(),
Matt Menkecb77b5402019-01-28 17:11:2314428 session_deps_.transport_security_state.get(),
14429 session_deps_.cert_transparency_verifier.get(),
14430 session_deps_.ct_policy_enforcer.get(),
Matt Menkec94d97b2019-02-01 19:28:2814431 nullptr /* ssl_client_session_cache */,
Daniel McArdleda3fa942019-02-15 16:41:2114432 nullptr /* ssl_client_session_cache_privacy_mode */,
Matt Menkefa9574f2019-01-28 18:55:2714433 session_deps_.ssl_config_service.get(),
Matt Menkecb77b5402019-01-28 17:11:2314434 nullptr /* socket_performance_watcher_factory */,
14435 nullptr /* network_quality_estimator */, session_deps_.net_log);
Jeremy Roman0579ed62017-08-29 15:56:1914436 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
Matt Menked23ab952019-03-06 00:24:4014437 mock_pool_manager->SetSocketPool(ProxyServer::Direct(),
14438 base::WrapUnique(transport_pool));
dchengc7eeda422015-12-26 03:56:4814439 session_peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]7ef4cbbb2011-02-06 11:19:1014440
bnc691fda62016-08-12 00:43:1614441 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4114442 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1414443
14444 const MockWrite kGet(
14445 "GET / HTTP/1.1\r\n"
14446 "Host: www.example.com\r\n"
14447 "Connection: keep-alive\r\n\r\n");
14448 const MockWrite kGetAuth(
14449 "GET / HTTP/1.1\r\n"
14450 "Host: www.example.com\r\n"
14451 "Connection: keep-alive\r\n"
14452 "Authorization: auth_token\r\n\r\n");
14453
14454 const MockRead kServerChallenge(
14455 "HTTP/1.1 401 Unauthorized\r\n"
14456 "WWW-Authenticate: Mock realm=server\r\n"
14457 "Content-Type: text/html; charset=iso-8859-1\r\n"
14458 "Content-Length: 14\r\n\r\n"
14459 "Unauthorized\r\n");
14460 const MockRead kSuccess(
14461 "HTTP/1.1 200 OK\r\n"
14462 "Content-Type: text/html; charset=iso-8859-1\r\n"
14463 "Content-Length: 3\r\n\r\n"
14464 "Yes");
14465
14466 MockWrite writes[] = {
14467 // First round
14468 kGet,
14469 // Second round
14470 kGetAuth,
14471 // Third round
14472 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3014473 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1014474 kGetAuth,
14475 // Competing request
14476 kGet,
[email protected]c871bce92010-07-15 21:51:1414477 };
14478 MockRead reads[] = {
14479 // First round
14480 kServerChallenge,
14481 // Second round
14482 kServerChallenge,
14483 // Third round
[email protected]eca50e122010-09-11 14:03:3014484 kServerChallenge,
14485 // Fourth round
[email protected]c871bce92010-07-15 21:51:1414486 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1014487 // Competing response
14488 kSuccess,
[email protected]c871bce92010-07-15 21:51:1414489 };
Ryan Sleevib8d7ea02018-05-07 20:01:0114490 StaticSocketDataProvider data_provider(reads, writes);
[email protected]bb88e1d32013-05-03 23:11:0714491 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1414492
thestig9d3bb0c2015-01-24 00:49:5114493 const char kSocketGroup[] = "www.example.com:80";
[email protected]7ef4cbbb2011-02-06 11:19:1014494
14495 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1414496 auth_handler->SetGenerateExpectation(false, OK);
tfarina42834112016-09-22 13:38:2014497 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]c871bce92010-07-15 21:51:1414498 if (rv == ERR_IO_PENDING)
14499 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114500 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1614501 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214502 ASSERT_TRUE(response);
14503 EXPECT_TRUE(response->auth_challenge);
Raul Tambre8335a6d2019-02-21 16:57:4314504 EXPECT_EQ(0u, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3114505 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
14506 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1414507
[email protected]7ef4cbbb2011-02-06 11:19:1014508 // In between rounds, another request comes in for the same domain.
14509 // It should not be able to grab the TCP socket that trans has already
14510 // claimed.
bnc691fda62016-08-12 00:43:1614511 HttpNetworkTransaction trans_compete(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4114512 TestCompletionCallback callback_compete;
tfarina42834112016-09-22 13:38:2014513 rv = trans_compete.Start(&request, callback_compete.callback(),
14514 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114515 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7ef4cbbb2011-02-06 11:19:1014516 // callback_compete.WaitForResult at this point would stall forever,
14517 // since the HttpNetworkTransaction does not release the request back to
14518 // the pool until after authentication completes.
14519
14520 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1414521 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1614522 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1414523 if (rv == ERR_IO_PENDING)
14524 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114525 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1614526 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214527 ASSERT_TRUE(response);
14528 EXPECT_FALSE(response->auth_challenge);
Raul Tambre8335a6d2019-02-21 16:57:4314529 EXPECT_EQ(0u, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3114530 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
14531 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1414532
[email protected]7ef4cbbb2011-02-06 11:19:1014533 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1414534 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1614535 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1414536 if (rv == ERR_IO_PENDING)
14537 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114538 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1614539 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214540 ASSERT_TRUE(response);
14541 EXPECT_FALSE(response->auth_challenge);
Raul Tambre8335a6d2019-02-21 16:57:4314542 EXPECT_EQ(0u, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3114543 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
14544 auth_handler->state());
[email protected]eca50e122010-09-11 14:03:3014545
[email protected]7ef4cbbb2011-02-06 11:19:1014546 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3014547 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1614548 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3014549 if (rv == ERR_IO_PENDING)
14550 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114551 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1614552 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214553 ASSERT_TRUE(response);
14554 EXPECT_FALSE(response->auth_challenge);
Raul Tambre8335a6d2019-02-21 16:57:4314555 EXPECT_EQ(0u, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1014556
asanka463ca4262016-11-16 02:34:3114557 // In WAIT_FOR_CHALLENGE, although in reality the auth handler is done. A real
14558 // auth handler should transition to a DONE state in concert with the remote
14559 // server. But that's not something we can test here with a mock handler.
14560 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_CHALLENGE,
14561 auth_handler->state());
14562
[email protected]7ef4cbbb2011-02-06 11:19:1014563 // Read the body since the fourth round was successful. This will also
14564 // release the socket back to the pool.
Victor Costan9c7302b2018-08-27 16:39:4414565 scoped_refptr<IOBufferWithSize> io_buf =
14566 base::MakeRefCounted<IOBufferWithSize>(50);
bnc691fda62016-08-12 00:43:1614567 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1014568 if (rv == ERR_IO_PENDING)
14569 rv = callback.WaitForResult();
14570 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1614571 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1014572 EXPECT_EQ(0, rv);
14573 // There are still 0 idle sockets, since the trans_compete transaction
14574 // will be handed it immediately after trans releases it to the group.
Raul Tambre8335a6d2019-02-21 16:57:4314575 EXPECT_EQ(0u, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1014576
14577 // The competing request can now finish. Wait for the headers and then
14578 // read the body.
14579 rv = callback_compete.WaitForResult();
robpercival214763f2016-07-01 23:27:0114580 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1614581 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1014582 if (rv == ERR_IO_PENDING)
14583 rv = callback.WaitForResult();
14584 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1614585 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1014586 EXPECT_EQ(0, rv);
14587
14588 // Finally, the socket is released to the group.
Raul Tambre8335a6d2019-02-21 16:57:4314589 EXPECT_EQ(1u, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1414590}
14591
[email protected]65041fa2010-05-21 06:56:5314592// This tests the case that a request is issued via http instead of spdy after
14593// npn is negotiated.
bncd16676a2016-07-20 16:23:0114594TEST_F(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]65041fa2010-05-21 06:56:5314595 HttpRequestInfo request;
14596 request.method = "GET";
bncce36dca22015-04-21 22:11:2314597 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1014598 request.traffic_annotation =
14599 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]65041fa2010-05-21 06:56:5314600
14601 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2314602 MockWrite(
14603 "GET / HTTP/1.1\r\n"
14604 "Host: www.example.org\r\n"
14605 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5314606 };
14607
14608 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5214609 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4314610 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5214611 MockRead("\r\n"),
14612 MockRead("hello world"),
14613 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5314614 };
14615
[email protected]8ddf8322012-02-23 18:08:0614616 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614617 ssl.next_proto = kProtoHTTP11;
[email protected]65041fa2010-05-21 06:56:5314618
[email protected]bb88e1d32013-05-03 23:11:0714619 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5314620
Ryan Sleevib8d7ea02018-05-07 20:01:0114621 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0714622 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5314623
[email protected]49639fa2011-12-20 23:22:4114624 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5314625
danakj1fd259a02016-04-16 03:17:0914626 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614627 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]65041fa2010-05-21 06:56:5314628
tfarina42834112016-09-22 13:38:2014629 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]65041fa2010-05-21 06:56:5314630
robpercival214763f2016-07-01 23:27:0114631 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14632 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]65041fa2010-05-21 06:56:5314633
bnc691fda62016-08-12 00:43:1614634 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214635 ASSERT_TRUE(response);
14636 ASSERT_TRUE(response->headers);
[email protected]65041fa2010-05-21 06:56:5314637 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
14638
14639 std::string response_data;
bnc691fda62016-08-12 00:43:1614640 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]65041fa2010-05-21 06:56:5314641 EXPECT_EQ("hello world", response_data);
14642
14643 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214644 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]65041fa2010-05-21 06:56:5314645}
[email protected]26ef6582010-06-24 02:30:4714646
bnc55ff9da2015-08-19 18:42:3514647// Simulate the SSL handshake completing with an NPN negotiation followed by an
14648// immediate server closing of the socket.
14649// Regression test for https://crbug.com/46369.
bncd16676a2016-07-20 16:23:0114650TEST_F(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:4714651 HttpRequestInfo request;
14652 request.method = "GET";
bncce36dca22015-04-21 22:11:2314653 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1014654 request.traffic_annotation =
14655 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]26ef6582010-06-24 02:30:4714656
[email protected]8ddf8322012-02-23 18:08:0614657 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614658 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0714659 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4714660
Ryan Hamilton0239aac2018-05-19 00:03:1314661 spdy::SpdySerializedFrame req(
14662 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4114663 MockWrite spdy_writes[] = {CreateMockWrite(req, 1)};
[email protected]26ef6582010-06-24 02:30:4714664
14665 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0614666 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4714667 };
14668
Ryan Sleevib8d7ea02018-05-07 20:01:0114669 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0714670 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4714671
[email protected]49639fa2011-12-20 23:22:4114672 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4714673
danakj1fd259a02016-04-16 03:17:0914674 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614675 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]26ef6582010-06-24 02:30:4714676
tfarina42834112016-09-22 13:38:2014677 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114678 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14679 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]26ef6582010-06-24 02:30:4714680}
[email protected]65d34382010-07-01 18:12:2614681
[email protected]795cbf82013-07-22 09:37:2714682// A subclass of HttpAuthHandlerMock that records the request URL when
14683// it gets it. This is needed since the auth handler may get destroyed
14684// before we get a chance to query it.
14685class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
14686 public:
14687 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
14688
Chris Watkins7a41d3552017-12-01 02:13:2714689 ~UrlRecordingHttpAuthHandlerMock() override = default;
[email protected]795cbf82013-07-22 09:37:2714690
14691 protected:
dchengb03027d2014-10-21 12:00:2014692 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
14693 const HttpRequestInfo* request,
Bence Béky7236fb72018-08-01 14:35:0914694 CompletionOnceCallback callback,
dchengb03027d2014-10-21 12:00:2014695 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2714696 *url_ = request->url;
14697 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
Bence Béky7236fb72018-08-01 14:35:0914698 credentials, request, std::move(callback), auth_token);
[email protected]795cbf82013-07-22 09:37:2714699 }
14700
14701 private:
14702 GURL* url_;
14703};
14704
[email protected]8e6441ca2010-08-19 05:56:3814705// Test that if we cancel the transaction as the connection is completing, that
14706// everything tears down correctly.
bncd16676a2016-07-20 16:23:0114707TEST_F(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3814708 // Setup everything about the connection to complete synchronously, so that
14709 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
14710 // for is the callback from the HttpStreamRequest.
14711 // Then cancel the transaction.
14712 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3614713 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3814714 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0614715 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
14716 MockRead(SYNCHRONOUS, "hello world"),
14717 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3814718 };
14719
[email protected]8e6441ca2010-08-19 05:56:3814720 HttpRequestInfo request;
14721 request.method = "GET";
bncce36dca22015-04-21 22:11:2314722 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1014723 request.traffic_annotation =
14724 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8e6441ca2010-08-19 05:56:3814725
danakj1fd259a02016-04-16 03:17:0914726 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5814727 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1914728 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2714729
Ryan Sleevib8d7ea02018-05-07 20:01:0114730 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]8e6441ca2010-08-19 05:56:3814731 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0714732 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3814733
[email protected]49639fa2011-12-20 23:22:4114734 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3814735
vishal.b62985ca92015-04-17 08:45:5114736 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4114737 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114738 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8e6441ca2010-08-19 05:56:3814739 trans.reset(); // Cancel the transaction here.
14740
fdoray92e35a72016-06-10 15:54:5514741 base::RunLoop().RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3014742}
14743
[email protected]ecab6e052014-05-16 14:58:1214744// Test that if a transaction is cancelled after receiving the headers, the
14745// stream is drained properly and added back to the socket pool. The main
14746// purpose of this test is to make sure that an HttpStreamParser can be read
14747// from after the HttpNetworkTransaction and the objects it owns have been
14748// deleted.
14749// See http://crbug.com/368418
bncd16676a2016-07-20 16:23:0114750TEST_F(HttpNetworkTransactionTest, CancelAfterHeaders) {
[email protected]ecab6e052014-05-16 14:58:1214751 MockRead data_reads[] = {
14752 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
14753 MockRead(ASYNC, "Content-Length: 2\r\n"),
14754 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
14755 MockRead(ASYNC, "1"),
14756 // 2 async reads are necessary to trigger a ReadResponseBody call after the
14757 // HttpNetworkTransaction has been deleted.
14758 MockRead(ASYNC, "2"),
14759 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
14760 };
Ryan Sleevib8d7ea02018-05-07 20:01:0114761 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]ecab6e052014-05-16 14:58:1214762 session_deps_.socket_factory->AddSocketDataProvider(&data);
14763
danakj1fd259a02016-04-16 03:17:0914764 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]ecab6e052014-05-16 14:58:1214765
14766 {
14767 HttpRequestInfo request;
14768 request.method = "GET";
bncce36dca22015-04-21 22:11:2314769 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1014770 request.traffic_annotation =
14771 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ecab6e052014-05-16 14:58:1214772
dcheng48459ac22014-08-26 00:46:4114773 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1214774 TestCompletionCallback callback;
14775
tfarina42834112016-09-22 13:38:2014776 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114777 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ecab6e052014-05-16 14:58:1214778 callback.WaitForResult();
14779
14780 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214781 ASSERT_TRUE(response);
14782 EXPECT_TRUE(response->headers);
[email protected]ecab6e052014-05-16 14:58:1214783 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
14784
14785 // The transaction and HttpRequestInfo are deleted.
14786 }
14787
14788 // Let the HttpResponseBodyDrainer drain the socket.
fdoray92e35a72016-06-10 15:54:5514789 base::RunLoop().RunUntilIdle();
[email protected]ecab6e052014-05-16 14:58:1214790
14791 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4114792 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1214793}
14794
[email protected]76a505b2010-08-25 06:23:0014795// Test a basic GET request through a proxy.
bncd16676a2016-07-20 16:23:0114796TEST_F(HttpNetworkTransactionTest, ProxyGet) {
Lily Houghton8c2f97d2018-01-22 05:06:5914797 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4914798 ProxyResolutionService::CreateFixedFromPacResult(
14799 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5114800 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714801 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0914802 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0014803
[email protected]76a505b2010-08-25 06:23:0014804 HttpRequestInfo request;
14805 request.method = "GET";
bncce36dca22015-04-21 22:11:2314806 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1014807 request.traffic_annotation =
14808 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0014809
14810 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2314811 MockWrite(
14812 "GET http://www.example.org/ HTTP/1.1\r\n"
14813 "Host: www.example.org\r\n"
14814 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014815 };
14816
14817 MockRead data_reads1[] = {
14818 MockRead("HTTP/1.1 200 OK\r\n"),
14819 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14820 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0614821 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0014822 };
14823
Ryan Sleevib8d7ea02018-05-07 20:01:0114824 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:0714825 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0014826
[email protected]49639fa2011-12-20 23:22:4114827 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0014828
bnc691fda62016-08-12 00:43:1614829 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0914830 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1614831 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0914832 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
14833 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5014834
bnc691fda62016-08-12 00:43:1614835 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114836 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0014837
14838 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0114839 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:0014840
bnc691fda62016-08-12 00:43:1614841 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214842 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0014843
14844 EXPECT_TRUE(response->headers->IsKeepAlive());
14845 EXPECT_EQ(200, response->headers->response_code());
14846 EXPECT_EQ(100, response->headers->GetContentLength());
14847 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4714848 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
14849 HostPortPair::FromString("myproxy:70")),
14850 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0914851 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
14852 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
14853 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0014854 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2014855
14856 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1614857 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2014858 TestLoadTimingNotReusedWithPac(load_timing_info,
14859 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0014860}
14861
14862// Test a basic HTTPS GET request through a proxy.
bncd16676a2016-07-20 16:23:0114863TEST_F(HttpNetworkTransactionTest, ProxyTunnelGet) {
Lily Houghton8c2f97d2018-01-22 05:06:5914864 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4914865 ProxyResolutionService::CreateFixedFromPacResult(
14866 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5114867 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714868 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0914869 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0014870
[email protected]76a505b2010-08-25 06:23:0014871 HttpRequestInfo request;
14872 request.method = "GET";
bncce36dca22015-04-21 22:11:2314873 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1014874 request.traffic_annotation =
14875 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0014876
14877 // Since we have proxy, should try to establish tunnel.
14878 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1714879 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
14880 "Host: www.example.org:443\r\n"
14881 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014882
rsleevidb16bb02015-11-12 23:47:1714883 MockWrite("GET / HTTP/1.1\r\n"
14884 "Host: www.example.org\r\n"
14885 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014886 };
14887
14888 MockRead data_reads1[] = {
14889 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
14890
14891 MockRead("HTTP/1.1 200 OK\r\n"),
14892 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14893 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0614894 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0014895 };
14896
Ryan Sleevib8d7ea02018-05-07 20:01:0114897 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:0714898 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0614899 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0714900 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0014901
[email protected]49639fa2011-12-20 23:22:4114902 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0014903
bnc691fda62016-08-12 00:43:1614904 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0914905 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1614906 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0914907 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
14908 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5014909
bnc691fda62016-08-12 00:43:1614910 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114911 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0014912
14913 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0114914 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:4614915 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4014916 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0014917 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014918 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
14919 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0014920 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4014921 entries, pos,
mikecirone8b85c432016-09-08 19:11:0014922 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
14923 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0014924
bnc691fda62016-08-12 00:43:1614925 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214926 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0014927
14928 EXPECT_TRUE(response->headers->IsKeepAlive());
14929 EXPECT_EQ(200, response->headers->response_code());
14930 EXPECT_EQ(100, response->headers->GetContentLength());
14931 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
14932 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4714933 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
14934 HostPortPair::FromString("myproxy:70")),
14935 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0914936 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
14937 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
14938 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]029c83b62013-01-24 05:28:2014939
14940 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1614941 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2014942 TestLoadTimingNotReusedWithPac(load_timing_info,
14943 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0014944}
14945
rsleevidb16bb02015-11-12 23:47:1714946// Test a basic HTTPS GET request through a proxy, connecting to an IPv6
14947// literal host.
bncd16676a2016-07-20 16:23:0114948TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetIPv6) {
Lily Houghton8c2f97d2018-01-22 05:06:5914949 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4914950 ProxyResolutionService::CreateFixedFromPacResult(
14951 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
rsleevidb16bb02015-11-12 23:47:1714952 BoundTestNetLog log;
14953 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0914954 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
rsleevidb16bb02015-11-12 23:47:1714955
14956 HttpRequestInfo request;
14957 request.method = "GET";
Eric Romanda790f92018-11-07 19:17:1514958 request.url = GURL("https://[::2]:443/");
Ramin Halavatib5e433e2018-02-07 07:41:1014959 request.traffic_annotation =
14960 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rsleevidb16bb02015-11-12 23:47:1714961
14962 // Since we have proxy, should try to establish tunnel.
14963 MockWrite data_writes1[] = {
Eric Romanda790f92018-11-07 19:17:1514964 MockWrite("CONNECT [::2]:443 HTTP/1.1\r\n"
14965 "Host: [::2]:443\r\n"
rsleevidb16bb02015-11-12 23:47:1714966 "Proxy-Connection: keep-alive\r\n\r\n"),
14967
14968 MockWrite("GET / HTTP/1.1\r\n"
Eric Romanda790f92018-11-07 19:17:1514969 "Host: [::2]\r\n"
rsleevidb16bb02015-11-12 23:47:1714970 "Connection: keep-alive\r\n\r\n"),
14971 };
14972
14973 MockRead data_reads1[] = {
14974 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
14975
14976 MockRead("HTTP/1.1 200 OK\r\n"),
14977 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14978 MockRead("Content-Length: 100\r\n\r\n"),
14979 MockRead(SYNCHRONOUS, OK),
14980 };
14981
Ryan Sleevib8d7ea02018-05-07 20:01:0114982 StaticSocketDataProvider data1(data_reads1, data_writes1);
rsleevidb16bb02015-11-12 23:47:1714983 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14984 SSLSocketDataProvider ssl(ASYNC, OK);
14985 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14986
14987 TestCompletionCallback callback1;
14988
bnc691fda62016-08-12 00:43:1614989 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
rsleevidb16bb02015-11-12 23:47:1714990
bnc691fda62016-08-12 00:43:1614991 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114992 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rsleevidb16bb02015-11-12 23:47:1714993
14994 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0114995 EXPECT_THAT(rv, IsOk());
rsleevidb16bb02015-11-12 23:47:1714996 TestNetLogEntry::List entries;
14997 log.GetEntries(&entries);
14998 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014999 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
15000 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1715001 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0015002 entries, pos,
15003 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
15004 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1715005
bnc691fda62016-08-12 00:43:1615006 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5215007 ASSERT_TRUE(response);
rsleevidb16bb02015-11-12 23:47:1715008
15009 EXPECT_TRUE(response->headers->IsKeepAlive());
15010 EXPECT_EQ(200, response->headers->response_code());
15011 EXPECT_EQ(100, response->headers->GetContentLength());
15012 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
15013 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4715014 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
15015 HostPortPair::FromString("myproxy:70")),
15016 response->proxy_server);
rsleevidb16bb02015-11-12 23:47:1715017
15018 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1615019 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
rsleevidb16bb02015-11-12 23:47:1715020 TestLoadTimingNotReusedWithPac(load_timing_info,
15021 CONNECT_TIMING_HAS_SSL_TIMES);
15022}
15023
[email protected]76a505b2010-08-25 06:23:0015024// Test a basic HTTPS GET request through a proxy, but the server hangs up
15025// while establishing the tunnel.
bncd16676a2016-07-20 16:23:0115026TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
Ramin Halavatica8d5252018-03-12 05:33:4915027 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
15028 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5115029 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0715030 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0915031 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0015032
[email protected]76a505b2010-08-25 06:23:0015033 HttpRequestInfo request;
15034 request.method = "GET";
bncce36dca22015-04-21 22:11:2315035 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1015036 request.traffic_annotation =
15037 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0015038
15039 // Since we have proxy, should try to establish tunnel.
15040 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1715041 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
15042 "Host: www.example.org:443\r\n"
15043 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0015044
rsleevidb16bb02015-11-12 23:47:1715045 MockWrite("GET / HTTP/1.1\r\n"
15046 "Host: www.example.org\r\n"
15047 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0015048 };
15049
15050 MockRead data_reads1[] = {
[email protected]76a505b2010-08-25 06:23:0015051 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0615052 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0015053 };
15054
Ryan Sleevib8d7ea02018-05-07 20:01:0115055 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:0715056 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0615057 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0715058 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0015059
[email protected]49639fa2011-12-20 23:22:4115060 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0015061
bnc691fda62016-08-12 00:43:1615062 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5015063
bnc691fda62016-08-12 00:43:1615064 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0115065 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0015066
15067 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0115068 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
mmenke43758e62015-05-04 21:09:4615069 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4015070 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0015071 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0015072 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
15073 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0015074 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4015075 entries, pos,
mikecirone8b85c432016-09-08 19:11:0015076 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
15077 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0015078}
15079
[email protected]749eefa82010-09-13 22:14:0315080// Test for crbug.com/55424.
bncd16676a2016-07-20 16:23:0115081TEST_F(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
Ryan Hamilton0239aac2018-05-19 00:03:1315082 spdy::SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4915083 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4115084 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]749eefa82010-09-13 22:14:0315085
Raul Tambre94493c652019-03-11 17:18:3515086 spdy::SpdySerializedFrame resp(
15087 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1315088 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0315089 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115090 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0315091 };
15092
Ryan Sleevib8d7ea02018-05-07 20:01:0115093 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0715094 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0315095
[email protected]8ddf8322012-02-23 18:08:0615096 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615097 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0715098 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0315099
danakj1fd259a02016-04-16 03:17:0915100 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0315101
15102 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2315103 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4015104 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
Matt Menke2436b2f2018-12-11 18:07:1115105 PRIVACY_MODE_DISABLED,
15106 SpdySessionKey::IsProxySession::kFalse, SocketTag());
[email protected]795cbf82013-07-22 09:37:2715107 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:5215108 CreateSpdySession(session.get(), key, NetLogWithSource());
[email protected]749eefa82010-09-13 22:14:0315109
15110 HttpRequestInfo request;
15111 request.method = "GET";
bncce36dca22015-04-21 22:11:2315112 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1015113 request.traffic_annotation =
15114 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]749eefa82010-09-13 22:14:0315115
bnc691fda62016-08-12 00:43:1615116 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]749eefa82010-09-13 22:14:0315117
[email protected]41d64e82013-07-03 22:44:2615118 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2015119 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115120 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15121 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]749eefa82010-09-13 22:14:0315122}
15123
[email protected]73b8dd222010-11-11 19:55:2415124// Given a net error, cause that error to be returned from the first Write()
bnc691fda62016-08-12 00:43:1615125// call and verify that the HttpNetworkTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0215126void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0715127 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2915128 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2715129 request_info.url = GURL("https://www.example.com/");
15130 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2915131 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:1015132 request_info.traffic_annotation =
15133 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2715134
[email protected]8ddf8322012-02-23 18:08:0615135 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2915136 MockWrite data_writes[] = {
15137 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2415138 };
Ryan Sleevib8d7ea02018-05-07 20:01:0115139 StaticSocketDataProvider data(base::span<MockRead>(), data_writes);
[email protected]bb88e1d32013-05-03 23:11:0715140 session_deps_.socket_factory->AddSocketDataProvider(&data);
15141 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2415142
danakj1fd259a02016-04-16 03:17:0915143 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615144 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]73b8dd222010-11-11 19:55:2415145
[email protected]49639fa2011-12-20 23:22:4115146 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2015147 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
ttuttle859dc7a2015-04-23 19:42:2915148 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2415149 rv = callback.WaitForResult();
15150 ASSERT_EQ(error, rv);
15151}
15152
bncd16676a2016-07-20 16:23:0115153TEST_F(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2415154 // Just check a grab bag of cert errors.
15155 static const int kErrors[] = {
15156 ERR_CERT_COMMON_NAME_INVALID,
15157 ERR_CERT_AUTHORITY_INVALID,
15158 ERR_CERT_DATE_INVALID,
15159 };
Avi Drissman4365a4782018-12-28 19:26:2415160 for (size_t i = 0; i < base::size(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0615161 CheckErrorIsPassedBack(kErrors[i], ASYNC);
15162 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2415163 }
15164}
15165
[email protected]bd0b6772011-01-11 19:59:3015166// Ensure that a client certificate is removed from the SSL client auth
15167// cache when:
15168// 1) No proxy is involved.
15169// 2) TLS False Start is disabled.
15170// 3) The initial TLS handshake requests a client certificate.
15171// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0115172TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_NoFalseStart) {
ttuttle859dc7a2015-04-23 19:42:2915173 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2715174 request_info.url = GURL("https://www.example.com/");
15175 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2915176 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:1015177 request_info.traffic_annotation =
15178 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2715179
[email protected]bd0b6772011-01-11 19:59:3015180 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4115181 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3015182
15183 // [ssl_]data1 contains the data for the first SSL handshake. When a
15184 // CertificateRequest is received for the first time, the handshake will
15185 // be aborted to allow the caller to provide a certificate.
ttuttle859dc7a2015-04-23 19:42:2915186 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3015187 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715188 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
Ryan Sleevib8d7ea02018-05-07 20:01:0115189 StaticSocketDataProvider data1;
[email protected]bb88e1d32013-05-03 23:11:0715190 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3015191
15192 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
15193 // False Start is not being used, the result of the SSL handshake will be
15194 // returned as part of the SSLClientSocket::Connect() call. This test
15195 // matches the result of a server sending a handshake_failure alert,
15196 // rather than a Finished message, because it requires a client
15197 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2915198 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3015199 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715200 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
Ryan Sleevib8d7ea02018-05-07 20:01:0115201 StaticSocketDataProvider data2;
[email protected]bb88e1d32013-05-03 23:11:0715202 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3015203
15204 // [ssl_]data3 contains the data for the third SSL handshake. When a
15205 // connection to a server fails during an SSL handshake,
Steven Valdez0ef94d02018-11-19 23:28:1315206 // HttpNetworkTransaction will attempt to fallback to TLSv1.2 if the previous
15207 // connection was attempted with TLSv1.3. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3015208 // of the HttpNetworkTransaction. Because this test failure is due to
15209 // requiring a client certificate, this fallback handshake should also
15210 // fail.
ttuttle859dc7a2015-04-23 19:42:2915211 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
Steven Valdez0ef94d02018-11-19 23:28:1315212 ssl_data3.expected_ssl_version_max = SSL_PROTOCOL_VERSION_TLS1_2;
[email protected]bd0b6772011-01-11 19:59:3015213 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715214 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
Ryan Sleevib8d7ea02018-05-07 20:01:0115215 StaticSocketDataProvider data3;
[email protected]bb88e1d32013-05-03 23:11:0715216 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3015217
[email protected]80c75f682012-05-26 16:22:1715218 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
15219 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4215220 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
15221 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]80c75f682012-05-26 16:22:1715222 // of the HttpNetworkTransaction. Because this test failure is due to
15223 // requiring a client certificate, this fallback handshake should also
15224 // fail.
ttuttle859dc7a2015-04-23 19:42:2915225 SSLSocketDataProvider ssl_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1715226 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715227 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
Ryan Sleevib8d7ea02018-05-07 20:01:0115228 StaticSocketDataProvider data4;
[email protected]bb88e1d32013-05-03 23:11:0715229 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1715230
danakj1fd259a02016-04-16 03:17:0915231 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615232 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3015233
[email protected]bd0b6772011-01-11 19:59:3015234 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4115235 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2015236 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115237 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3015238
15239 // Complete the SSL handshake, which should abort due to requiring a
15240 // client certificate.
15241 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115242 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3015243
15244 // Indicate that no certificate should be supplied. From the perspective
15245 // of SSLClientCertCache, NULL is just as meaningful as a real
15246 // certificate, so this is the same as supply a
15247 // legitimate-but-unacceptable certificate.
Raul Tambre94493c652019-03-11 17:18:3515248 rv = trans.RestartWithCertificate(nullptr, nullptr, callback.callback());
robpercival214763f2016-07-01 23:27:0115249 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3015250
15251 // Ensure the certificate was added to the client auth cache before
15252 // allowing the connection to continue restarting.
15253 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5415254 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4115255 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415256 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5215257 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3015258
15259 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1715260 // then consume ssl_data3 and ssl_data4, both of which should also fail.
15261 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3015262 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115263 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3015264
15265 // Ensure that the client certificate is removed from the cache on a
15266 // handshake failure.
[email protected]791879c2013-12-17 07:22:4115267 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415268 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3015269}
15270
15271// Ensure that a client certificate is removed from the SSL client auth
15272// cache when:
15273// 1) No proxy is involved.
15274// 2) TLS False Start is enabled.
15275// 3) The initial TLS handshake requests a client certificate.
15276// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0115277TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2915278 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2715279 request_info.url = GURL("https://www.example.com/");
15280 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2915281 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:1015282 request_info.traffic_annotation =
15283 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2715284
[email protected]bd0b6772011-01-11 19:59:3015285 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4115286 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3015287
15288 // When TLS False Start is used, SSLClientSocket::Connect() calls will
15289 // return successfully after reading up to the peer's Certificate message.
15290 // This is to allow the caller to call SSLClientSocket::Write(), which can
15291 // enqueue application data to be sent in the same packet as the
15292 // ChangeCipherSpec and Finished messages.
15293 // The actual handshake will be finished when SSLClientSocket::Read() is
15294 // called, which expects to process the peer's ChangeCipherSpec and
15295 // Finished messages. If there was an error negotiating with the peer,
15296 // such as due to the peer requiring a client certificate when none was
15297 // supplied, the alert sent by the peer won't be processed until Read() is
15298 // called.
15299
15300 // Like the non-False Start case, when a client certificate is requested by
15301 // the peer, the handshake is aborted during the Connect() call.
15302 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2915303 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3015304 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715305 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
Ryan Sleevib8d7ea02018-05-07 20:01:0115306 StaticSocketDataProvider data1;
[email protected]bb88e1d32013-05-03 23:11:0715307 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3015308
15309 // When a client certificate is supplied, Connect() will not be aborted
15310 // when the peer requests the certificate. Instead, the handshake will
15311 // artificially succeed, allowing the caller to write the HTTP request to
15312 // the socket. The handshake messages are not processed until Read() is
15313 // called, which then detects that the handshake was aborted, due to the
15314 // peer sending a handshake_failure because it requires a client
15315 // certificate.
ttuttle859dc7a2015-04-23 19:42:2915316 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3015317 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715318 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2915319 MockRead data2_reads[] = {
15320 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3015321 };
Ryan Sleevib8d7ea02018-05-07 20:01:0115322 StaticSocketDataProvider data2(data2_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0715323 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3015324
15325 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1715326 // the data for the SSL handshake once the TLSv1.1 connection falls back to
15327 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2915328 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3015329 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715330 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
Ryan Sleevib8d7ea02018-05-07 20:01:0115331 StaticSocketDataProvider data3(data2_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0715332 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3015333
[email protected]80c75f682012-05-26 16:22:1715334 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
15335 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2915336 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1715337 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715338 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
Ryan Sleevib8d7ea02018-05-07 20:01:0115339 StaticSocketDataProvider data4(data2_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0715340 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1715341
[email protected]7799de12013-05-30 05:52:5115342 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2915343 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5115344 ssl_data5.cert_request_info = cert_request.get();
15345 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
Ryan Sleevib8d7ea02018-05-07 20:01:0115346 StaticSocketDataProvider data5(data2_reads, base::span<MockWrite>());
[email protected]7799de12013-05-30 05:52:5115347 session_deps_.socket_factory->AddSocketDataProvider(&data5);
15348
danakj1fd259a02016-04-16 03:17:0915349 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615350 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3015351
[email protected]bd0b6772011-01-11 19:59:3015352 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4115353 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2015354 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115355 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3015356
15357 // Complete the SSL handshake, which should abort due to requiring a
15358 // client certificate.
15359 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115360 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3015361
15362 // Indicate that no certificate should be supplied. From the perspective
15363 // of SSLClientCertCache, NULL is just as meaningful as a real
15364 // certificate, so this is the same as supply a
15365 // legitimate-but-unacceptable certificate.
Raul Tambre94493c652019-03-11 17:18:3515366 rv = trans.RestartWithCertificate(nullptr, nullptr, callback.callback());
robpercival214763f2016-07-01 23:27:0115367 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3015368
15369 // Ensure the certificate was added to the client auth cache before
15370 // allowing the connection to continue restarting.
15371 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5415372 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4115373 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415374 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5215375 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3015376
[email protected]bd0b6772011-01-11 19:59:3015377 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1715378 // then consume ssl_data3 and ssl_data4, both of which should also fail.
15379 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3015380 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115381 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3015382
15383 // Ensure that the client certificate is removed from the cache on a
15384 // handshake failure.
[email protected]791879c2013-12-17 07:22:4115385 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415386 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3015387}
15388
[email protected]8c405132011-01-11 22:03:1815389// Ensure that a client certificate is removed from the SSL client auth
15390// cache when:
15391// 1) An HTTPS proxy is involved.
15392// 3) The HTTPS proxy requests a client certificate.
15393// 4) The client supplies an invalid/unacceptable certificate for the
15394// proxy.
15395// The test is repeated twice, first for connecting to an HTTPS endpoint,
15396// then for connecting to an HTTP endpoint.
bncd16676a2016-07-20 16:23:0115397TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
Ramin Halavatica8d5252018-03-12 05:33:4915398 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
15399 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5115400 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0715401 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1815402
15403 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4115404 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1815405
15406 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
15407 // [ssl_]data[1-3]. Rather than represending the endpoint
15408 // (www.example.com:443), they represent failures with the HTTPS proxy
15409 // (proxy:70).
ttuttle859dc7a2015-04-23 19:42:2915410 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1815411 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715412 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
Ryan Sleevib8d7ea02018-05-07 20:01:0115413 StaticSocketDataProvider data1;
[email protected]bb88e1d32013-05-03 23:11:0715414 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1815415
ttuttle859dc7a2015-04-23 19:42:2915416 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1815417 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715418 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
Ryan Sleevib8d7ea02018-05-07 20:01:0115419 StaticSocketDataProvider data2;
[email protected]bb88e1d32013-05-03 23:11:0715420 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1815421
[email protected]80c75f682012-05-26 16:22:1715422 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
15423#if 0
ttuttle859dc7a2015-04-23 19:42:2915424 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1815425 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715426 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
Ryan Sleevib8d7ea02018-05-07 20:01:0115427 StaticSocketDataProvider data3;
[email protected]bb88e1d32013-05-03 23:11:0715428 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1715429#endif
[email protected]8c405132011-01-11 22:03:1815430
ttuttle859dc7a2015-04-23 19:42:2915431 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1815432 requests[0].url = GURL("https://www.example.com/");
15433 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2915434 requests[0].load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:1015435 requests[0].traffic_annotation =
15436 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c405132011-01-11 22:03:1815437
15438 requests[1].url = GURL("http://www.example.com/");
15439 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2915440 requests[1].load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:1015441 requests[1].traffic_annotation =
15442 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c405132011-01-11 22:03:1815443
Avi Drissman4365a4782018-12-28 19:26:2415444 for (size_t i = 0; i < base::size(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0715445 session_deps_.socket_factory->ResetNextMockIndexes();
danakj1fd259a02016-04-16 03:17:0915446 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615447 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]8c405132011-01-11 22:03:1815448
15449 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4115450 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2015451 int rv = trans.Start(&requests[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115452 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1815453
15454 // Complete the SSL handshake, which should abort due to requiring a
15455 // client certificate.
15456 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115457 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]8c405132011-01-11 22:03:1815458
15459 // Indicate that no certificate should be supplied. From the perspective
15460 // of SSLClientCertCache, NULL is just as meaningful as a real
15461 // certificate, so this is the same as supply a
15462 // legitimate-but-unacceptable certificate.
Raul Tambre94493c652019-03-11 17:18:3515463 rv = trans.RestartWithCertificate(nullptr, nullptr, callback.callback());
robpercival214763f2016-07-01 23:27:0115464 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1815465
15466 // Ensure the certificate was added to the client auth cache before
15467 // allowing the connection to continue restarting.
15468 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5415469 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4115470 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415471 HostPortPair("proxy", 70), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5215472 ASSERT_FALSE(client_cert);
[email protected]8c405132011-01-11 22:03:1815473 // Ensure the certificate was NOT cached for the endpoint. This only
15474 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4115475 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415476 HostPortPair("www.example.com", 443), &client_cert,
15477 &client_private_key));
[email protected]8c405132011-01-11 22:03:1815478
15479 // Restart the handshake. This will consume ssl_data2, which fails, and
15480 // then consume ssl_data3, which should also fail. The result code is
15481 // checked against what ssl_data3 should return.
15482 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115483 ASSERT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]8c405132011-01-11 22:03:1815484
15485 // Now that the new handshake has failed, ensure that the client
15486 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4115487 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415488 HostPortPair("proxy", 70), &client_cert, &client_private_key));
[email protected]791879c2013-12-17 07:22:4115489 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415490 HostPortPair("www.example.com", 443), &client_cert,
15491 &client_private_key));
[email protected]8c405132011-01-11 22:03:1815492 }
15493}
15494
bncd16676a2016-07-20 16:23:0115495TEST_F(HttpNetworkTransactionTest, UseIPConnectionPooling) {
[email protected]e3ceb682011-06-28 23:55:4615496 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1915497 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0915498 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4615499
bnc032658ba2016-09-26 18:17:1515500 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4615501
Ryan Hamilton0239aac2018-05-19 00:03:1315502 spdy::SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4915503 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3815504 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1315505 spdy::SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3715506 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4615507 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115508 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4615509 };
Ryan Hamilton0239aac2018-05-19 00:03:1315510 spdy::SpdySerializedFrame host1_resp(
Raul Tambre94493c652019-03-11 17:18:3515511 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1315512 spdy::SpdySerializedFrame host1_resp_body(
bncdf80d44fd2016-07-15 20:27:4115513 spdy_util_.ConstructSpdyDataFrame(1, true));
Ryan Hamilton0239aac2018-05-19 00:03:1315514 spdy::SpdySerializedFrame host2_resp(
Raul Tambre94493c652019-03-11 17:18:3515515 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
Ryan Hamilton0239aac2018-05-19 00:03:1315516 spdy::SpdySerializedFrame host2_resp_body(
bncdf80d44fd2016-07-15 20:27:4115517 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4615518 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115519 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
15520 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1315521 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4615522 };
15523
eroman36d84e54432016-03-17 03:23:0215524 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0215525 MockConnect connect(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115526 SequencedSocketData spdy_data(connect, spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0715527 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4615528
[email protected]aa22b242011-11-16 18:58:2915529 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4615530 HttpRequestInfo request1;
15531 request1.method = "GET";
bncce36dca22015-04-21 22:11:2315532 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4615533 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015534 request1.traffic_annotation =
15535 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015536 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4615537
tfarina42834112016-09-22 13:38:2015538 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115539 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15540 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615541
15542 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5215543 ASSERT_TRUE(response);
15544 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215545 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4615546
15547 std::string response_data;
robpercival214763f2016-07-01 23:27:0115548 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615549 EXPECT_EQ("hello!", response_data);
15550
bnca4d611d2016-09-22 19:55:3715551 // Preload mail.example.com into HostCache.
Eric Orthf4db66a2019-02-19 21:35:3315552 rv = session_deps_.host_resolver->LoadIntoCache(
15553 HostPortPair("mail.example.com", 443), base::nullopt);
robpercival214763f2016-07-01 23:27:0115554 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4615555
15556 HttpRequestInfo request2;
15557 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3715558 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4615559 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015560 request2.traffic_annotation =
15561 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015562 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4615563
tfarina42834112016-09-22 13:38:2015564 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115565 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15566 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615567
15568 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215569 ASSERT_TRUE(response);
15570 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215571 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4615572 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215573 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115574 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615575 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4615576}
15577
bncd16676a2016-07-20 16:23:0115578TEST_F(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d2b5f092012-06-08 23:55:0215579 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1915580 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0915581 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0215582
bnc032658ba2016-09-26 18:17:1515583 AddSSLSocketData();
[email protected]d2b5f092012-06-08 23:55:0215584
Ryan Hamilton0239aac2018-05-19 00:03:1315585 spdy::SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4915586 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3815587 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1315588 spdy::SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3715589 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0215590 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115591 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0215592 };
Ryan Hamilton0239aac2018-05-19 00:03:1315593 spdy::SpdySerializedFrame host1_resp(
Raul Tambre94493c652019-03-11 17:18:3515594 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1315595 spdy::SpdySerializedFrame host1_resp_body(
bncdf80d44fd2016-07-15 20:27:4115596 spdy_util_.ConstructSpdyDataFrame(1, true));
Ryan Hamilton0239aac2018-05-19 00:03:1315597 spdy::SpdySerializedFrame host2_resp(
Raul Tambre94493c652019-03-11 17:18:3515598 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
Ryan Hamilton0239aac2018-05-19 00:03:1315599 spdy::SpdySerializedFrame host2_resp_body(
bncdf80d44fd2016-07-15 20:27:4115600 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0215601 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115602 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
15603 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1315604 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0215605 };
15606
eroman36d84e54432016-03-17 03:23:0215607 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0215608 MockConnect connect(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115609 SequencedSocketData spdy_data(connect, spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0715610 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0215611
15612 TestCompletionCallback callback;
15613 HttpRequestInfo request1;
15614 request1.method = "GET";
bncce36dca22015-04-21 22:11:2315615 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0215616 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015617 request1.traffic_annotation =
15618 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015619 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0215620
tfarina42834112016-09-22 13:38:2015621 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115622 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15623 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0215624
15625 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5215626 ASSERT_TRUE(response);
15627 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215628 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0215629
15630 std::string response_data;
robpercival214763f2016-07-01 23:27:0115631 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0215632 EXPECT_EQ("hello!", response_data);
15633
15634 HttpRequestInfo request2;
15635 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3715636 request2.url = GURL("https://mail.example.com/");
[email protected]d2b5f092012-06-08 23:55:0215637 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015638 request2.traffic_annotation =
15639 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015640 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0215641
tfarina42834112016-09-22 13:38:2015642 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115643 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15644 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0215645
15646 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215647 ASSERT_TRUE(response);
15648 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215649 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0215650 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215651 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115652 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0215653 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0215654}
15655
bnc8016c1f2017-03-31 02:11:2915656// Regression test for https://crbug.com/546991.
15657// The server might not be able to serve an IP pooled request, and might send a
15658// 421 Misdirected Request response status to indicate this.
15659// HttpNetworkTransaction should reset the request and retry without IP pooling.
15660TEST_F(HttpNetworkTransactionTest, RetryWithoutConnectionPooling) {
15661 // Two hosts resolve to the same IP address.
15662 const std::string ip_addr = "1.2.3.4";
15663 IPAddress ip;
15664 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
15665 IPEndPoint peer_addr = IPEndPoint(ip, 443);
15666
Jeremy Roman0579ed62017-08-29 15:56:1915667 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
bnc8016c1f2017-03-31 02:11:2915668 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
15669 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
15670
15671 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15672
15673 // Two requests on the first connection.
Ryan Hamilton0239aac2018-05-19 00:03:1315674 spdy::SpdySerializedFrame req1(
bnc8016c1f2017-03-31 02:11:2915675 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
15676 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1315677 spdy::SpdySerializedFrame req2(
bnc8016c1f2017-03-31 02:11:2915678 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1315679 spdy::SpdySerializedFrame rst(
15680 spdy_util_.ConstructSpdyRstStream(3, spdy::ERROR_CODE_CANCEL));
bnc8016c1f2017-03-31 02:11:2915681 MockWrite writes1[] = {
15682 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
15683 CreateMockWrite(rst, 6),
15684 };
15685
15686 // The first one succeeds, the second gets error 421 Misdirected Request.
Ryan Hamilton0239aac2018-05-19 00:03:1315687 spdy::SpdySerializedFrame resp1(
15688 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
15689 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
15690 spdy::SpdyHeaderBlock response_headers;
15691 response_headers[spdy::kHttp2StatusHeader] = "421";
15692 spdy::SpdySerializedFrame resp2(
bnc8016c1f2017-03-31 02:11:2915693 spdy_util_.ConstructSpdyReply(3, std::move(response_headers)));
15694 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
15695 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
15696
15697 MockConnect connect1(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115698 SequencedSocketData data1(connect1, reads1, writes1);
bnc8016c1f2017-03-31 02:11:2915699 session_deps_.socket_factory->AddSocketDataProvider(&data1);
15700
15701 AddSSLSocketData();
15702
15703 // Retry the second request on a second connection.
15704 SpdyTestUtil spdy_util2;
Ryan Hamilton0239aac2018-05-19 00:03:1315705 spdy::SpdySerializedFrame req3(
bnc8016c1f2017-03-31 02:11:2915706 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
15707 MockWrite writes2[] = {
15708 CreateMockWrite(req3, 0),
15709 };
15710
Ryan Hamilton0239aac2018-05-19 00:03:1315711 spdy::SpdySerializedFrame resp3(
15712 spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
15713 spdy::SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
bnc8016c1f2017-03-31 02:11:2915714 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
15715 MockRead(ASYNC, 0, 3)};
15716
15717 MockConnect connect2(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115718 SequencedSocketData data2(connect2, reads2, writes2);
bnc8016c1f2017-03-31 02:11:2915719 session_deps_.socket_factory->AddSocketDataProvider(&data2);
15720
15721 AddSSLSocketData();
15722
15723 // Preload mail.example.org into HostCache.
Eric Orthf4db66a2019-02-19 21:35:3315724 int rv = session_deps_.host_resolver->LoadIntoCache(
15725 HostPortPair("mail.example.com", 443), base::nullopt);
bnc8016c1f2017-03-31 02:11:2915726 EXPECT_THAT(rv, IsOk());
15727
15728 HttpRequestInfo request1;
15729 request1.method = "GET";
15730 request1.url = GURL("https://www.example.org/");
15731 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015732 request1.traffic_annotation =
15733 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8016c1f2017-03-31 02:11:2915734 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
15735
Eric Orthf4db66a2019-02-19 21:35:3315736 TestCompletionCallback callback;
bnc8016c1f2017-03-31 02:11:2915737 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
15738 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15739 rv = callback.WaitForResult();
15740 EXPECT_THAT(rv, IsOk());
15741
15742 const HttpResponseInfo* response = trans1.GetResponseInfo();
15743 ASSERT_TRUE(response);
15744 ASSERT_TRUE(response->headers);
15745 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
15746 EXPECT_TRUE(response->was_fetched_via_spdy);
15747 EXPECT_TRUE(response->was_alpn_negotiated);
15748 std::string response_data;
15749 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
15750 EXPECT_EQ("hello!", response_data);
15751
15752 HttpRequestInfo request2;
15753 request2.method = "GET";
15754 request2.url = GURL("https://mail.example.org/");
15755 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015756 request2.traffic_annotation =
15757 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8016c1f2017-03-31 02:11:2915758 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
15759
15760 BoundTestNetLog log;
15761 rv = trans2.Start(&request2, callback.callback(), log.bound());
15762 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15763 rv = callback.WaitForResult();
15764 EXPECT_THAT(rv, IsOk());
15765
15766 response = trans2.GetResponseInfo();
15767 ASSERT_TRUE(response);
15768 ASSERT_TRUE(response->headers);
15769 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
15770 EXPECT_TRUE(response->was_fetched_via_spdy);
15771 EXPECT_TRUE(response->was_alpn_negotiated);
15772 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
15773 EXPECT_EQ("hello!", response_data);
15774
15775 TestNetLogEntry::List entries;
15776 log.GetEntries(&entries);
davidbence688ae2017-05-04 15:12:5915777 ExpectLogContainsSomewhere(
15778 entries, 0, NetLogEventType::HTTP_TRANSACTION_RESTART_MISDIRECTED_REQUEST,
bnc8016c1f2017-03-31 02:11:2915779 NetLogEventPhase::NONE);
davidbence688ae2017-05-04 15:12:5915780}
15781
15782// Test that HTTP 421 responses are properly returned to the caller if received
15783// on the retry as well. HttpNetworkTransaction should not infinite loop or lose
15784// portions of the response.
15785TEST_F(HttpNetworkTransactionTest, ReturnHTTP421OnRetry) {
15786 // Two hosts resolve to the same IP address.
15787 const std::string ip_addr = "1.2.3.4";
15788 IPAddress ip;
15789 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
15790 IPEndPoint peer_addr = IPEndPoint(ip, 443);
15791
Jeremy Roman0579ed62017-08-29 15:56:1915792 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
davidbence688ae2017-05-04 15:12:5915793 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
15794 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
15795
15796 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15797
15798 // Two requests on the first connection.
Ryan Hamilton0239aac2018-05-19 00:03:1315799 spdy::SpdySerializedFrame req1(
davidbence688ae2017-05-04 15:12:5915800 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
15801 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1315802 spdy::SpdySerializedFrame req2(
davidbence688ae2017-05-04 15:12:5915803 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1315804 spdy::SpdySerializedFrame rst(
15805 spdy_util_.ConstructSpdyRstStream(3, spdy::ERROR_CODE_CANCEL));
davidbence688ae2017-05-04 15:12:5915806 MockWrite writes1[] = {
15807 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
15808 CreateMockWrite(rst, 6),
15809 };
15810
15811 // The first one succeeds, the second gets error 421 Misdirected Request.
Ryan Hamilton0239aac2018-05-19 00:03:1315812 spdy::SpdySerializedFrame resp1(
15813 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
15814 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
15815 spdy::SpdyHeaderBlock response_headers;
15816 response_headers[spdy::kHttp2StatusHeader] = "421";
15817 spdy::SpdySerializedFrame resp2(
davidbence688ae2017-05-04 15:12:5915818 spdy_util_.ConstructSpdyReply(3, response_headers.Clone()));
15819 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
15820 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
15821
15822 MockConnect connect1(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115823 SequencedSocketData data1(connect1, reads1, writes1);
davidbence688ae2017-05-04 15:12:5915824 session_deps_.socket_factory->AddSocketDataProvider(&data1);
15825
15826 AddSSLSocketData();
15827
15828 // Retry the second request on a second connection. It returns 421 Misdirected
15829 // Retry again.
15830 SpdyTestUtil spdy_util2;
Ryan Hamilton0239aac2018-05-19 00:03:1315831 spdy::SpdySerializedFrame req3(
davidbence688ae2017-05-04 15:12:5915832 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
15833 MockWrite writes2[] = {
15834 CreateMockWrite(req3, 0),
15835 };
15836
Ryan Hamilton0239aac2018-05-19 00:03:1315837 spdy::SpdySerializedFrame resp3(
davidbence688ae2017-05-04 15:12:5915838 spdy_util2.ConstructSpdyReply(1, std::move(response_headers)));
Ryan Hamilton0239aac2018-05-19 00:03:1315839 spdy::SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
davidbence688ae2017-05-04 15:12:5915840 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
15841 MockRead(ASYNC, 0, 3)};
15842
15843 MockConnect connect2(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115844 SequencedSocketData data2(connect2, reads2, writes2);
davidbence688ae2017-05-04 15:12:5915845 session_deps_.socket_factory->AddSocketDataProvider(&data2);
15846
15847 AddSSLSocketData();
15848
15849 // Preload mail.example.org into HostCache.
Eric Orthf4db66a2019-02-19 21:35:3315850 int rv = session_deps_.host_resolver->LoadIntoCache(
15851 HostPortPair("mail.example.com", 443), base::nullopt);
davidbence688ae2017-05-04 15:12:5915852 EXPECT_THAT(rv, IsOk());
15853
15854 HttpRequestInfo request1;
15855 request1.method = "GET";
15856 request1.url = GURL("https://www.example.org/");
15857 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015858 request1.traffic_annotation =
15859 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
davidbence688ae2017-05-04 15:12:5915860 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
15861
Eric Orthf4db66a2019-02-19 21:35:3315862 TestCompletionCallback callback;
davidbence688ae2017-05-04 15:12:5915863 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
15864 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15865 rv = callback.WaitForResult();
15866 EXPECT_THAT(rv, IsOk());
15867
15868 const HttpResponseInfo* response = trans1.GetResponseInfo();
15869 ASSERT_TRUE(response);
15870 ASSERT_TRUE(response->headers);
15871 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
15872 EXPECT_TRUE(response->was_fetched_via_spdy);
15873 EXPECT_TRUE(response->was_alpn_negotiated);
15874 std::string response_data;
15875 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
15876 EXPECT_EQ("hello!", response_data);
15877
15878 HttpRequestInfo request2;
15879 request2.method = "GET";
15880 request2.url = GURL("https://mail.example.org/");
15881 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015882 request2.traffic_annotation =
15883 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
davidbence688ae2017-05-04 15:12:5915884 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
15885
15886 BoundTestNetLog log;
15887 rv = trans2.Start(&request2, callback.callback(), log.bound());
15888 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15889 rv = callback.WaitForResult();
15890 EXPECT_THAT(rv, IsOk());
15891
15892 // After a retry, the 421 Misdirected Request is reported back up to the
15893 // caller.
15894 response = trans2.GetResponseInfo();
15895 ASSERT_TRUE(response);
15896 ASSERT_TRUE(response->headers);
15897 EXPECT_EQ("HTTP/1.1 421", response->headers->GetStatusLine());
15898 EXPECT_TRUE(response->was_fetched_via_spdy);
15899 EXPECT_TRUE(response->was_alpn_negotiated);
15900 EXPECT_TRUE(response->ssl_info.cert);
15901 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
15902 EXPECT_EQ("hello!", response_data);
bnc8016c1f2017-03-31 02:11:2915903}
15904
bncd16676a2016-07-20 16:23:0115905TEST_F(HttpNetworkTransactionTest,
mmenke5c642132015-06-02 16:05:1315906 UseIPConnectionPoolingWithHostCacheExpiration) {
Eric Orth1da75de2019-02-20 21:10:3415907 // Set up HostResolver to invalidate cached entries after 1 cached resolve.
15908 session_deps_.host_resolver =
15909 std::make_unique<MockCachingHostResolver>(1 /* cache_invalidation_num */);
danakj1fd259a02016-04-16 03:17:0915910 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4615911
bnc032658ba2016-09-26 18:17:1515912 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4615913
Ryan Hamilton0239aac2018-05-19 00:03:1315914 spdy::SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4915915 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3815916 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1315917 spdy::SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3715918 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4615919 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115920 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4615921 };
Ryan Hamilton0239aac2018-05-19 00:03:1315922 spdy::SpdySerializedFrame host1_resp(
Raul Tambre94493c652019-03-11 17:18:3515923 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1315924 spdy::SpdySerializedFrame host1_resp_body(
bncdf80d44fd2016-07-15 20:27:4115925 spdy_util_.ConstructSpdyDataFrame(1, true));
Ryan Hamilton0239aac2018-05-19 00:03:1315926 spdy::SpdySerializedFrame host2_resp(
Raul Tambre94493c652019-03-11 17:18:3515927 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
Ryan Hamilton0239aac2018-05-19 00:03:1315928 spdy::SpdySerializedFrame host2_resp_body(
bncdf80d44fd2016-07-15 20:27:4115929 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4615930 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115931 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
15932 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1315933 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4615934 };
15935
eroman36d84e54432016-03-17 03:23:0215936 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0215937 MockConnect connect(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115938 SequencedSocketData spdy_data(connect, spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0715939 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4615940
[email protected]aa22b242011-11-16 18:58:2915941 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4615942 HttpRequestInfo request1;
15943 request1.method = "GET";
bncce36dca22015-04-21 22:11:2315944 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4615945 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015946 request1.traffic_annotation =
15947 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015948 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4615949
tfarina42834112016-09-22 13:38:2015950 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115951 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15952 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615953
15954 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5215955 ASSERT_TRUE(response);
15956 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215957 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4615958
15959 std::string response_data;
robpercival214763f2016-07-01 23:27:0115960 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615961 EXPECT_EQ("hello!", response_data);
15962
15963 // Preload cache entries into HostCache.
Eric Orthf4db66a2019-02-19 21:35:3315964 rv = session_deps_.host_resolver->LoadIntoCache(
15965 HostPortPair("mail.example.com", 443), base::nullopt);
robpercival214763f2016-07-01 23:27:0115966 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4615967
15968 HttpRequestInfo request2;
15969 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3715970 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4615971 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015972 request2.traffic_annotation =
15973 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015974 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4615975
tfarina42834112016-09-22 13:38:2015976 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115977 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15978 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615979
15980 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215981 ASSERT_TRUE(response);
15982 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215983 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4615984 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215985 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115986 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615987 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4615988}
15989
bncd16676a2016-07-20 16:23:0115990TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2315991 const std::string https_url = "https://www.example.org:8080/";
15992 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0415993
15994 // SPDY GET for HTTPS URL
Ryan Hamilton0239aac2018-05-19 00:03:1315995 spdy::SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4915996 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0415997
15998 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4115999 CreateMockWrite(req1, 0),
[email protected]8450d722012-07-02 19:14:0416000 };
16001
Raul Tambre94493c652019-03-11 17:18:3516002 spdy::SpdySerializedFrame resp1(
16003 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316004 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
bncdf80d44fd2016-07-15 20:27:4116005 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
mmenkee24011922015-12-17 22:12:5916006 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)};
[email protected]8450d722012-07-02 19:14:0416007
Ryan Sleevib8d7ea02018-05-07 20:01:0116008 SequencedSocketData data1(reads1, writes1);
[email protected]8450d722012-07-02 19:14:0416009 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5716010 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0416011
16012 // HTTP GET for the HTTP URL
16013 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1316014 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3416015 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2316016 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3416017 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0416018 };
16019
16020 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1316021 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
16022 MockRead(ASYNC, 2, "hello"),
16023 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0416024 };
16025
Ryan Sleevib8d7ea02018-05-07 20:01:0116026 SequencedSocketData data2(reads2, writes2);
[email protected]8450d722012-07-02 19:14:0416027
[email protected]8450d722012-07-02 19:14:0416028 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616029 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0716030 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16031 session_deps_.socket_factory->AddSocketDataProvider(&data1);
16032 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0416033
danakj1fd259a02016-04-16 03:17:0916034 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0416035
16036 // Start the first transaction to set up the SpdySession
16037 HttpRequestInfo request1;
16038 request1.method = "GET";
16039 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0416040 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016041 request1.traffic_annotation =
16042 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016043 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0416044 TestCompletionCallback callback1;
16045 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016046 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5516047 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0416048
robpercival214763f2016-07-01 23:27:0116049 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0416050 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
16051
16052 // Now, start the HTTP request
16053 HttpRequestInfo request2;
16054 request2.method = "GET";
16055 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0416056 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016057 request2.traffic_annotation =
16058 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016059 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0416060 TestCompletionCallback callback2;
16061 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016062 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5516063 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0416064
robpercival214763f2016-07-01 23:27:0116065 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0416066 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
16067}
16068
bnc5452e2a2015-05-08 16:27:4216069// Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
16070// with the alternative server. That connection should not be used.
bncd16676a2016-07-20 16:23:0116071TEST_F(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
bnc8bef8da22016-05-30 01:28:2516072 url::SchemeHostPort server("https", "www.example.org", 443);
16073 HostPortPair alternative("www.example.org", 444);
bnc5452e2a2015-05-08 16:27:4216074
bnc8bef8da22016-05-30 01:28:2516075 // Negotiate HTTP/1.1 with alternative.
bnc5452e2a2015-05-08 16:27:4216076 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616077 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4216078 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16079
16080 // No data should be read from the alternative, because HTTP/1.1 is
16081 // negotiated.
16082 StaticSocketDataProvider data;
16083 session_deps_.socket_factory->AddSocketDataProvider(&data);
16084
16085 // This test documents that an alternate Job should not be used if HTTP/1.1 is
zhongyi3d4a55e72016-04-22 20:36:4616086 // negotiated. In order to test this, a failed connection to the server is
bnc5452e2a2015-05-08 16:27:4216087 // mocked. This way the request relies on the alternate Job.
16088 StaticSocketDataProvider data_refused;
16089 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
16090 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
16091
zhongyi3d4a55e72016-04-22 20:36:4616092 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0916093 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4016094 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4216095 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2116096 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1216097 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2116098 http_server_properties->SetHttp2AlternativeService(
16099 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4216100
bnc5452e2a2015-05-08 16:27:4216101 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4616102 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4216103 request.method = "GET";
bnc8bef8da22016-05-30 01:28:2516104 request.url = GURL("https://www.example.org:443");
Ramin Halavatib5e433e2018-02-07 07:41:1016105 request.traffic_annotation =
16106 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4216107 TestCompletionCallback callback;
16108
16109 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
bnc94c92842016-09-21 15:22:5216110 // negotiated, the alternate Job should fail with ERR_ALPN_NEGOTIATION_FAILED.
tfarina42834112016-09-22 13:38:2016111 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc94c92842016-09-21 15:22:5216112 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_ALPN_NEGOTIATION_FAILED));
bnc5452e2a2015-05-08 16:27:4216113}
16114
bnc40448a532015-05-11 19:13:1416115// A request to a server with an alternative service fires two Jobs: one to the
zhongyi3d4a55e72016-04-22 20:36:4616116// server, and an alternate one to the alternative server. If the former
bnc40448a532015-05-11 19:13:1416117// succeeds, the request should succeed, even if the latter fails because
16118// HTTP/1.1 is negotiated which is insufficient for alternative service.
bncd16676a2016-07-20 16:23:0116119TEST_F(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
bnc8bef8da22016-05-30 01:28:2516120 url::SchemeHostPort server("https", "www.example.org", 443);
16121 HostPortPair alternative("www.example.org", 444);
bnc40448a532015-05-11 19:13:1416122
16123 // Negotiate HTTP/1.1 with alternative.
16124 SSLSocketDataProvider alternative_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616125 alternative_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1416126 session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
16127
16128 // No data should be read from the alternative, because HTTP/1.1 is
16129 // negotiated.
16130 StaticSocketDataProvider data;
16131 session_deps_.socket_factory->AddSocketDataProvider(&data);
16132
zhongyi3d4a55e72016-04-22 20:36:4616133 // Negotiate HTTP/1.1 with server.
bnc40448a532015-05-11 19:13:1416134 SSLSocketDataProvider origin_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616135 origin_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1416136 session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
16137
16138 MockWrite http_writes[] = {
bnc8bef8da22016-05-30 01:28:2516139 MockWrite("GET / HTTP/1.1\r\n"
16140 "Host: www.example.org\r\n"
16141 "Connection: keep-alive\r\n\r\n"),
16142 MockWrite("GET /second HTTP/1.1\r\n"
16143 "Host: www.example.org\r\n"
16144 "Connection: keep-alive\r\n\r\n"),
bnc40448a532015-05-11 19:13:1416145 };
16146
16147 MockRead http_reads[] = {
16148 MockRead("HTTP/1.1 200 OK\r\n"),
16149 MockRead("Content-Type: text/html\r\n"),
16150 MockRead("Content-Length: 6\r\n\r\n"),
16151 MockRead("foobar"),
16152 MockRead("HTTP/1.1 200 OK\r\n"),
16153 MockRead("Content-Type: text/html\r\n"),
16154 MockRead("Content-Length: 7\r\n\r\n"),
16155 MockRead("another"),
16156 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116157 StaticSocketDataProvider http_data(http_reads, http_writes);
bnc40448a532015-05-11 19:13:1416158 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16159
zhongyi3d4a55e72016-04-22 20:36:4616160 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0916161 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4016162 HttpServerProperties* http_server_properties =
bnc40448a532015-05-11 19:13:1416163 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2116164 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1216165 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2116166 http_server_properties->SetHttp2AlternativeService(
16167 server, alternative_service, expiration);
bnc40448a532015-05-11 19:13:1416168
16169 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
16170 HttpRequestInfo request1;
16171 request1.method = "GET";
bnc8bef8da22016-05-30 01:28:2516172 request1.url = GURL("https://www.example.org:443");
bnc40448a532015-05-11 19:13:1416173 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016174 request1.traffic_annotation =
16175 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc40448a532015-05-11 19:13:1416176 TestCompletionCallback callback1;
16177
tfarina42834112016-09-22 13:38:2016178 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1416179 rv = callback1.GetResult(rv);
robpercival214763f2016-07-01 23:27:0116180 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1416181
16182 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5216183 ASSERT_TRUE(response1);
16184 ASSERT_TRUE(response1->headers);
bnc40448a532015-05-11 19:13:1416185 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
16186
16187 std::string response_data1;
robpercival214763f2016-07-01 23:27:0116188 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc40448a532015-05-11 19:13:1416189 EXPECT_EQ("foobar", response_data1);
16190
16191 // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
16192 // for alternative service.
16193 EXPECT_TRUE(
16194 http_server_properties->IsAlternativeServiceBroken(alternative_service));
16195
zhongyi3d4a55e72016-04-22 20:36:4616196 // Since |alternative_service| is broken, a second transaction to server
bnc40448a532015-05-11 19:13:1416197 // should not start an alternate Job. It should pool to existing connection
zhongyi3d4a55e72016-04-22 20:36:4616198 // to server.
bnc40448a532015-05-11 19:13:1416199 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
16200 HttpRequestInfo request2;
16201 request2.method = "GET";
bnc8bef8da22016-05-30 01:28:2516202 request2.url = GURL("https://www.example.org:443/second");
bnc40448a532015-05-11 19:13:1416203 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016204 request2.traffic_annotation =
16205 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc40448a532015-05-11 19:13:1416206 TestCompletionCallback callback2;
16207
tfarina42834112016-09-22 13:38:2016208 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1416209 rv = callback2.GetResult(rv);
robpercival214763f2016-07-01 23:27:0116210 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1416211
16212 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5216213 ASSERT_TRUE(response2);
16214 ASSERT_TRUE(response2->headers);
bnc40448a532015-05-11 19:13:1416215 EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
16216
16217 std::string response_data2;
robpercival214763f2016-07-01 23:27:0116218 ASSERT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
bnc40448a532015-05-11 19:13:1416219 EXPECT_EQ("another", response_data2);
16220}
16221
bnc5452e2a2015-05-08 16:27:4216222// Alternative service requires HTTP/2 (or SPDY), but there is already a
16223// HTTP/1.1 socket open to the alternative server. That socket should not be
16224// used.
bncd16676a2016-07-20 16:23:0116225TEST_F(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
zhongyi3d4a55e72016-04-22 20:36:4616226 url::SchemeHostPort server("https", "origin.example.org", 443);
bnc5452e2a2015-05-08 16:27:4216227 HostPortPair alternative("alternative.example.org", 443);
16228 std::string origin_url = "https://origin.example.org:443";
16229 std::string alternative_url = "https://alternative.example.org:443";
16230
16231 // Negotiate HTTP/1.1 with alternative.example.org.
16232 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616233 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4216234 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16235
16236 // HTTP/1.1 data for |request1| and |request2|.
16237 MockWrite http_writes[] = {
16238 MockWrite(
16239 "GET / HTTP/1.1\r\n"
16240 "Host: alternative.example.org\r\n"
16241 "Connection: keep-alive\r\n\r\n"),
16242 MockWrite(
16243 "GET / HTTP/1.1\r\n"
16244 "Host: alternative.example.org\r\n"
16245 "Connection: keep-alive\r\n\r\n"),
16246 };
16247
16248 MockRead http_reads[] = {
16249 MockRead(
16250 "HTTP/1.1 200 OK\r\n"
16251 "Content-Type: text/html; charset=iso-8859-1\r\n"
16252 "Content-Length: 40\r\n\r\n"
16253 "first HTTP/1.1 response from alternative"),
16254 MockRead(
16255 "HTTP/1.1 200 OK\r\n"
16256 "Content-Type: text/html; charset=iso-8859-1\r\n"
16257 "Content-Length: 41\r\n\r\n"
16258 "second HTTP/1.1 response from alternative"),
16259 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116260 StaticSocketDataProvider http_data(http_reads, http_writes);
bnc5452e2a2015-05-08 16:27:4216261 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16262
16263 // This test documents that an alternate Job should not pool to an already
16264 // existing HTTP/1.1 connection. In order to test this, a failed connection
zhongyi3d4a55e72016-04-22 20:36:4616265 // to the server is mocked. This way |request2| relies on the alternate Job.
bnc5452e2a2015-05-08 16:27:4216266 StaticSocketDataProvider data_refused;
16267 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
16268 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
16269
zhongyi3d4a55e72016-04-22 20:36:4616270 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0916271 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4016272 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4216273 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2116274 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1216275 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2116276 http_server_properties->SetHttp2AlternativeService(
16277 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4216278
16279 // First transaction to alternative to open an HTTP/1.1 socket.
bnc5452e2a2015-05-08 16:27:4216280 HttpRequestInfo request1;
krasinc06a72a2016-12-21 03:42:4616281 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4216282 request1.method = "GET";
16283 request1.url = GURL(alternative_url);
16284 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016285 request1.traffic_annotation =
16286 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4216287 TestCompletionCallback callback1;
16288
tfarina42834112016-09-22 13:38:2016289 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116290 EXPECT_THAT(callback1.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1616291 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4216292 ASSERT_TRUE(response1);
wezca1070932016-05-26 20:30:5216293 ASSERT_TRUE(response1->headers);
bnc5452e2a2015-05-08 16:27:4216294 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5216295 EXPECT_TRUE(response1->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4216296 EXPECT_FALSE(response1->was_fetched_via_spdy);
16297 std::string response_data1;
bnc691fda62016-08-12 00:43:1616298 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc5452e2a2015-05-08 16:27:4216299 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
16300
16301 // Request for origin.example.org, which has an alternative service. This
16302 // will start two Jobs: the alternative looks for connections to pool to,
16303 // finds one which is HTTP/1.1, and should ignore it, and should not try to
zhongyi3d4a55e72016-04-22 20:36:4616304 // open other connections to alternative server. The Job to server fails, so
bnc5452e2a2015-05-08 16:27:4216305 // this request fails.
bnc5452e2a2015-05-08 16:27:4216306 HttpRequestInfo request2;
krasinc06a72a2016-12-21 03:42:4616307 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4216308 request2.method = "GET";
16309 request2.url = GURL(origin_url);
16310 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016311 request2.traffic_annotation =
16312 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4216313 TestCompletionCallback callback2;
16314
tfarina42834112016-09-22 13:38:2016315 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116316 EXPECT_THAT(callback2.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc5452e2a2015-05-08 16:27:4216317
16318 // Another transaction to alternative. This is to test that the HTTP/1.1
16319 // socket is still open and in the pool.
bnc5452e2a2015-05-08 16:27:4216320 HttpRequestInfo request3;
krasinc06a72a2016-12-21 03:42:4616321 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4216322 request3.method = "GET";
16323 request3.url = GURL(alternative_url);
16324 request3.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016325 request3.traffic_annotation =
16326 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4216327 TestCompletionCallback callback3;
16328
tfarina42834112016-09-22 13:38:2016329 rv = trans3.Start(&request3, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116330 EXPECT_THAT(callback3.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1616331 const HttpResponseInfo* response3 = trans3.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4216332 ASSERT_TRUE(response3);
wezca1070932016-05-26 20:30:5216333 ASSERT_TRUE(response3->headers);
bnc5452e2a2015-05-08 16:27:4216334 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5216335 EXPECT_TRUE(response3->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4216336 EXPECT_FALSE(response3->was_fetched_via_spdy);
16337 std::string response_data3;
bnc691fda62016-08-12 00:43:1616338 ASSERT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
bnc5452e2a2015-05-08 16:27:4216339 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
16340}
16341
bncd16676a2016-07-20 16:23:0116342TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2316343 const std::string https_url = "https://www.example.org:8080/";
16344 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0416345
rdsmithebb50aa2015-11-12 03:44:3816346 // Separate SPDY util instance for naked and wrapped requests.
bncd16676a2016-07-20 16:23:0116347 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:3816348
[email protected]8450d722012-07-02 19:14:0416349 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2316350 const HostPortPair host_port_pair("www.example.org", 8080);
Ryan Hamilton0239aac2018-05-19 00:03:1316351 spdy::SpdySerializedFrame connect(
Raul Tambre94493c652019-03-11 17:18:3516352 spdy_util_.ConstructSpdyConnect(nullptr, 0, 1, LOWEST, host_port_pair));
Ryan Hamilton0239aac2018-05-19 00:03:1316353 spdy::SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4916354 spdy_util_wrapped.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1316355 spdy::SpdySerializedFrame wrapped_req1(
[email protected]23e482282013-06-14 16:08:0216356 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3916357
16358 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
Ryan Hamilton0239aac2018-05-19 00:03:1316359 spdy::SpdyHeaderBlock req2_block;
16360 req2_block[spdy::kHttp2MethodHeader] = "GET";
16361 req2_block[spdy::kHttp2AuthorityHeader] = "www.example.org:8080";
16362 req2_block[spdy::kHttp2SchemeHeader] = "http";
16363 req2_block[spdy::kHttp2PathHeader] = "/";
16364 spdy::SpdySerializedFrame req2(
bnc42331402016-07-25 13:36:1516365 spdy_util_.ConstructSpdyHeaders(3, std::move(req2_block), MEDIUM, true));
[email protected]8450d722012-07-02 19:14:0416366
16367 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4116368 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_req1, 2),
16369 CreateMockWrite(req2, 6),
[email protected]8450d722012-07-02 19:14:0416370 };
16371
Ryan Hamilton0239aac2018-05-19 00:03:1316372 spdy::SpdySerializedFrame conn_resp(
bnc42331402016-07-25 13:36:1516373 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316374 spdy::SpdySerializedFrame resp1(
bnc42331402016-07-25 13:36:1516375 spdy_util_wrapped.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316376 spdy::SpdySerializedFrame body1(
16377 spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
16378 spdy::SpdySerializedFrame wrapped_resp1(
rdsmithebb50aa2015-11-12 03:44:3816379 spdy_util_wrapped.ConstructWrappedSpdyFrame(resp1, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316380 spdy::SpdySerializedFrame wrapped_body1(
rdsmithebb50aa2015-11-12 03:44:3816381 spdy_util_wrapped.ConstructWrappedSpdyFrame(body1, 1));
Raul Tambre94493c652019-03-11 17:18:3516382 spdy::SpdySerializedFrame resp2(
16383 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
Ryan Hamilton0239aac2018-05-19 00:03:1316384 spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
mmenke666a6fea2015-12-19 04:16:3316385 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4116386 CreateMockRead(conn_resp, 1),
mmenke666a6fea2015-12-19 04:16:3316387 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:4116388 CreateMockRead(wrapped_resp1, 4),
16389 CreateMockRead(wrapped_body1, 5),
mmenke666a6fea2015-12-19 04:16:3316390 MockRead(ASYNC, ERR_IO_PENDING, 7),
bncdf80d44fd2016-07-15 20:27:4116391 CreateMockRead(resp2, 8),
16392 CreateMockRead(body2, 9),
mmenke666a6fea2015-12-19 04:16:3316393 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 10),
16394 };
[email protected]8450d722012-07-02 19:14:0416395
Ryan Sleevib8d7ea02018-05-07 20:01:0116396 SequencedSocketData data1(reads1, writes1);
[email protected]8450d722012-07-02 19:14:0416397 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5716398 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0416399
Lily Houghton8c2f97d2018-01-22 05:06:5916400 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4916401 ProxyResolutionService::CreateFixedFromPacResult(
16402 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5116403 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0716404 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0416405 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3616406 ssl1.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3316407 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0416408 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3616409 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3316410 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
16411 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0416412
danakj1fd259a02016-04-16 03:17:0916413 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]8450d722012-07-02 19:14:0416414
16415 // Start the first transaction to set up the SpdySession
16416 HttpRequestInfo request1;
16417 request1.method = "GET";
16418 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0416419 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016420 request1.traffic_annotation =
16421 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016422 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0416423 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:2016424 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0416425
mmenke666a6fea2015-12-19 04:16:3316426 // This pause is a hack to avoid running into https://crbug.com/497228.
16427 data1.RunUntilPaused();
16428 base::RunLoop().RunUntilIdle();
16429 data1.Resume();
robpercival214763f2016-07-01 23:27:0116430 EXPECT_THAT(callback1.GetResult(rv), IsOk());
[email protected]8450d722012-07-02 19:14:0416431 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
16432
[email protected]f6c63db52013-02-02 00:35:2216433 LoadTimingInfo load_timing_info1;
16434 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
16435 TestLoadTimingNotReusedWithPac(load_timing_info1,
16436 CONNECT_TIMING_HAS_SSL_TIMES);
16437
mmenke666a6fea2015-12-19 04:16:3316438 // Now, start the HTTP request.
[email protected]8450d722012-07-02 19:14:0416439 HttpRequestInfo request2;
16440 request2.method = "GET";
16441 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0416442 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016443 request2.traffic_annotation =
16444 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016445 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0416446 TestCompletionCallback callback2;
tfarina42834112016-09-22 13:38:2016447 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0416448
mmenke666a6fea2015-12-19 04:16:3316449 // This pause is a hack to avoid running into https://crbug.com/497228.
16450 data1.RunUntilPaused();
16451 base::RunLoop().RunUntilIdle();
16452 data1.Resume();
robpercival214763f2016-07-01 23:27:0116453 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenke666a6fea2015-12-19 04:16:3316454
[email protected]8450d722012-07-02 19:14:0416455 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2216456
16457 LoadTimingInfo load_timing_info2;
16458 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
16459 // The established SPDY sessions is considered reused by the HTTP request.
16460 TestLoadTimingReusedWithPac(load_timing_info2);
16461 // HTTP requests over a SPDY session should have a different connection
16462 // socket_log_id than requests over a tunnel.
16463 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0416464}
16465
[email protected]2d88e7d2012-07-19 17:55:1716466// Test that in the case where we have a SPDY session to a SPDY proxy
16467// that we do not pool other origins that resolve to the same IP when
16468// the certificate does not match the new origin.
16469// http://crbug.com/134690
bncd16676a2016-07-20 16:23:0116470TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2316471 const std::string url1 = "http://www.example.org/";
16472 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1716473 const std::string ip_addr = "1.2.3.4";
16474
rdsmithebb50aa2015-11-12 03:44:3816475 // Second SpdyTestUtil instance for the second socket.
bncd16676a2016-07-20 16:23:0116476 SpdyTestUtil spdy_util_secure;
rdsmithebb50aa2015-11-12 03:44:3816477
[email protected]2d88e7d2012-07-19 17:55:1716478 // SPDY GET for HTTP URL (through SPDY proxy)
Ryan Hamilton0239aac2018-05-19 00:03:1316479 spdy::SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:2316480 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
Ryan Hamilton0239aac2018-05-19 00:03:1316481 spdy::SpdySerializedFrame req1(
bnc42331402016-07-25 13:36:1516482 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
[email protected]2d88e7d2012-07-19 17:55:1716483
16484 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4116485 CreateMockWrite(req1, 0),
[email protected]2d88e7d2012-07-19 17:55:1716486 };
16487
Raul Tambre94493c652019-03-11 17:18:3516488 spdy::SpdySerializedFrame resp1(
16489 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316490 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1716491 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4116492 MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(resp1, 2),
16493 CreateMockRead(body1, 3), MockRead(ASYNC, OK, 4), // EOF
[email protected]2d88e7d2012-07-19 17:55:1716494 };
16495
Ryan Sleevib8d7ea02018-05-07 20:01:0116496 SequencedSocketData data1(reads1, writes1);
martijnfe9636e2016-02-06 14:33:3216497 IPAddress ip;
martijn654c8c42016-02-10 22:10:5916498 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
[email protected]2d88e7d2012-07-19 17:55:1716499 IPEndPoint peer_addr = IPEndPoint(ip, 443);
16500 MockConnect connect_data1(ASYNC, OK, peer_addr);
mmenke666a6fea2015-12-19 04:16:3316501 data1.set_connect_data(connect_data1);
[email protected]2d88e7d2012-07-19 17:55:1716502
16503 // SPDY GET for HTTPS URL (direct)
Ryan Hamilton0239aac2018-05-19 00:03:1316504 spdy::SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4916505 spdy_util_secure.ConstructSpdyGet(url2.c_str(), 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1716506
16507 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4116508 CreateMockWrite(req2, 0),
[email protected]2d88e7d2012-07-19 17:55:1716509 };
16510
Ryan Hamilton0239aac2018-05-19 00:03:1316511 spdy::SpdySerializedFrame resp2(
Raul Tambre94493c652019-03-11 17:18:3516512 spdy_util_secure.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316513 spdy::SpdySerializedFrame body2(
16514 spdy_util_secure.ConstructSpdyDataFrame(1, true));
bncdf80d44fd2016-07-15 20:27:4116515 MockRead reads2[] = {CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
mmenke666a6fea2015-12-19 04:16:3316516 MockRead(ASYNC, OK, 3)};
[email protected]2d88e7d2012-07-19 17:55:1716517
Ryan Sleevib8d7ea02018-05-07 20:01:0116518 SequencedSocketData data2(reads2, writes2);
[email protected]2d88e7d2012-07-19 17:55:1716519 MockConnect connect_data2(ASYNC, OK);
mmenke666a6fea2015-12-19 04:16:3316520 data2.set_connect_data(connect_data2);
[email protected]2d88e7d2012-07-19 17:55:1716521
16522 // Set up a proxy config that sends HTTP requests to a proxy, and
16523 // all others direct.
16524 ProxyConfig proxy_config;
16525 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
Ramin Halavatica8d5252018-03-12 05:33:4916526 session_deps_.proxy_resolution_service =
16527 std::make_unique<ProxyResolutionService>(
16528 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
16529 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
16530 nullptr, nullptr);
[email protected]2d88e7d2012-07-19 17:55:1716531
bncce36dca22015-04-21 22:11:2316532 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3616533 ssl1.next_proto = kProtoHTTP2;
[email protected]2d88e7d2012-07-19 17:55:1716534 // Load a valid cert. Note, that this does not need to
16535 // be valid for proxy because the MockSSLClientSocket does
16536 // not actually verify it. But SpdySession will use this
16537 // to see if it is valid for the new origin
Ryan Sleevi4f832092017-11-21 23:25:4916538 ssl1.ssl_info.cert =
16539 ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
16540 ASSERT_TRUE(ssl1.ssl_info.cert);
mmenke666a6fea2015-12-19 04:16:3316541 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
16542 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d88e7d2012-07-19 17:55:1716543
16544 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3616545 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3316546 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
16547 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d88e7d2012-07-19 17:55:1716548
Jeremy Roman0579ed62017-08-29 15:56:1916549 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
bncce36dca22015-04-21 22:11:2316550 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0716551 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1716552
danakj1fd259a02016-04-16 03:17:0916553 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]2d88e7d2012-07-19 17:55:1716554
16555 // Start the first transaction to set up the SpdySession
16556 HttpRequestInfo request1;
16557 request1.method = "GET";
16558 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1716559 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016560 request1.traffic_annotation =
16561 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016562 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1716563 TestCompletionCallback callback1;
16564 ASSERT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016565 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
mmenke666a6fea2015-12-19 04:16:3316566 // This pause is a hack to avoid running into https://crbug.com/497228.
16567 data1.RunUntilPaused();
16568 base::RunLoop().RunUntilIdle();
16569 data1.Resume();
[email protected]2d88e7d2012-07-19 17:55:1716570
robpercival214763f2016-07-01 23:27:0116571 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1716572 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
16573
16574 // Now, start the HTTP request
16575 HttpRequestInfo request2;
16576 request2.method = "GET";
16577 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1716578 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016579 request2.traffic_annotation =
16580 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016581 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1716582 TestCompletionCallback callback2;
16583 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016584 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5516585 base::RunLoop().RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1716586
16587 ASSERT_TRUE(callback2.have_result());
robpercival214763f2016-07-01 23:27:0116588 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1716589 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
16590}
16591
[email protected]85f97342013-04-17 06:12:2416592// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
16593// error) in SPDY session, removes the socket from pool and closes the SPDY
16594// session. Verify that new url's from the same HttpNetworkSession (and a new
16595// SpdySession) do work. http://crbug.com/224701
bncd16676a2016-07-20 16:23:0116596TEST_F(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2316597 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2416598
16599 MockRead reads1[] = {
16600 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
16601 };
16602
Ryan Sleevib8d7ea02018-05-07 20:01:0116603 SequencedSocketData data1(reads1, base::span<MockWrite>());
[email protected]85f97342013-04-17 06:12:2416604
Ryan Hamilton0239aac2018-05-19 00:03:1316605 spdy::SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4916606 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2416607 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4116608 CreateMockWrite(req2, 0),
[email protected]85f97342013-04-17 06:12:2416609 };
16610
Raul Tambre94493c652019-03-11 17:18:3516611 spdy::SpdySerializedFrame resp2(
16612 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316613 spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]85f97342013-04-17 06:12:2416614 MockRead reads2[] = {
bncdf80d44fd2016-07-15 20:27:4116615 CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
16616 MockRead(ASYNC, OK, 3) // EOF
[email protected]85f97342013-04-17 06:12:2416617 };
16618
Ryan Sleevib8d7ea02018-05-07 20:01:0116619 SequencedSocketData data2(reads2, writes2);
[email protected]85f97342013-04-17 06:12:2416620
[email protected]85f97342013-04-17 06:12:2416621 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616622 ssl1.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5016623 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
16624 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]85f97342013-04-17 06:12:2416625
16626 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616627 ssl2.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5016628 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
16629 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]85f97342013-04-17 06:12:2416630
danakj1fd259a02016-04-16 03:17:0916631 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:5016632 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]85f97342013-04-17 06:12:2416633
16634 // Start the first transaction to set up the SpdySession and verify that
16635 // connection was closed.
16636 HttpRequestInfo request1;
16637 request1.method = "GET";
16638 request1.url = GURL(https_url);
16639 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016640 request1.traffic_annotation =
16641 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016642 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2416643 TestCompletionCallback callback1;
16644 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016645 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0116646 EXPECT_THAT(callback1.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]85f97342013-04-17 06:12:2416647
16648 // Now, start the second request and make sure it succeeds.
16649 HttpRequestInfo request2;
16650 request2.method = "GET";
16651 request2.url = GURL(https_url);
16652 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016653 request2.traffic_annotation =
16654 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016655 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2416656 TestCompletionCallback callback2;
16657 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016658 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
[email protected]85f97342013-04-17 06:12:2416659
robpercival214763f2016-07-01 23:27:0116660 ASSERT_THAT(callback2.WaitForResult(), IsOk());
[email protected]85f97342013-04-17 06:12:2416661 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
16662}
16663
bncd16676a2016-07-20 16:23:0116664TEST_F(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]483fa202013-05-14 01:07:0316665 ClientSocketPoolManager::set_max_sockets_per_group(
16666 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16667 ClientSocketPoolManager::set_max_sockets_per_pool(
16668 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16669
16670 // Use two different hosts with different IPs so they don't get pooled.
16671 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
16672 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
danakj1fd259a02016-04-16 03:17:0916673 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]483fa202013-05-14 01:07:0316674
16675 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616676 ssl1.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0316677 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616678 ssl2.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0316679 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
16680 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
16681
Ryan Hamilton0239aac2018-05-19 00:03:1316682 spdy::SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4916683 spdy_util_.ConstructSpdyGet("https://www.a.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0316684 MockWrite spdy1_writes[] = {
bncdf80d44fd2016-07-15 20:27:4116685 CreateMockWrite(host1_req, 0),
[email protected]483fa202013-05-14 01:07:0316686 };
Ryan Hamilton0239aac2018-05-19 00:03:1316687 spdy::SpdySerializedFrame host1_resp(
Raul Tambre94493c652019-03-11 17:18:3516688 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316689 spdy::SpdySerializedFrame host1_resp_body(
bncdf80d44fd2016-07-15 20:27:4116690 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0316691 MockRead spdy1_reads[] = {
bncdf80d44fd2016-07-15 20:27:4116692 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
mmenkee24011922015-12-17 22:12:5916693 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0316694 };
16695
rdsmithebb50aa2015-11-12 03:44:3816696 // Use a separate test instance for the separate SpdySession that will be
16697 // created.
bncd16676a2016-07-20 16:23:0116698 SpdyTestUtil spdy_util_2;
Ryan Sleevib8d7ea02018-05-07 20:01:0116699 SequencedSocketData spdy1_data(spdy1_reads, spdy1_writes);
Bence Béky53a5aef2018-03-29 21:54:1216700 session_deps_.socket_factory->AddSocketDataProvider(&spdy1_data);
[email protected]483fa202013-05-14 01:07:0316701
Ryan Hamilton0239aac2018-05-19 00:03:1316702 spdy::SpdySerializedFrame host2_req(
bnc38dcd392016-02-09 23:19:4916703 spdy_util_2.ConstructSpdyGet("https://www.b.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0316704 MockWrite spdy2_writes[] = {
bncdf80d44fd2016-07-15 20:27:4116705 CreateMockWrite(host2_req, 0),
[email protected]483fa202013-05-14 01:07:0316706 };
Ryan Hamilton0239aac2018-05-19 00:03:1316707 spdy::SpdySerializedFrame host2_resp(
Raul Tambre94493c652019-03-11 17:18:3516708 spdy_util_2.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316709 spdy::SpdySerializedFrame host2_resp_body(
bncdf80d44fd2016-07-15 20:27:4116710 spdy_util_2.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0316711 MockRead spdy2_reads[] = {
bncdf80d44fd2016-07-15 20:27:4116712 CreateMockRead(host2_resp, 1), CreateMockRead(host2_resp_body, 2),
mmenkee24011922015-12-17 22:12:5916713 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0316714 };
16715
Ryan Sleevib8d7ea02018-05-07 20:01:0116716 SequencedSocketData spdy2_data(spdy2_reads, spdy2_writes);
Bence Béky53a5aef2018-03-29 21:54:1216717 session_deps_.socket_factory->AddSocketDataProvider(&spdy2_data);
[email protected]483fa202013-05-14 01:07:0316718
16719 MockWrite http_write[] = {
16720 MockWrite("GET / HTTP/1.1\r\n"
16721 "Host: www.a.com\r\n"
16722 "Connection: keep-alive\r\n\r\n"),
16723 };
16724
16725 MockRead http_read[] = {
16726 MockRead("HTTP/1.1 200 OK\r\n"),
16727 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
16728 MockRead("Content-Length: 6\r\n\r\n"),
16729 MockRead("hello!"),
16730 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116731 StaticSocketDataProvider http_data(http_read, http_write);
[email protected]483fa202013-05-14 01:07:0316732 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16733
16734 HostPortPair host_port_pair_a("www.a.com", 443);
Matt Menke2436b2f2018-12-11 18:07:1116735 SpdySessionKey spdy_session_key_a(
16736 host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
16737 SpdySessionKey::IsProxySession::kFalse, SocketTag());
[email protected]483fa202013-05-14 01:07:0316738 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616739 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0316740
16741 TestCompletionCallback callback;
16742 HttpRequestInfo request1;
16743 request1.method = "GET";
16744 request1.url = GURL("https://www.a.com/");
16745 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016746 request1.traffic_annotation =
16747 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5816748 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1916749 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0316750
tfarina42834112016-09-22 13:38:2016751 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116752 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16753 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0316754
16755 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5216756 ASSERT_TRUE(response);
16757 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0216758 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0316759 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5216760 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]483fa202013-05-14 01:07:0316761
16762 std::string response_data;
robpercival214763f2016-07-01 23:27:0116763 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0316764 EXPECT_EQ("hello!", response_data);
16765 trans.reset();
16766 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2616767 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0316768
16769 HostPortPair host_port_pair_b("www.b.com", 443);
Matt Menke2436b2f2018-12-11 18:07:1116770 SpdySessionKey spdy_session_key_b(
16771 host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
16772 SpdySessionKey::IsProxySession::kFalse, SocketTag());
[email protected]483fa202013-05-14 01:07:0316773 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616774 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0316775 HttpRequestInfo request2;
16776 request2.method = "GET";
16777 request2.url = GURL("https://www.b.com/");
16778 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016779 request2.traffic_annotation =
16780 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5816781 trans =
Jeremy Roman0579ed62017-08-29 15:56:1916782 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0316783
tfarina42834112016-09-22 13:38:2016784 rv = trans->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116785 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16786 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0316787
16788 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5216789 ASSERT_TRUE(response);
16790 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0216791 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0316792 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5216793 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0116794 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0316795 EXPECT_EQ("hello!", response_data);
16796 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616797 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0316798 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2616799 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0316800
16801 HostPortPair host_port_pair_a1("www.a.com", 80);
Matt Menke2436b2f2018-12-11 18:07:1116802 SpdySessionKey spdy_session_key_a1(
16803 host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
16804 SpdySessionKey::IsProxySession::kFalse, SocketTag());
[email protected]483fa202013-05-14 01:07:0316805 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616806 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0316807 HttpRequestInfo request3;
16808 request3.method = "GET";
16809 request3.url = GURL("http://www.a.com/");
16810 request3.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016811 request3.traffic_annotation =
16812 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5816813 trans =
Jeremy Roman0579ed62017-08-29 15:56:1916814 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0316815
tfarina42834112016-09-22 13:38:2016816 rv = trans->Start(&request3, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116817 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16818 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0316819
16820 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5216821 ASSERT_TRUE(response);
16822 ASSERT_TRUE(response->headers);
[email protected]483fa202013-05-14 01:07:0316823 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
16824 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5216825 EXPECT_FALSE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0116826 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0316827 EXPECT_EQ("hello!", response_data);
16828 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616829 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0316830 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616831 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0316832}
16833
bncd16676a2016-07-20 16:23:0116834TEST_F(HttpNetworkTransactionTest, HttpSyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0416835 HttpRequestInfo request;
16836 request.method = "GET";
bncce36dca22015-04-21 22:11:2316837 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016838 request.traffic_annotation =
16839 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416840
danakj1fd259a02016-04-16 03:17:0916841 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616842 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416843
ttuttled9dbc652015-09-29 20:00:5916844 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0416845 StaticSocketDataProvider data;
16846 data.set_connect_data(mock_connect);
16847 session_deps_.socket_factory->AddSocketDataProvider(&data);
16848
16849 TestCompletionCallback callback;
16850
tfarina42834112016-09-22 13:38:2016851 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116852 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416853
16854 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116855 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0416856
[email protected]79e1fd62013-06-20 06:50:0416857 // We don't care whether this succeeds or fails, but it shouldn't crash.
16858 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616859 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4716860
16861 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1616862 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4716863 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0116864 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5916865
16866 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1616867 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5916868 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0416869}
16870
bncd16676a2016-07-20 16:23:0116871TEST_F(HttpNetworkTransactionTest, HttpAsyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0416872 HttpRequestInfo request;
16873 request.method = "GET";
bncce36dca22015-04-21 22:11:2316874 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016875 request.traffic_annotation =
16876 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416877
danakj1fd259a02016-04-16 03:17:0916878 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616879 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416880
ttuttled9dbc652015-09-29 20:00:5916881 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0416882 StaticSocketDataProvider data;
16883 data.set_connect_data(mock_connect);
16884 session_deps_.socket_factory->AddSocketDataProvider(&data);
16885
16886 TestCompletionCallback callback;
16887
tfarina42834112016-09-22 13:38:2016888 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116889 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416890
16891 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116892 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0416893
[email protected]79e1fd62013-06-20 06:50:0416894 // We don't care whether this succeeds or fails, but it shouldn't crash.
16895 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616896 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4716897
16898 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1616899 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4716900 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0116901 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5916902
16903 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1616904 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5916905 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0416906}
16907
bncd16676a2016-07-20 16:23:0116908TEST_F(HttpNetworkTransactionTest, HttpSyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0416909 HttpRequestInfo request;
16910 request.method = "GET";
bncce36dca22015-04-21 22:11:2316911 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016912 request.traffic_annotation =
16913 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416914
danakj1fd259a02016-04-16 03:17:0916915 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616916 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416917
16918 MockWrite data_writes[] = {
16919 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16920 };
16921 MockRead data_reads[] = {
16922 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
16923 };
16924
Ryan Sleevib8d7ea02018-05-07 20:01:0116925 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0416926 session_deps_.socket_factory->AddSocketDataProvider(&data);
16927
16928 TestCompletionCallback callback;
16929
tfarina42834112016-09-22 13:38:2016930 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116931 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416932
16933 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116934 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416935
[email protected]79e1fd62013-06-20 06:50:0416936 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616937 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416938 EXPECT_TRUE(request_headers.HasHeader("Host"));
16939}
16940
bncd16676a2016-07-20 16:23:0116941TEST_F(HttpNetworkTransactionTest, HttpAsyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0416942 HttpRequestInfo request;
16943 request.method = "GET";
bncce36dca22015-04-21 22:11:2316944 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016945 request.traffic_annotation =
16946 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416947
danakj1fd259a02016-04-16 03:17:0916948 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616949 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416950
16951 MockWrite data_writes[] = {
16952 MockWrite(ASYNC, ERR_CONNECTION_RESET),
16953 };
16954 MockRead data_reads[] = {
16955 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
16956 };
16957
Ryan Sleevib8d7ea02018-05-07 20:01:0116958 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0416959 session_deps_.socket_factory->AddSocketDataProvider(&data);
16960
16961 TestCompletionCallback callback;
16962
tfarina42834112016-09-22 13:38:2016963 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116964 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416965
16966 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116967 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416968
[email protected]79e1fd62013-06-20 06:50:0416969 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616970 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416971 EXPECT_TRUE(request_headers.HasHeader("Host"));
16972}
16973
bncd16676a2016-07-20 16:23:0116974TEST_F(HttpNetworkTransactionTest, HttpSyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0416975 HttpRequestInfo request;
16976 request.method = "GET";
bncce36dca22015-04-21 22:11:2316977 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016978 request.traffic_annotation =
16979 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416980
danakj1fd259a02016-04-16 03:17:0916981 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616982 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416983
16984 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2316985 MockWrite(
16986 "GET / HTTP/1.1\r\n"
16987 "Host: www.example.org\r\n"
16988 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0416989 };
16990 MockRead data_reads[] = {
16991 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
16992 };
16993
Ryan Sleevib8d7ea02018-05-07 20:01:0116994 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0416995 session_deps_.socket_factory->AddSocketDataProvider(&data);
16996
16997 TestCompletionCallback callback;
16998
tfarina42834112016-09-22 13:38:2016999 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117000 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0417001
17002 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117003 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0417004
[email protected]79e1fd62013-06-20 06:50:0417005 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1617006 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0417007 EXPECT_TRUE(request_headers.HasHeader("Host"));
17008}
17009
bncd16676a2016-07-20 16:23:0117010TEST_F(HttpNetworkTransactionTest, HttpAsyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0417011 HttpRequestInfo request;
17012 request.method = "GET";
bncce36dca22015-04-21 22:11:2317013 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017014 request.traffic_annotation =
17015 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0417016
danakj1fd259a02016-04-16 03:17:0917017 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617018 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0417019
17020 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2317021 MockWrite(
17022 "GET / HTTP/1.1\r\n"
17023 "Host: www.example.org\r\n"
17024 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0417025 };
17026 MockRead data_reads[] = {
17027 MockRead(ASYNC, ERR_CONNECTION_RESET),
17028 };
17029
Ryan Sleevib8d7ea02018-05-07 20:01:0117030 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0417031 session_deps_.socket_factory->AddSocketDataProvider(&data);
17032
17033 TestCompletionCallback callback;
17034
tfarina42834112016-09-22 13:38:2017035 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117036 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0417037
17038 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117039 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0417040
[email protected]79e1fd62013-06-20 06:50:0417041 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1617042 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0417043 EXPECT_TRUE(request_headers.HasHeader("Host"));
17044}
17045
bncd16676a2016-07-20 16:23:0117046TEST_F(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
[email protected]79e1fd62013-06-20 06:50:0417047 HttpRequestInfo request;
17048 request.method = "GET";
bncce36dca22015-04-21 22:11:2317049 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0417050 request.extra_headers.SetHeader("X-Foo", "bar");
Ramin Halavatib5e433e2018-02-07 07:41:1017051 request.traffic_annotation =
17052 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0417053
danakj1fd259a02016-04-16 03:17:0917054 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617055 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0417056
17057 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2317058 MockWrite(
17059 "GET / HTTP/1.1\r\n"
17060 "Host: www.example.org\r\n"
17061 "Connection: keep-alive\r\n"
17062 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0417063 };
17064 MockRead data_reads[] = {
17065 MockRead("HTTP/1.1 200 OK\r\n"
17066 "Content-Length: 5\r\n\r\n"
17067 "hello"),
17068 MockRead(ASYNC, ERR_UNEXPECTED),
17069 };
17070
Ryan Sleevib8d7ea02018-05-07 20:01:0117071 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0417072 session_deps_.socket_factory->AddSocketDataProvider(&data);
17073
17074 TestCompletionCallback callback;
17075
tfarina42834112016-09-22 13:38:2017076 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117077 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0417078
17079 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117080 EXPECT_THAT(rv, IsOk());
[email protected]79e1fd62013-06-20 06:50:0417081
17082 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1617083 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0417084 std::string foo;
17085 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
17086 EXPECT_EQ("bar", foo);
17087}
17088
[email protected]043b68c82013-08-22 23:41:5217089// Tests that when a used socket is returned to the SSL socket pool, it's closed
17090// if the transport socket pool is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0117091TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
[email protected]043b68c82013-08-22 23:41:5217092 ClientSocketPoolManager::set_max_sockets_per_group(
17093 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
17094 ClientSocketPoolManager::set_max_sockets_per_pool(
17095 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
17096
17097 // Set up SSL request.
17098
17099 HttpRequestInfo ssl_request;
17100 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2317101 ssl_request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017102 ssl_request.traffic_annotation =
17103 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5217104
17105 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2317106 MockWrite(
17107 "GET / HTTP/1.1\r\n"
17108 "Host: www.example.org\r\n"
17109 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5217110 };
17111 MockRead ssl_reads[] = {
17112 MockRead("HTTP/1.1 200 OK\r\n"),
17113 MockRead("Content-Length: 11\r\n\r\n"),
17114 MockRead("hello world"),
17115 MockRead(SYNCHRONOUS, OK),
17116 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117117 StaticSocketDataProvider ssl_data(ssl_reads, ssl_writes);
[email protected]043b68c82013-08-22 23:41:5217118 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
17119
17120 SSLSocketDataProvider ssl(ASYNC, OK);
17121 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
17122
17123 // Set up HTTP request.
17124
17125 HttpRequestInfo http_request;
17126 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2317127 http_request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017128 http_request.traffic_annotation =
17129 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5217130
17131 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2317132 MockWrite(
17133 "GET / HTTP/1.1\r\n"
17134 "Host: www.example.org\r\n"
17135 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5217136 };
17137 MockRead http_reads[] = {
17138 MockRead("HTTP/1.1 200 OK\r\n"),
17139 MockRead("Content-Length: 7\r\n\r\n"),
17140 MockRead("falafel"),
17141 MockRead(SYNCHRONOUS, OK),
17142 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117143 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]043b68c82013-08-22 23:41:5217144 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
17145
danakj1fd259a02016-04-16 03:17:0917146 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5217147
17148 // Start the SSL request.
17149 TestCompletionCallback ssl_callback;
bnc691fda62016-08-12 00:43:1617150 HttpNetworkTransaction ssl_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2017151 ASSERT_EQ(ERR_IO_PENDING,
17152 ssl_trans.Start(&ssl_request, ssl_callback.callback(),
17153 NetLogWithSource()));
[email protected]043b68c82013-08-22 23:41:5217154
17155 // Start the HTTP request. Pool should stall.
17156 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1617157 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2017158 ASSERT_EQ(ERR_IO_PENDING,
17159 http_trans.Start(&http_request, http_callback.callback(),
17160 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4117161 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5217162
17163 // Wait for response from SSL request.
robpercival214763f2016-07-01 23:27:0117164 ASSERT_THAT(ssl_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5217165 std::string response_data;
bnc691fda62016-08-12 00:43:1617166 ASSERT_THAT(ReadTransaction(&ssl_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5217167 EXPECT_EQ("hello world", response_data);
17168
17169 // The SSL socket should automatically be closed, so the HTTP request can
17170 // start.
Matt Menke9d5e2c92019-02-05 01:42:2317171 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
dcheng48459ac22014-08-26 00:46:4117172 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5217173
17174 // The HTTP request can now complete.
robpercival214763f2016-07-01 23:27:0117175 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
bnc691fda62016-08-12 00:43:1617176 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5217177 EXPECT_EQ("falafel", response_data);
17178
dcheng48459ac22014-08-26 00:46:4117179 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5217180}
17181
17182// Tests that when a SSL connection is established but there's no corresponding
17183// request that needs it, the new socket is closed if the transport socket pool
17184// is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0117185TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
[email protected]043b68c82013-08-22 23:41:5217186 ClientSocketPoolManager::set_max_sockets_per_group(
17187 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
17188 ClientSocketPoolManager::set_max_sockets_per_pool(
17189 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
17190
17191 // Set up an ssl request.
17192
17193 HttpRequestInfo ssl_request;
17194 ssl_request.method = "GET";
17195 ssl_request.url = GURL("https://www.foopy.com/");
Ramin Halavatib5e433e2018-02-07 07:41:1017196 ssl_request.traffic_annotation =
17197 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5217198
17199 // No data will be sent on the SSL socket.
17200 StaticSocketDataProvider ssl_data;
17201 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
17202
17203 SSLSocketDataProvider ssl(ASYNC, OK);
17204 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
17205
17206 // Set up HTTP request.
17207
17208 HttpRequestInfo http_request;
17209 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2317210 http_request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017211 http_request.traffic_annotation =
17212 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5217213
17214 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2317215 MockWrite(
17216 "GET / HTTP/1.1\r\n"
17217 "Host: www.example.org\r\n"
17218 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5217219 };
17220 MockRead http_reads[] = {
17221 MockRead("HTTP/1.1 200 OK\r\n"),
17222 MockRead("Content-Length: 7\r\n\r\n"),
17223 MockRead("falafel"),
17224 MockRead(SYNCHRONOUS, OK),
17225 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117226 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]043b68c82013-08-22 23:41:5217227 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
17228
danakj1fd259a02016-04-16 03:17:0917229 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5217230
17231 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
17232 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2917233 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
nharper8cdb0fb2016-04-22 21:34:5917234 http_stream_factory->PreconnectStreams(1, ssl_request);
Matt Menke9d5e2c92019-02-05 01:42:2317235 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5217236
17237 // Start the HTTP request. Pool should stall.
17238 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1617239 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2017240 ASSERT_EQ(ERR_IO_PENDING,
17241 http_trans.Start(&http_request, http_callback.callback(),
17242 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4117243 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5217244
17245 // The SSL connection will automatically be closed once the connection is
17246 // established, to let the HTTP request start.
robpercival214763f2016-07-01 23:27:0117247 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5217248 std::string response_data;
bnc691fda62016-08-12 00:43:1617249 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5217250 EXPECT_EQ("falafel", response_data);
17251
dcheng48459ac22014-08-26 00:46:4117252 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5217253}
17254
bncd16676a2016-07-20 16:23:0117255TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0917256 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217257 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917258 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217259 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417260
17261 HttpRequestInfo request;
17262 request.method = "POST";
17263 request.url = GURL("http://www.foo.com/");
17264 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017265 request.traffic_annotation =
17266 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417267
danakj1fd259a02016-04-16 03:17:0917268 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617269 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417270 // Send headers successfully, but get an error while sending the body.
17271 MockWrite data_writes[] = {
17272 MockWrite("POST / HTTP/1.1\r\n"
17273 "Host: www.foo.com\r\n"
17274 "Connection: keep-alive\r\n"
17275 "Content-Length: 3\r\n\r\n"),
17276 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17277 };
17278
17279 MockRead data_reads[] = {
17280 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
17281 MockRead("hello world"),
17282 MockRead(SYNCHRONOUS, OK),
17283 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117284 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417285 session_deps_.socket_factory->AddSocketDataProvider(&data);
17286
17287 TestCompletionCallback callback;
17288
tfarina42834112016-09-22 13:38:2017289 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117290 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417291
17292 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117293 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417294
bnc691fda62016-08-12 00:43:1617295 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5217296 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5417297
wezca1070932016-05-26 20:30:5217298 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5417299 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
17300
17301 std::string response_data;
bnc691fda62016-08-12 00:43:1617302 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0117303 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417304 EXPECT_EQ("hello world", response_data);
17305}
17306
17307// This test makes sure the retry logic doesn't trigger when reading an error
17308// response from a server that rejected a POST with a CONNECTION_RESET.
bncd16676a2016-07-20 16:23:0117309TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5417310 PostReadsErrorResponseAfterResetOnReusedSocket) {
danakj1fd259a02016-04-16 03:17:0917311 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5417312 MockWrite data_writes[] = {
17313 MockWrite("GET / HTTP/1.1\r\n"
17314 "Host: www.foo.com\r\n"
17315 "Connection: keep-alive\r\n\r\n"),
17316 MockWrite("POST / HTTP/1.1\r\n"
17317 "Host: www.foo.com\r\n"
17318 "Connection: keep-alive\r\n"
17319 "Content-Length: 3\r\n\r\n"),
17320 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17321 };
17322
17323 MockRead data_reads[] = {
17324 MockRead("HTTP/1.1 200 Peachy\r\n"
17325 "Content-Length: 14\r\n\r\n"),
17326 MockRead("first response"),
17327 MockRead("HTTP/1.1 400 Not OK\r\n"
17328 "Content-Length: 15\r\n\r\n"),
17329 MockRead("second response"),
17330 MockRead(SYNCHRONOUS, OK),
17331 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117332 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417333 session_deps_.socket_factory->AddSocketDataProvider(&data);
17334
17335 TestCompletionCallback callback;
17336 HttpRequestInfo request1;
17337 request1.method = "GET";
17338 request1.url = GURL("http://www.foo.com/");
17339 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1017340 request1.traffic_annotation =
17341 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417342
bnc87dcefc2017-05-25 12:47:5817343 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:1917344 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2017345 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117346 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417347
17348 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117349 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417350
17351 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:5217352 ASSERT_TRUE(response1);
[email protected]02d74a02014-04-23 18:10:5417353
wezca1070932016-05-26 20:30:5217354 EXPECT_TRUE(response1->headers);
[email protected]02d74a02014-04-23 18:10:5417355 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
17356
17357 std::string response_data1;
17358 rv = ReadTransaction(trans1.get(), &response_data1);
robpercival214763f2016-07-01 23:27:0117359 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417360 EXPECT_EQ("first response", response_data1);
17361 // Delete the transaction to release the socket back into the socket pool.
17362 trans1.reset();
17363
danakj1fd259a02016-04-16 03:17:0917364 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217365 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917366 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217367 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417368
17369 HttpRequestInfo request2;
17370 request2.method = "POST";
17371 request2.url = GURL("http://www.foo.com/");
17372 request2.upload_data_stream = &upload_data_stream;
17373 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1017374 request2.traffic_annotation =
17375 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417376
bnc691fda62016-08-12 00:43:1617377 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2017378 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117379 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417380
17381 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117382 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417383
bnc691fda62016-08-12 00:43:1617384 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5217385 ASSERT_TRUE(response2);
[email protected]02d74a02014-04-23 18:10:5417386
wezca1070932016-05-26 20:30:5217387 EXPECT_TRUE(response2->headers);
[email protected]02d74a02014-04-23 18:10:5417388 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
17389
17390 std::string response_data2;
bnc691fda62016-08-12 00:43:1617391 rv = ReadTransaction(&trans2, &response_data2);
robpercival214763f2016-07-01 23:27:0117392 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417393 EXPECT_EQ("second response", response_data2);
17394}
17395
bncd16676a2016-07-20 16:23:0117396TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5417397 PostReadsErrorResponseAfterResetPartialBodySent) {
danakj1fd259a02016-04-16 03:17:0917398 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217399 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917400 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217401 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417402
17403 HttpRequestInfo request;
17404 request.method = "POST";
17405 request.url = GURL("http://www.foo.com/");
17406 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017407 request.traffic_annotation =
17408 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417409
danakj1fd259a02016-04-16 03:17:0917410 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617411 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417412 // Send headers successfully, but get an error while sending the body.
17413 MockWrite data_writes[] = {
17414 MockWrite("POST / HTTP/1.1\r\n"
17415 "Host: www.foo.com\r\n"
17416 "Connection: keep-alive\r\n"
17417 "Content-Length: 3\r\n\r\n"
17418 "fo"),
17419 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17420 };
17421
17422 MockRead data_reads[] = {
17423 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
17424 MockRead("hello world"),
17425 MockRead(SYNCHRONOUS, OK),
17426 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117427 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417428 session_deps_.socket_factory->AddSocketDataProvider(&data);
17429
17430 TestCompletionCallback callback;
17431
tfarina42834112016-09-22 13:38:2017432 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117433 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417434
17435 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117436 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417437
bnc691fda62016-08-12 00:43:1617438 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5217439 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5417440
wezca1070932016-05-26 20:30:5217441 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5417442 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
17443
17444 std::string response_data;
bnc691fda62016-08-12 00:43:1617445 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0117446 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417447 EXPECT_EQ("hello world", response_data);
17448}
17449
17450// This tests the more common case than the previous test, where headers and
17451// body are not merged into a single request.
bncd16676a2016-07-20 16:23:0117452TEST_F(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
mmenkecbc2b712014-10-09 20:29:0717453 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5417454
17455 HttpRequestInfo request;
17456 request.method = "POST";
17457 request.url = GURL("http://www.foo.com/");
17458 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017459 request.traffic_annotation =
17460 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417461
danakj1fd259a02016-04-16 03:17:0917462 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617463 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417464 // Send headers successfully, but get an error while sending the body.
17465 MockWrite data_writes[] = {
17466 MockWrite("POST / HTTP/1.1\r\n"
17467 "Host: www.foo.com\r\n"
17468 "Connection: keep-alive\r\n"
17469 "Transfer-Encoding: chunked\r\n\r\n"),
17470 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17471 };
17472
17473 MockRead data_reads[] = {
17474 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
17475 MockRead("hello world"),
17476 MockRead(SYNCHRONOUS, OK),
17477 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117478 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417479 session_deps_.socket_factory->AddSocketDataProvider(&data);
17480
17481 TestCompletionCallback callback;
17482
tfarina42834112016-09-22 13:38:2017483 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117484 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417485 // Make sure the headers are sent before adding a chunk. This ensures that
17486 // they can't be merged with the body in a single send. Not currently
17487 // necessary since a chunked body is never merged with headers, but this makes
17488 // the test more future proof.
17489 base::RunLoop().RunUntilIdle();
17490
mmenkecbc2b712014-10-09 20:29:0717491 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5417492
17493 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117494 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417495
bnc691fda62016-08-12 00:43:1617496 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5217497 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5417498
wezca1070932016-05-26 20:30:5217499 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5417500 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
17501
17502 std::string response_data;
bnc691fda62016-08-12 00:43:1617503 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0117504 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417505 EXPECT_EQ("hello world", response_data);
17506}
17507
bncd16676a2016-07-20 16:23:0117508TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0917509 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217510 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917511 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217512 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417513
17514 HttpRequestInfo request;
17515 request.method = "POST";
17516 request.url = GURL("http://www.foo.com/");
17517 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017518 request.traffic_annotation =
17519 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417520
danakj1fd259a02016-04-16 03:17:0917521 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617522 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417523
17524 MockWrite data_writes[] = {
17525 MockWrite("POST / HTTP/1.1\r\n"
17526 "Host: www.foo.com\r\n"
17527 "Connection: keep-alive\r\n"
17528 "Content-Length: 3\r\n\r\n"),
17529 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17530 };
17531
17532 MockRead data_reads[] = {
17533 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
17534 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
17535 MockRead("hello world"),
17536 MockRead(SYNCHRONOUS, OK),
17537 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117538 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417539 session_deps_.socket_factory->AddSocketDataProvider(&data);
17540
17541 TestCompletionCallback callback;
17542
tfarina42834112016-09-22 13:38:2017543 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117544 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417545
17546 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117547 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417548
bnc691fda62016-08-12 00:43:1617549 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5217550 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5417551
wezca1070932016-05-26 20:30:5217552 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5417553 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
17554
17555 std::string response_data;
bnc691fda62016-08-12 00:43:1617556 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0117557 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417558 EXPECT_EQ("hello world", response_data);
17559}
17560
bncd16676a2016-07-20 16:23:0117561TEST_F(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0917562 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217563 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917564 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217565 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417566
17567 HttpRequestInfo request;
17568 request.method = "POST";
17569 request.url = GURL("http://www.foo.com/");
17570 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017571 request.traffic_annotation =
17572 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417573
danakj1fd259a02016-04-16 03:17:0917574 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617575 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417576 // Send headers successfully, but get an error while sending the body.
17577 MockWrite data_writes[] = {
17578 MockWrite("POST / HTTP/1.1\r\n"
17579 "Host: www.foo.com\r\n"
17580 "Connection: keep-alive\r\n"
17581 "Content-Length: 3\r\n\r\n"),
17582 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17583 };
17584
17585 MockRead data_reads[] = {
17586 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
17587 MockRead("hello world"),
17588 MockRead(SYNCHRONOUS, OK),
17589 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117590 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417591 session_deps_.socket_factory->AddSocketDataProvider(&data);
17592
17593 TestCompletionCallback callback;
17594
tfarina42834112016-09-22 13:38:2017595 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117596 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417597
17598 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117599 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417600}
17601
bncd16676a2016-07-20 16:23:0117602TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5417603 PostIgnoresNonErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0917604 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217605 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917606 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217607 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417608
17609 HttpRequestInfo request;
17610 request.method = "POST";
17611 request.url = GURL("http://www.foo.com/");
17612 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017613 request.traffic_annotation =
17614 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417615
danakj1fd259a02016-04-16 03:17:0917616 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617617 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417618 // Send headers successfully, but get an error while sending the body.
17619 MockWrite data_writes[] = {
17620 MockWrite("POST / HTTP/1.1\r\n"
17621 "Host: www.foo.com\r\n"
17622 "Connection: keep-alive\r\n"
17623 "Content-Length: 3\r\n\r\n"),
17624 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17625 };
17626
17627 MockRead data_reads[] = {
17628 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
17629 MockRead("HTTP/1.0 302 Redirect\r\n"),
17630 MockRead("Location: http://somewhere-else.com/\r\n"),
17631 MockRead("Content-Length: 0\r\n\r\n"),
17632 MockRead(SYNCHRONOUS, OK),
17633 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117634 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417635 session_deps_.socket_factory->AddSocketDataProvider(&data);
17636
17637 TestCompletionCallback callback;
17638
tfarina42834112016-09-22 13:38:2017639 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117640 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417641
17642 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117643 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417644}
17645
bncd16676a2016-07-20 16:23:0117646TEST_F(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0917647 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217648 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917649 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217650 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417651
17652 HttpRequestInfo request;
17653 request.method = "POST";
17654 request.url = GURL("http://www.foo.com/");
17655 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017656 request.traffic_annotation =
17657 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417658
danakj1fd259a02016-04-16 03:17:0917659 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617660 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417661 // Send headers successfully, but get an error while sending the body.
17662 MockWrite data_writes[] = {
17663 MockWrite("POST / HTTP/1.1\r\n"
17664 "Host: www.foo.com\r\n"
17665 "Connection: keep-alive\r\n"
17666 "Content-Length: 3\r\n\r\n"),
17667 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17668 };
17669
17670 MockRead data_reads[] = {
17671 MockRead("HTTP 0.9 rocks!"),
17672 MockRead(SYNCHRONOUS, OK),
17673 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117674 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417675 session_deps_.socket_factory->AddSocketDataProvider(&data);
17676
17677 TestCompletionCallback callback;
17678
tfarina42834112016-09-22 13:38:2017679 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117680 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417681
17682 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117683 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417684}
17685
bncd16676a2016-07-20 16:23:0117686TEST_F(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
danakj1fd259a02016-04-16 03:17:0917687 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217688 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917689 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217690 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417691
17692 HttpRequestInfo request;
17693 request.method = "POST";
17694 request.url = GURL("http://www.foo.com/");
17695 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017696 request.traffic_annotation =
17697 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417698
danakj1fd259a02016-04-16 03:17:0917699 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617700 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417701 // Send headers successfully, but get an error while sending the body.
17702 MockWrite data_writes[] = {
17703 MockWrite("POST / HTTP/1.1\r\n"
17704 "Host: www.foo.com\r\n"
17705 "Connection: keep-alive\r\n"
17706 "Content-Length: 3\r\n\r\n"),
17707 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17708 };
17709
17710 MockRead data_reads[] = {
17711 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
17712 MockRead(SYNCHRONOUS, OK),
17713 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117714 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417715 session_deps_.socket_factory->AddSocketDataProvider(&data);
17716
17717 TestCompletionCallback callback;
17718
tfarina42834112016-09-22 13:38:2017719 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117720 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417721
17722 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117723 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417724}
17725
Bence Békydca6bd92018-01-30 13:43:0617726#if BUILDFLAG(ENABLE_WEBSOCKETS)
17727
17728namespace {
17729
17730void AddWebSocketHeaders(HttpRequestHeaders* headers) {
17731 headers->SetHeader("Connection", "Upgrade");
17732 headers->SetHeader("Upgrade", "websocket");
17733 headers->SetHeader("Origin", "http://www.example.org");
17734 headers->SetHeader("Sec-WebSocket-Version", "13");
Bence Békydca6bd92018-01-30 13:43:0617735}
17736
17737} // namespace
17738
17739TEST_F(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
Bence Béky2fcf4fa2018-04-06 20:06:0117740 for (bool secure : {true, false}) {
17741 MockWrite data_writes[] = {
17742 MockWrite("GET / HTTP/1.1\r\n"
17743 "Host: www.example.org\r\n"
17744 "Connection: Upgrade\r\n"
17745 "Upgrade: websocket\r\n"
17746 "Origin: http://www.example.org\r\n"
17747 "Sec-WebSocket-Version: 13\r\n"
17748 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
17749 "Sec-WebSocket-Extensions: permessage-deflate; "
17750 "client_max_window_bits\r\n\r\n")};
17751
17752 MockRead data_reads[] = {
17753 MockRead("HTTP/1.1 101 Switching Protocols\r\n"
17754 "Upgrade: websocket\r\n"
17755 "Connection: Upgrade\r\n"
17756 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
17757
Ryan Sleevib8d7ea02018-05-07 20:01:0117758 StaticSocketDataProvider data(data_reads, data_writes);
Bence Béky2fcf4fa2018-04-06 20:06:0117759 session_deps_.socket_factory->AddSocketDataProvider(&data);
17760 SSLSocketDataProvider ssl(ASYNC, OK);
17761 if (secure)
17762 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
Bence Békydca6bd92018-01-30 13:43:0617763
17764 HttpRequestInfo request;
17765 request.method = "GET";
Bence Béky2fcf4fa2018-04-06 20:06:0117766 request.url =
17767 GURL(secure ? "ws://www.example.org/" : "wss://www.example.org/");
17768 AddWebSocketHeaders(&request.extra_headers);
Ramin Halavatib5e433e2018-02-07 07:41:1017769 request.traffic_annotation =
17770 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Békydca6bd92018-01-30 13:43:0617771
Bence Béky2fcf4fa2018-04-06 20:06:0117772 TestWebSocketHandshakeStreamCreateHelper
17773 websocket_handshake_stream_create_helper;
Bence Béky8d1c6052018-02-07 12:48:1517774
Bence Béky2fcf4fa2018-04-06 20:06:0117775 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Bence Békydca6bd92018-01-30 13:43:0617776 HttpNetworkTransaction trans(LOW, session.get());
17777 trans.SetWebSocketHandshakeStreamCreateHelper(
Bence Béky2fcf4fa2018-04-06 20:06:0117778 &websocket_handshake_stream_create_helper);
Bence Békydca6bd92018-01-30 13:43:0617779
17780 TestCompletionCallback callback;
Bence Béky2fcf4fa2018-04-06 20:06:0117781 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17782 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Bence Békydca6bd92018-01-30 13:43:0617783
Bence Béky2fcf4fa2018-04-06 20:06:0117784 const HttpStreamRequest* stream_request = trans.stream_request_.get();
17785 ASSERT_TRUE(stream_request);
17786 EXPECT_EQ(&websocket_handshake_stream_create_helper,
17787 stream_request->websocket_handshake_stream_create_helper());
17788
17789 rv = callback.WaitForResult();
17790 EXPECT_THAT(rv, IsOk());
17791
17792 EXPECT_TRUE(data.AllReadDataConsumed());
17793 EXPECT_TRUE(data.AllWriteDataConsumed());
Bence Békydca6bd92018-01-30 13:43:0617794 }
17795}
17796
Adam Rice425cf122015-01-19 06:18:2417797// Verify that proxy headers are not sent to the destination server when
17798// establishing a tunnel for a secure WebSocket connection.
bncd16676a2016-07-20 16:23:0117799TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
Adam Rice425cf122015-01-19 06:18:2417800 HttpRequestInfo request;
17801 request.method = "GET";
bncce36dca22015-04-21 22:11:2317802 request.url = GURL("wss://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017803 request.traffic_annotation =
17804 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417805 AddWebSocketHeaders(&request.extra_headers);
17806
17807 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:5917808 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4917809 ProxyResolutionService::CreateFixedFromPacResult(
17810 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417811
danakj1fd259a02016-04-16 03:17:0917812 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2417813
17814 // Since a proxy is configured, try to establish a tunnel.
17815 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1717816 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
17817 "Host: www.example.org:443\r\n"
17818 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417819
17820 // After calling trans->RestartWithAuth(), this is the request we should
17821 // be issuing -- the final header line contains the credentials.
rsleevidb16bb02015-11-12 23:47:1717822 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
17823 "Host: www.example.org:443\r\n"
17824 "Proxy-Connection: keep-alive\r\n"
17825 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417826
rsleevidb16bb02015-11-12 23:47:1717827 MockWrite("GET / HTTP/1.1\r\n"
17828 "Host: www.example.org\r\n"
17829 "Connection: Upgrade\r\n"
17830 "Upgrade: websocket\r\n"
17831 "Origin: http://www.example.org\r\n"
17832 "Sec-WebSocket-Version: 13\r\n"
Bence Béky8d1c6052018-02-07 12:48:1517833 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
17834 "Sec-WebSocket-Extensions: permessage-deflate; "
17835 "client_max_window_bits\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417836
17837 // The proxy responds to the connect with a 407, using a persistent
17838 // connection.
17839 MockRead data_reads[] = {
17840 // No credentials.
Bence Béky8d1c6052018-02-07 12:48:1517841 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"
17842 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
17843 "Content-Length: 0\r\n"
17844 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417845
17846 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
17847
Bence Béky8d1c6052018-02-07 12:48:1517848 MockRead("HTTP/1.1 101 Switching Protocols\r\n"
17849 "Upgrade: websocket\r\n"
17850 "Connection: Upgrade\r\n"
17851 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417852
Ryan Sleevib8d7ea02018-05-07 20:01:0117853 StaticSocketDataProvider data(data_reads, data_writes);
Adam Rice425cf122015-01-19 06:18:2417854 session_deps_.socket_factory->AddSocketDataProvider(&data);
17855 SSLSocketDataProvider ssl(ASYNC, OK);
17856 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
17857
Bence Béky8d1c6052018-02-07 12:48:1517858 TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
17859
bnc87dcefc2017-05-25 12:47:5817860 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917861 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2417862 trans->SetWebSocketHandshakeStreamCreateHelper(
17863 &websocket_stream_create_helper);
17864
17865 {
17866 TestCompletionCallback callback;
17867
tfarina42834112016-09-22 13:38:2017868 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117869 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2417870
17871 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117872 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2417873 }
17874
17875 const HttpResponseInfo* response = trans->GetResponseInfo();
17876 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5217877 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2417878 EXPECT_EQ(407, response->headers->response_code());
17879
17880 {
17881 TestCompletionCallback callback;
17882
17883 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
17884 callback.callback());
robpercival214763f2016-07-01 23:27:0117885 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2417886
17887 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117888 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2417889 }
17890
17891 response = trans->GetResponseInfo();
17892 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5217893 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2417894
17895 EXPECT_EQ(101, response->headers->response_code());
17896
17897 trans.reset();
17898 session->CloseAllConnections();
17899}
17900
17901// Verify that proxy headers are not sent to the destination server when
17902// establishing a tunnel for an insecure WebSocket connection.
17903// This requires the authentication info to be injected into the auth cache
17904// due to crbug.com/395064
17905// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
bncd16676a2016-07-20 16:23:0117906TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
Adam Rice425cf122015-01-19 06:18:2417907 HttpRequestInfo request;
17908 request.method = "GET";
bncce36dca22015-04-21 22:11:2317909 request.url = GURL("ws://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017910 request.traffic_annotation =
17911 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417912 AddWebSocketHeaders(&request.extra_headers);
17913
17914 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:5917915 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4917916 ProxyResolutionService::CreateFixedFromPacResult(
17917 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417918
danakj1fd259a02016-04-16 03:17:0917919 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2417920
17921 MockWrite data_writes[] = {
17922 // Try to establish a tunnel for the WebSocket connection, with
17923 // credentials. Because WebSockets have a separate set of socket pools,
17924 // they cannot and will not use the same TCP/IP connection as the
17925 // preflight HTTP request.
Bence Béky8d1c6052018-02-07 12:48:1517926 MockWrite("CONNECT www.example.org:80 HTTP/1.1\r\n"
17927 "Host: www.example.org:80\r\n"
17928 "Proxy-Connection: keep-alive\r\n"
17929 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417930
Bence Béky8d1c6052018-02-07 12:48:1517931 MockWrite("GET / HTTP/1.1\r\n"
17932 "Host: www.example.org\r\n"
17933 "Connection: Upgrade\r\n"
17934 "Upgrade: websocket\r\n"
17935 "Origin: http://www.example.org\r\n"
17936 "Sec-WebSocket-Version: 13\r\n"
17937 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
17938 "Sec-WebSocket-Extensions: permessage-deflate; "
17939 "client_max_window_bits\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417940
17941 MockRead data_reads[] = {
17942 // HTTP CONNECT with credentials.
17943 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
17944
17945 // WebSocket connection established inside tunnel.
Bence Béky8d1c6052018-02-07 12:48:1517946 MockRead("HTTP/1.1 101 Switching Protocols\r\n"
17947 "Upgrade: websocket\r\n"
17948 "Connection: Upgrade\r\n"
17949 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417950
Ryan Sleevib8d7ea02018-05-07 20:01:0117951 StaticSocketDataProvider data(data_reads, data_writes);
Adam Rice425cf122015-01-19 06:18:2417952 session_deps_.socket_factory->AddSocketDataProvider(&data);
17953
17954 session->http_auth_cache()->Add(
17955 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
17956 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
17957
Bence Béky8d1c6052018-02-07 12:48:1517958 TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
17959
bnc87dcefc2017-05-25 12:47:5817960 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917961 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2417962 trans->SetWebSocketHandshakeStreamCreateHelper(
17963 &websocket_stream_create_helper);
17964
17965 TestCompletionCallback callback;
17966
tfarina42834112016-09-22 13:38:2017967 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117968 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2417969
17970 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117971 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2417972
17973 const HttpResponseInfo* response = trans->GetResponseInfo();
17974 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5217975 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2417976
17977 EXPECT_EQ(101, response->headers->response_code());
17978
17979 trans.reset();
17980 session->CloseAllConnections();
17981}
17982
Bence Békydca6bd92018-01-30 13:43:0617983#endif // BUILDFLAG(ENABLE_WEBSOCKETS)
17984
bncd16676a2016-07-20 16:23:0117985TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost) {
danakj1fd259a02016-04-16 03:17:0917986 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217987 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917988 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217989 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2217990
17991 HttpRequestInfo request;
17992 request.method = "POST";
17993 request.url = GURL("http://www.foo.com/");
17994 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017995 request.traffic_annotation =
17996 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2217997
danakj1fd259a02016-04-16 03:17:0917998 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617999 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2218000 MockWrite data_writes[] = {
18001 MockWrite("POST / HTTP/1.1\r\n"
18002 "Host: www.foo.com\r\n"
18003 "Connection: keep-alive\r\n"
18004 "Content-Length: 3\r\n\r\n"),
18005 MockWrite("foo"),
18006 };
18007
18008 MockRead data_reads[] = {
18009 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
18010 MockRead(SYNCHRONOUS, OK),
18011 };
Ryan Sleevib8d7ea02018-05-07 20:01:0118012 StaticSocketDataProvider data(data_reads, data_writes);
sclittlefb249892015-09-10 21:33:2218013 session_deps_.socket_factory->AddSocketDataProvider(&data);
18014
18015 TestCompletionCallback callback;
18016
18017 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2018018 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0118019 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2218020
18021 std::string response_data;
bnc691fda62016-08-12 00:43:1618022 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2218023
Ryan Sleevib8d7ea02018-05-07 20:01:0118024 EXPECT_EQ(CountWriteBytes(data_writes), trans.GetTotalSentBytes());
18025 EXPECT_EQ(CountReadBytes(data_reads), trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2218026}
18027
bncd16676a2016-07-20 16:23:0118028TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost100Continue) {
danakj1fd259a02016-04-16 03:17:0918029 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2218030 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1918031 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2218032 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2218033
18034 HttpRequestInfo request;
18035 request.method = "POST";
18036 request.url = GURL("http://www.foo.com/");
18037 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1018038 request.traffic_annotation =
18039 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2218040
danakj1fd259a02016-04-16 03:17:0918041 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1618042 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2218043 MockWrite data_writes[] = {
18044 MockWrite("POST / HTTP/1.1\r\n"
18045 "Host: www.foo.com\r\n"
18046 "Connection: keep-alive\r\n"
18047 "Content-Length: 3\r\n\r\n"),
18048 MockWrite("foo"),
18049 };
18050
18051 MockRead data_reads[] = {
18052 MockRead("HTTP/1.1 100 Continue\r\n\r\n"),
18053 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
18054 MockRead(SYNCHRONOUS, OK),
18055 };
Ryan Sleevib8d7ea02018-05-07 20:01:0118056 StaticSocketDataProvider data(data_reads, data_writes);
sclittlefb249892015-09-10 21:33:2218057 session_deps_.socket_factory->AddSocketDataProvider(&data);
18058
18059 TestCompletionCallback callback;
18060
18061 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2018062 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0118063 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2218064
18065 std::string response_data;
bnc691fda62016-08-12 00:43:1618066 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2218067
Ryan Sleevib8d7ea02018-05-07 20:01:0118068 EXPECT_EQ(CountWriteBytes(data_writes), trans.GetTotalSentBytes());
18069 EXPECT_EQ(CountReadBytes(data_reads), trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2218070}
18071
bncd16676a2016-07-20 16:23:0118072TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) {
sclittlefb249892015-09-10 21:33:2218073 ChunkedUploadDataStream upload_data_stream(0);
18074
18075 HttpRequestInfo request;
18076 request.method = "POST";
18077 request.url = GURL("http://www.foo.com/");
18078 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1018079 request.traffic_annotation =
18080 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2218081
danakj1fd259a02016-04-16 03:17:0918082 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1618083 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2218084 // Send headers successfully, but get an error while sending the body.
18085 MockWrite data_writes[] = {
18086 MockWrite("POST / HTTP/1.1\r\n"
18087 "Host: www.foo.com\r\n"
18088 "Connection: keep-alive\r\n"
18089 "Transfer-Encoding: chunked\r\n\r\n"),
18090 MockWrite("1\r\nf\r\n"), MockWrite("2\r\noo\r\n"), MockWrite("0\r\n\r\n"),
18091 };
18092
18093 MockRead data_reads[] = {
18094 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
18095 MockRead(SYNCHRONOUS, OK),
18096 };
Ryan Sleevib8d7ea02018-05-07 20:01:0118097 StaticSocketDataProvider data(data_reads, data_writes);
sclittlefb249892015-09-10 21:33:2218098 session_deps_.socket_factory->AddSocketDataProvider(&data);
18099
18100 TestCompletionCallback callback;
18101
18102 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2018103 trans.Start(&request, callback.callback(), NetLogWithSource()));
sclittlefb249892015-09-10 21:33:2218104
18105 base::RunLoop().RunUntilIdle();
18106 upload_data_stream.AppendData("f", 1, false);
18107
18108 base::RunLoop().RunUntilIdle();
18109 upload_data_stream.AppendData("oo", 2, true);
18110
robpercival214763f2016-07-01 23:27:0118111 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2218112
18113 std::string response_data;
bnc691fda62016-08-12 00:43:1618114 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2218115
Ryan Sleevib8d7ea02018-05-07 20:01:0118116 EXPECT_EQ(CountWriteBytes(data_writes), trans.GetTotalSentBytes());
18117 EXPECT_EQ(CountReadBytes(data_reads), trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2218118}
18119
eustasc7d27da2017-04-06 10:33:2018120void CheckContentEncodingMatching(SpdySessionDependencies* session_deps,
18121 const std::string& accept_encoding,
18122 const std::string& content_encoding,
sky50576f32017-05-01 19:28:0318123 const std::string& location,
eustasc7d27da2017-04-06 10:33:2018124 bool should_match) {
18125 HttpRequestInfo request;
18126 request.method = "GET";
18127 request.url = GURL("http://www.foo.com/");
18128 request.extra_headers.SetHeader(HttpRequestHeaders::kAcceptEncoding,
18129 accept_encoding);
Ramin Halavatib5e433e2018-02-07 07:41:1018130 request.traffic_annotation =
18131 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
eustasc7d27da2017-04-06 10:33:2018132
18133 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps));
18134 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18135 // Send headers successfully, but get an error while sending the body.
18136 MockWrite data_writes[] = {
18137 MockWrite("GET / HTTP/1.1\r\n"
18138 "Host: www.foo.com\r\n"
18139 "Connection: keep-alive\r\n"
18140 "Accept-Encoding: "),
18141 MockWrite(accept_encoding.data()), MockWrite("\r\n\r\n"),
18142 };
18143
sky50576f32017-05-01 19:28:0318144 std::string response_code = "200 OK";
18145 std::string extra;
18146 if (!location.empty()) {
18147 response_code = "301 Redirect\r\nLocation: ";
18148 response_code.append(location);
18149 }
18150
eustasc7d27da2017-04-06 10:33:2018151 MockRead data_reads[] = {
sky50576f32017-05-01 19:28:0318152 MockRead("HTTP/1.0 "),
18153 MockRead(response_code.data()),
18154 MockRead("\r\nContent-Encoding: "),
18155 MockRead(content_encoding.data()),
18156 MockRead("\r\n\r\n"),
eustasc7d27da2017-04-06 10:33:2018157 MockRead(SYNCHRONOUS, OK),
18158 };
Ryan Sleevib8d7ea02018-05-07 20:01:0118159 StaticSocketDataProvider data(data_reads, data_writes);
eustasc7d27da2017-04-06 10:33:2018160 session_deps->socket_factory->AddSocketDataProvider(&data);
18161
18162 TestCompletionCallback callback;
18163
18164 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18165 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18166
18167 rv = callback.WaitForResult();
18168 if (should_match) {
18169 EXPECT_THAT(rv, IsOk());
18170 } else {
18171 EXPECT_THAT(rv, IsError(ERR_CONTENT_DECODING_FAILED));
18172 }
18173}
18174
18175TEST_F(HttpNetworkTransactionTest, MatchContentEncoding1) {
sky50576f32017-05-01 19:28:0318176 CheckContentEncodingMatching(&session_deps_, "gzip,sdch", "br", "", false);
eustasc7d27da2017-04-06 10:33:2018177}
18178
18179TEST_F(HttpNetworkTransactionTest, MatchContentEncoding2) {
sky50576f32017-05-01 19:28:0318180 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "", "",
18181 true);
eustasc7d27da2017-04-06 10:33:2018182}
18183
18184TEST_F(HttpNetworkTransactionTest, MatchContentEncoding3) {
18185 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
sky50576f32017-05-01 19:28:0318186 "", false);
18187}
18188
18189TEST_F(HttpNetworkTransactionTest, MatchContentEncoding4) {
18190 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
18191 "www.foo.com/other", true);
eustasc7d27da2017-04-06 10:33:2018192}
18193
xunjieli96f2a402017-06-05 17:24:2718194TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsSync) {
18195 ProxyConfig proxy_config;
18196 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
18197 proxy_config.set_pac_mandatory(true);
18198 MockAsyncProxyResolver resolver;
Lily Houghton8c2f97d2018-01-22 05:06:5918199 session_deps_.proxy_resolution_service.reset(new ProxyResolutionService(
Ramin Halavatica8d5252018-03-12 05:33:4918200 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
18201 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
Bence Béky8f9d7d3952017-10-09 19:58:0418202 std::make_unique<FailingProxyResolverFactory>(), nullptr));
xunjieli96f2a402017-06-05 17:24:2718203
18204 HttpRequestInfo request;
18205 request.method = "GET";
18206 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1018207 request.traffic_annotation =
18208 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2718209
18210 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18211 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18212
18213 TestCompletionCallback callback;
18214
18215 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18216 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18217 EXPECT_THAT(callback.WaitForResult(),
18218 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
18219}
18220
18221TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsAsync) {
18222 ProxyConfig proxy_config;
18223 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
18224 proxy_config.set_pac_mandatory(true);
18225 MockAsyncProxyResolverFactory* proxy_resolver_factory =
18226 new MockAsyncProxyResolverFactory(false);
18227 MockAsyncProxyResolver resolver;
Lily Houghton8c2f97d2018-01-22 05:06:5918228 session_deps_.proxy_resolution_service.reset(new ProxyResolutionService(
Ramin Halavatica8d5252018-03-12 05:33:4918229 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
18230 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
Lily Houghton8c2f97d2018-01-22 05:06:5918231 base::WrapUnique(proxy_resolver_factory), nullptr));
xunjieli96f2a402017-06-05 17:24:2718232 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 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18243 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18244
18245 proxy_resolver_factory->pending_requests()[0]->CompleteNowWithForwarder(
18246 ERR_FAILED, &resolver);
18247 EXPECT_THAT(callback.WaitForResult(),
18248 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
18249}
18250
18251TEST_F(HttpNetworkTransactionTest, NoSupportedProxies) {
Lily Houghton8c2f97d2018-01-22 05:06:5918252 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4918253 ProxyResolutionService::CreateFixedFromPacResult(
18254 "QUIC myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2718255 session_deps_.enable_quic = false;
18256 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18257
18258 HttpRequestInfo request;
18259 request.method = "GET";
18260 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1018261 request.traffic_annotation =
18262 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2718263
18264 TestCompletionCallback callback;
18265 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18266 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18267 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18268
18269 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NO_SUPPORTED_PROXIES));
18270}
18271
Douglas Creager3cb042052018-11-06 23:08:5218272//-----------------------------------------------------------------------------
Douglas Creager134b52e2018-11-09 18:00:1418273// Reporting tests
18274
18275#if BUILDFLAG(ENABLE_REPORTING)
18276class HttpNetworkTransactionReportingTest : public HttpNetworkTransactionTest {
18277 protected:
18278 void SetUp() override {
Douglas Creageref5eecdc2018-11-09 20:50:3618279 HttpNetworkTransactionTest::SetUp();
Douglas Creager134b52e2018-11-09 18:00:1418280 auto test_reporting_context = std::make_unique<TestReportingContext>(
18281 &clock_, &tick_clock_, ReportingPolicy());
18282 test_reporting_context_ = test_reporting_context.get();
18283 session_deps_.reporting_service =
18284 ReportingService::CreateForTesting(std::move(test_reporting_context));
18285 }
18286
18287 TestReportingContext* reporting_context() const {
18288 return test_reporting_context_;
18289 }
18290
18291 void clear_reporting_service() {
18292 session_deps_.reporting_service.reset();
18293 test_reporting_context_ = nullptr;
18294 }
18295
18296 // Makes an HTTPS request that should install a valid Reporting policy.
Lily Chenfec60d92019-01-24 01:16:4218297 void RequestPolicy(CertStatus cert_status = 0) {
18298 HttpRequestInfo request;
18299 request.method = "GET";
18300 request.url = GURL(url_);
18301 request.traffic_annotation =
18302 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
18303
Lily Chend3930e72019-03-01 19:31:1118304 MockWrite data_writes[] = {
18305 MockWrite("GET / HTTP/1.1\r\n"
18306 "Host: www.example.org\r\n"
18307 "Connection: keep-alive\r\n\r\n"),
18308 };
Douglas Creager134b52e2018-11-09 18:00:1418309 MockRead data_reads[] = {
18310 MockRead("HTTP/1.0 200 OK\r\n"),
18311 MockRead("Report-To: {\"group\": \"nel\", \"max_age\": 86400, "
18312 "\"endpoints\": [{\"url\": "
18313 "\"https://www.example.org/upload/\"}]}\r\n"),
18314 MockRead("\r\n"),
18315 MockRead("hello world"),
18316 MockRead(SYNCHRONOUS, OK),
18317 };
Douglas Creager134b52e2018-11-09 18:00:1418318
Lily Chenfec60d92019-01-24 01:16:4218319 StaticSocketDataProvider reads(data_reads, data_writes);
18320 session_deps_.socket_factory->AddSocketDataProvider(&reads);
Douglas Creager134b52e2018-11-09 18:00:1418321
18322 SSLSocketDataProvider ssl(ASYNC, OK);
18323 if (request.url.SchemeIsCryptographic()) {
18324 ssl.ssl_info.cert =
18325 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
18326 ASSERT_TRUE(ssl.ssl_info.cert);
Lily Chenfec60d92019-01-24 01:16:4218327 ssl.ssl_info.cert_status = cert_status;
Douglas Creager134b52e2018-11-09 18:00:1418328 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
18329 }
18330
Douglas Creager134b52e2018-11-09 18:00:1418331 TestCompletionCallback callback;
18332 auto session = CreateSession(&session_deps_);
18333 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18334 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
Lily Chenfec60d92019-01-24 01:16:4218335 EXPECT_THAT(callback.GetResult(rv), IsOk());
Douglas Creager134b52e2018-11-09 18:00:1418336 }
18337
18338 protected:
18339 std::string url_ = "https://www.example.org/";
Douglas Creager134b52e2018-11-09 18:00:1418340
18341 private:
18342 TestReportingContext* test_reporting_context_;
18343};
18344
18345TEST_F(HttpNetworkTransactionReportingTest,
18346 DontProcessReportToHeaderNoService) {
18347 base::HistogramTester histograms;
18348 clear_reporting_service();
18349 RequestPolicy();
18350 histograms.ExpectBucketCount(
18351 ReportingHeaderParser::kHeaderOutcomeHistogram,
18352 ReportingHeaderParser::HeaderOutcome::DISCARDED_NO_REPORTING_SERVICE, 1);
18353}
18354
18355TEST_F(HttpNetworkTransactionReportingTest, DontProcessReportToHeaderHttp) {
18356 base::HistogramTester histograms;
18357 url_ = "http://www.example.org/";
18358 RequestPolicy();
18359 histograms.ExpectBucketCount(
18360 ReportingHeaderParser::kHeaderOutcomeHistogram,
18361 ReportingHeaderParser::HeaderOutcome::DISCARDED_INVALID_SSL_INFO, 1);
18362}
18363
18364TEST_F(HttpNetworkTransactionReportingTest, ProcessReportToHeaderHttps) {
18365 RequestPolicy();
18366 std::vector<const ReportingClient*> clients;
18367 reporting_context()->cache()->GetClients(&clients);
18368 ASSERT_EQ(1u, clients.size());
18369 const auto* client = clients[0];
18370 EXPECT_EQ(url::Origin::Create(GURL("https://www.example.org/")),
18371 client->origin);
18372 EXPECT_EQ(GURL("https://www.example.org/upload/"), client->endpoint);
18373 EXPECT_EQ("nel", client->group);
18374}
18375
18376TEST_F(HttpNetworkTransactionReportingTest,
18377 DontProcessReportToHeaderInvalidHttps) {
18378 base::HistogramTester histograms;
Lily Chenfec60d92019-01-24 01:16:4218379 CertStatus cert_status = CERT_STATUS_COMMON_NAME_INVALID;
18380 RequestPolicy(cert_status);
Douglas Creager134b52e2018-11-09 18:00:1418381 histograms.ExpectBucketCount(
18382 ReportingHeaderParser::kHeaderOutcomeHistogram,
18383 ReportingHeaderParser::HeaderOutcome::DISCARDED_CERT_STATUS_ERROR, 1);
18384}
18385#endif // BUILDFLAG(ENABLE_REPORTING)
18386
18387//-----------------------------------------------------------------------------
Douglas Creager3cb042052018-11-06 23:08:5218388// Network Error Logging tests
18389
18390#if BUILDFLAG(ENABLE_REPORTING)
Lily Chenfec60d92019-01-24 01:16:4218391namespace {
18392
18393const char kUserAgent[] = "Mozilla/1.0";
18394const char kReferrer[] = "https://www.referrer.org/";
18395
18396} // namespace
18397
Douglas Creager3cb042052018-11-06 23:08:5218398class HttpNetworkTransactionNetworkErrorLoggingTest
18399 : public HttpNetworkTransactionTest {
18400 protected:
18401 void SetUp() override {
Douglas Creageref5eecdc2018-11-09 20:50:3618402 HttpNetworkTransactionTest::SetUp();
Douglas Creager3cb042052018-11-06 23:08:5218403 auto network_error_logging_service =
18404 std::make_unique<TestNetworkErrorLoggingService>();
18405 test_network_error_logging_service_ = network_error_logging_service.get();
18406 session_deps_.network_error_logging_service =
18407 std::move(network_error_logging_service);
Lily Chenfec60d92019-01-24 01:16:4218408
18409 extra_headers_.SetHeader("User-Agent", kUserAgent);
18410 extra_headers_.SetHeader("Referer", kReferrer);
18411
18412 request_.method = "GET";
18413 request_.url = GURL(url_);
18414 request_.extra_headers = extra_headers_;
18415 request_.reporting_upload_depth = reporting_upload_depth_;
18416 request_.traffic_annotation =
18417 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Douglas Creager3cb042052018-11-06 23:08:5218418 }
18419
18420 TestNetworkErrorLoggingService* network_error_logging_service() const {
18421 return test_network_error_logging_service_;
18422 }
18423
18424 void clear_network_error_logging_service() {
18425 session_deps_.network_error_logging_service.reset();
18426 test_network_error_logging_service_ = nullptr;
18427 }
18428
18429 // Makes an HTTPS request that should install a valid NEL policy.
Lily Chenfec60d92019-01-24 01:16:4218430 void RequestPolicy(CertStatus cert_status = 0) {
Douglas Creageref5eecdc2018-11-09 20:50:3618431 std::string extra_header_string = extra_headers_.ToString();
Lily Chen29c04032019-02-25 21:50:5318432 MockWrite data_writes[] = {
18433 MockWrite("GET / HTTP/1.1\r\n"
18434 "Host: www.example.org\r\n"
18435 "Connection: keep-alive\r\n"),
18436 MockWrite(ASYNC, extra_header_string.data(),
18437 extra_header_string.size()),
18438 };
Lily Chend3930e72019-03-01 19:31:1118439 MockRead data_reads[] = {
18440 MockRead("HTTP/1.0 200 OK\r\n"),
18441 MockRead("NEL: {\"report_to\": \"nel\", \"max_age\": 86400}\r\n"),
18442 MockRead("\r\n"),
18443 MockRead("hello world"),
18444 MockRead(SYNCHRONOUS, OK),
18445 };
Douglas Creager3cb042052018-11-06 23:08:5218446
Lily Chenfec60d92019-01-24 01:16:4218447 StaticSocketDataProvider reads(data_reads, data_writes);
18448 session_deps_.socket_factory->AddSocketDataProvider(&reads);
Douglas Creager3cb042052018-11-06 23:08:5218449
18450 SSLSocketDataProvider ssl(ASYNC, OK);
Lily Chenfec60d92019-01-24 01:16:4218451 if (request_.url.SchemeIsCryptographic()) {
Douglas Creager3cb042052018-11-06 23:08:5218452 ssl.ssl_info.cert =
18453 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
18454 ASSERT_TRUE(ssl.ssl_info.cert);
Lily Chenfec60d92019-01-24 01:16:4218455 ssl.ssl_info.cert_status = cert_status;
Douglas Creager3cb042052018-11-06 23:08:5218456 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
18457 }
18458
Douglas Creager3cb042052018-11-06 23:08:5218459 TestCompletionCallback callback;
18460 auto session = CreateSession(&session_deps_);
18461 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
Lily Chenfec60d92019-01-24 01:16:4218462 int rv = trans.Start(&request_, callback.callback(), NetLogWithSource());
18463 EXPECT_THAT(callback.GetResult(rv), IsOk());
18464
18465 std::string response_data;
18466 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
18467 EXPECT_EQ("hello world", response_data);
18468 }
18469
18470 void CheckReport(size_t index,
18471 int status_code,
18472 int error_type,
18473 IPAddress server_ip = IPAddress::IPv4Localhost()) {
18474 ASSERT_LT(index, network_error_logging_service()->errors().size());
18475
18476 const NetworkErrorLoggingService::RequestDetails& error =
18477 network_error_logging_service()->errors()[index];
18478 EXPECT_EQ(url_, error.uri);
18479 EXPECT_EQ(kReferrer, error.referrer);
18480 EXPECT_EQ(kUserAgent, error.user_agent);
18481 EXPECT_EQ(server_ip, error.server_ip);
18482 EXPECT_EQ("http/1.1", error.protocol);
18483 EXPECT_EQ("GET", error.method);
18484 EXPECT_EQ(status_code, error.status_code);
18485 EXPECT_EQ(error_type, error.type);
18486 EXPECT_EQ(0, error.reporting_upload_depth);
Douglas Creager3cb042052018-11-06 23:08:5218487 }
18488
18489 protected:
18490 std::string url_ = "https://www.example.org/";
18491 CertStatus cert_status_ = 0;
Lily Chenfec60d92019-01-24 01:16:4218492 HttpRequestInfo request_;
Douglas Creageref5eecdc2018-11-09 20:50:3618493 HttpRequestHeaders extra_headers_;
18494 int reporting_upload_depth_ = 0;
Douglas Creager3cb042052018-11-06 23:08:5218495
18496 private:
18497 TestNetworkErrorLoggingService* test_network_error_logging_service_;
18498};
18499
18500TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18501 DontProcessNelHeaderNoService) {
18502 base::HistogramTester histograms;
18503 clear_network_error_logging_service();
18504 RequestPolicy();
18505 histograms.ExpectBucketCount(
18506 NetworkErrorLoggingService::kHeaderOutcomeHistogram,
18507 NetworkErrorLoggingService::HeaderOutcome::
18508 DISCARDED_NO_NETWORK_ERROR_LOGGING_SERVICE,
18509 1);
18510}
18511
18512TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18513 DontProcessNelHeaderHttp) {
18514 base::HistogramTester histograms;
18515 url_ = "http://www.example.org/";
Lily Chenfec60d92019-01-24 01:16:4218516 request_.url = GURL(url_);
Douglas Creager3cb042052018-11-06 23:08:5218517 RequestPolicy();
18518 histograms.ExpectBucketCount(
18519 NetworkErrorLoggingService::kHeaderOutcomeHistogram,
18520 NetworkErrorLoggingService::HeaderOutcome::DISCARDED_INVALID_SSL_INFO, 1);
18521}
18522
Lily Chen90ae93cc2019-02-14 01:15:3918523// Don't set NEL policies received on a proxied connection.
18524TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18525 DontProcessNelHeaderProxy) {
18526 session_deps_.proxy_resolution_service =
18527 ProxyResolutionService::CreateFixedFromPacResult(
18528 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
18529 BoundTestNetLog log;
18530 session_deps_.net_log = log.bound().net_log();
18531 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18532
18533 HttpRequestInfo request;
18534 request.method = "GET";
18535 request.url = GURL("https://www.example.org/");
18536 request.traffic_annotation =
18537 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
18538
18539 // Since we have proxy, should try to establish tunnel.
18540 MockWrite data_writes1[] = {
18541 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
18542 "Host: www.example.org:443\r\n"
18543 "Proxy-Connection: keep-alive\r\n\r\n"),
18544
18545 MockWrite("GET / HTTP/1.1\r\n"
18546 "Host: www.example.org\r\n"
18547 "Connection: keep-alive\r\n\r\n"),
18548 };
18549
18550 MockRead data_reads1[] = {
18551 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
18552
18553 MockRead("HTTP/1.1 200 OK\r\n"),
18554 MockRead("NEL: {\"report_to\": \"nel\", \"max_age\": 86400}\r\n"),
18555 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
18556 MockRead("Content-Length: 100\r\n\r\n"),
18557 MockRead(SYNCHRONOUS, OK),
18558 };
18559
18560 StaticSocketDataProvider data1(data_reads1, data_writes1);
18561 session_deps_.socket_factory->AddSocketDataProvider(&data1);
18562 SSLSocketDataProvider ssl(ASYNC, OK);
18563 ssl.ssl_info.cert =
18564 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
18565 ASSERT_TRUE(ssl.ssl_info.cert);
18566 ssl.ssl_info.cert_status = 0;
18567 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
18568
18569 TestCompletionCallback callback1;
18570 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18571
18572 int rv = trans.Start(&request, callback1.callback(), log.bound());
18573 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18574
18575 rv = callback1.WaitForResult();
18576 EXPECT_THAT(rv, IsOk());
18577
18578 const HttpResponseInfo* response = trans.GetResponseInfo();
18579 ASSERT_TRUE(response);
18580 EXPECT_EQ(200, response->headers->response_code());
18581 EXPECT_TRUE(response->was_fetched_via_proxy);
18582
18583 // No NEL header was set.
18584 EXPECT_EQ(0u, network_error_logging_service()->headers().size());
18585}
18586
Douglas Creager3cb042052018-11-06 23:08:5218587TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, ProcessNelHeaderHttps) {
18588 RequestPolicy();
18589 ASSERT_EQ(1u, network_error_logging_service()->headers().size());
18590 const auto& header = network_error_logging_service()->headers()[0];
18591 EXPECT_EQ(url::Origin::Create(GURL("https://www.example.org/")),
18592 header.origin);
18593 EXPECT_EQ(IPAddress::IPv4Localhost(), header.received_ip_address);
18594 EXPECT_EQ("{\"report_to\": \"nel\", \"max_age\": 86400}", header.value);
18595}
18596
18597TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18598 DontProcessNelHeaderInvalidHttps) {
18599 base::HistogramTester histograms;
Lily Chenfec60d92019-01-24 01:16:4218600 CertStatus cert_status = CERT_STATUS_COMMON_NAME_INVALID;
18601 RequestPolicy(cert_status);
Douglas Creager3cb042052018-11-06 23:08:5218602 histograms.ExpectBucketCount(
18603 NetworkErrorLoggingService::kHeaderOutcomeHistogram,
18604 NetworkErrorLoggingService::HeaderOutcome::DISCARDED_CERT_STATUS_ERROR,
18605 1);
18606}
Douglas Creageref5eecdc2018-11-09 20:50:3618607
Lily Chenfec60d92019-01-24 01:16:4218608TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, CreateReportSuccess) {
Douglas Creageref5eecdc2018-11-09 20:50:3618609 RequestPolicy();
18610 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
Lily Chenfec60d92019-01-24 01:16:4218611 CheckReport(0 /* index */, 200 /* status_code */, OK);
18612}
18613
18614TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18615 CreateReportErrorAfterStart) {
18616 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18617 auto trans =
18618 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18619
18620 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
18621 StaticSocketDataProvider data;
18622 data.set_connect_data(mock_connect);
18623 session_deps_.socket_factory->AddSocketDataProvider(&data);
18624
18625 TestCompletionCallback callback;
18626
18627 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
18628 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_NAME_NOT_RESOLVED));
18629
18630 trans.reset();
18631
18632 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18633 CheckReport(0 /* index */, 0 /* status_code */, ERR_NAME_NOT_RESOLVED,
18634 IPAddress() /* server_ip */);
18635}
18636
18637// Same as above except the error is ASYNC
18638TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18639 CreateReportErrorAfterStartAsync) {
18640 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18641 auto trans =
18642 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18643
18644 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
18645 StaticSocketDataProvider data;
18646 data.set_connect_data(mock_connect);
18647 session_deps_.socket_factory->AddSocketDataProvider(&data);
18648
18649 TestCompletionCallback callback;
18650
18651 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
18652 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_NAME_NOT_RESOLVED));
18653
18654 trans.reset();
18655
18656 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18657 CheckReport(0 /* index */, 0 /* status_code */, ERR_NAME_NOT_RESOLVED,
18658 IPAddress() /* server_ip */);
18659}
18660
18661TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18662 CreateReportReadBodyError) {
18663 std::string extra_header_string = extra_headers_.ToString();
Lily Chen29c04032019-02-25 21:50:5318664 MockWrite data_writes[] = {
18665 MockWrite("GET / HTTP/1.1\r\n"
18666 "Host: www.example.org\r\n"
18667 "Connection: keep-alive\r\n"),
18668 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18669 };
Lily Chend3930e72019-03-01 19:31:1118670 MockRead data_reads[] = {
18671 MockRead("HTTP/1.0 200 OK\r\n"),
18672 MockRead("Content-Length: 100\r\n\r\n"), // wrong content length
18673 MockRead("hello world"),
18674 MockRead(SYNCHRONOUS, OK),
18675 };
Lily Chenfec60d92019-01-24 01:16:4218676
18677 StaticSocketDataProvider reads(data_reads, data_writes);
18678 session_deps_.socket_factory->AddSocketDataProvider(&reads);
18679
18680 SSLSocketDataProvider ssl(ASYNC, OK);
18681 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
18682
18683 // Log start time
18684 base::TimeTicks start_time = base::TimeTicks::Now();
18685
18686 TestCompletionCallback callback;
18687 auto session = CreateSession(&session_deps_);
18688 auto trans =
18689 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18690 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
18691 EXPECT_THAT(callback.GetResult(rv), IsOk());
18692
18693 const HttpResponseInfo* response = trans->GetResponseInfo();
18694 ASSERT_TRUE(response);
18695
18696 EXPECT_TRUE(response->headers);
18697 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
18698
18699 std::string response_data;
18700 rv = ReadTransaction(trans.get(), &response_data);
18701 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
18702
18703 trans.reset();
18704
18705 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18706
18707 CheckReport(0 /* index */, 200 /* status_code */,
18708 ERR_CONTENT_LENGTH_MISMATCH);
18709 const NetworkErrorLoggingService::RequestDetails& error =
18710 network_error_logging_service()->errors()[0];
18711 EXPECT_LE(error.elapsed_time, base::TimeTicks::Now() - start_time);
18712}
18713
18714// Same as above except the final read is ASYNC.
18715TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18716 CreateReportReadBodyErrorAsync) {
18717 std::string extra_header_string = extra_headers_.ToString();
Lily Chen29c04032019-02-25 21:50:5318718 MockWrite data_writes[] = {
18719 MockWrite("GET / HTTP/1.1\r\n"
18720 "Host: www.example.org\r\n"
18721 "Connection: keep-alive\r\n"),
18722 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18723 };
Lily Chend3930e72019-03-01 19:31:1118724 MockRead data_reads[] = {
18725 MockRead("HTTP/1.0 200 OK\r\n"),
18726 MockRead("Content-Length: 100\r\n\r\n"), // wrong content length
18727 MockRead("hello world"),
18728 MockRead(ASYNC, OK),
18729 };
Lily Chenfec60d92019-01-24 01:16:4218730
18731 StaticSocketDataProvider reads(data_reads, data_writes);
18732 session_deps_.socket_factory->AddSocketDataProvider(&reads);
18733
18734 SSLSocketDataProvider ssl(ASYNC, OK);
18735 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
18736
18737 // Log start time
18738 base::TimeTicks start_time = base::TimeTicks::Now();
18739
18740 TestCompletionCallback callback;
18741 auto session = CreateSession(&session_deps_);
18742 auto trans =
18743 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18744 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
18745 EXPECT_THAT(callback.GetResult(rv), IsOk());
18746
18747 const HttpResponseInfo* response = trans->GetResponseInfo();
18748 ASSERT_TRUE(response);
18749
18750 EXPECT_TRUE(response->headers);
18751 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
18752
18753 std::string response_data;
18754 rv = ReadTransaction(trans.get(), &response_data);
18755 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
18756
18757 trans.reset();
18758
18759 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18760
18761 CheckReport(0 /* index */, 200 /* status_code */,
18762 ERR_CONTENT_LENGTH_MISMATCH);
18763 const NetworkErrorLoggingService::RequestDetails& error =
18764 network_error_logging_service()->errors()[0];
18765 EXPECT_LE(error.elapsed_time, base::TimeTicks::Now() - start_time);
18766}
18767
18768TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18769 CreateReportRestartWithAuth) {
18770 std::string extra_header_string = extra_headers_.ToString();
18771 static const base::TimeDelta kSleepDuration =
18772 base::TimeDelta::FromMilliseconds(10);
18773
18774 MockWrite data_writes1[] = {
18775 MockWrite("GET / HTTP/1.1\r\n"
18776 "Host: www.example.org\r\n"
18777 "Connection: keep-alive\r\n"),
18778 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18779 };
18780
18781 MockRead data_reads1[] = {
18782 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
18783 // Give a couple authenticate options (only the middle one is actually
18784 // supported).
18785 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
18786 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
18787 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
18788 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
18789 // Large content-length -- won't matter, as connection will be reset.
18790 MockRead("Content-Length: 10000\r\n\r\n"),
18791 MockRead(SYNCHRONOUS, ERR_FAILED),
18792 };
18793
18794 // After calling trans->RestartWithAuth(), this is the request we should
18795 // be issuing -- the final header line contains the credentials.
18796 MockWrite data_writes2[] = {
18797 MockWrite("GET / HTTP/1.1\r\n"
18798 "Host: www.example.org\r\n"
18799 "Connection: keep-alive\r\n"
18800 "Authorization: Basic Zm9vOmJhcg==\r\n"),
18801 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18802 };
18803
18804 // Lastly, the server responds with the actual content.
18805 MockRead data_reads2[] = {
18806 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
18807 MockRead("hello world"),
18808 MockRead(SYNCHRONOUS, OK),
18809 };
18810
18811 StaticSocketDataProvider data1(data_reads1, data_writes1);
18812 StaticSocketDataProvider data2(data_reads2, data_writes2);
18813 session_deps_.socket_factory->AddSocketDataProvider(&data1);
18814 session_deps_.socket_factory->AddSocketDataProvider(&data2);
18815
18816 SSLSocketDataProvider ssl1(ASYNC, OK);
18817 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
18818 SSLSocketDataProvider ssl2(ASYNC, OK);
18819 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
18820
18821 base::TimeTicks start_time = base::TimeTicks::Now();
18822 base::TimeTicks restart_time;
18823
18824 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18825 auto trans =
18826 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18827
18828 TestCompletionCallback callback1;
18829
18830 int rv = trans->Start(&request_, callback1.callback(), NetLogWithSource());
18831 EXPECT_THAT(callback1.GetResult(rv), IsOk());
18832
18833 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18834
18835 TestCompletionCallback callback2;
18836
18837 // Wait 10 ms then restart with auth
18838 FastForwardBy(kSleepDuration);
18839 restart_time = base::TimeTicks::Now();
18840 rv =
18841 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
18842 EXPECT_THAT(callback2.GetResult(rv), IsOk());
18843
18844 std::string response_data;
18845 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
18846 EXPECT_EQ("hello world", response_data);
18847
18848 trans.reset();
18849
18850 // One 401 report for the auth challenge, then a 200 report for the successful
18851 // retry. Note that we don't report the error draining the body, as the first
18852 // request already generated a report for the auth challenge.
18853 ASSERT_EQ(2u, network_error_logging_service()->errors().size());
18854
18855 // Check error report contents
18856 CheckReport(0 /* index */, 401 /* status_code */, OK);
18857 CheckReport(1 /* index */, 200 /* status_code */, OK);
18858
18859 const NetworkErrorLoggingService::RequestDetails& error1 =
18860 network_error_logging_service()->errors()[0];
18861 const NetworkErrorLoggingService::RequestDetails& error2 =
18862 network_error_logging_service()->errors()[1];
18863
18864 // Sanity-check elapsed time values
18865 EXPECT_EQ(error1.elapsed_time, restart_time - start_time - kSleepDuration);
18866 // Check that the start time is refreshed when restarting with auth.
18867 EXPECT_EQ(error2.elapsed_time, base::TimeTicks::Now() - restart_time);
18868}
18869
18870// Same as above, except draining the body before restarting fails
18871// asynchronously.
18872TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18873 CreateReportRestartWithAuthAsync) {
18874 std::string extra_header_string = extra_headers_.ToString();
18875 static const base::TimeDelta kSleepDuration =
18876 base::TimeDelta::FromMilliseconds(10);
18877
18878 MockWrite data_writes1[] = {
18879 MockWrite("GET / HTTP/1.1\r\n"
18880 "Host: www.example.org\r\n"
18881 "Connection: keep-alive\r\n"),
18882 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18883 };
18884
18885 MockRead data_reads1[] = {
18886 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
18887 // Give a couple authenticate options (only the middle one is actually
18888 // supported).
18889 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
18890 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
18891 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
18892 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
18893 // Large content-length -- won't matter, as connection will be reset.
18894 MockRead("Content-Length: 10000\r\n\r\n"),
18895 MockRead(ASYNC, ERR_FAILED),
18896 };
18897
18898 // After calling trans->RestartWithAuth(), this is the request we should
18899 // be issuing -- the final header line contains the credentials.
18900 MockWrite data_writes2[] = {
18901 MockWrite("GET / HTTP/1.1\r\n"
18902 "Host: www.example.org\r\n"
18903 "Connection: keep-alive\r\n"
18904 "Authorization: Basic Zm9vOmJhcg==\r\n"),
18905 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18906 };
18907
18908 // Lastly, the server responds with the actual content.
18909 MockRead data_reads2[] = {
18910 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
18911 MockRead("hello world"),
18912 MockRead(SYNCHRONOUS, OK),
18913 };
18914
18915 StaticSocketDataProvider data1(data_reads1, data_writes1);
18916 StaticSocketDataProvider data2(data_reads2, data_writes2);
18917 session_deps_.socket_factory->AddSocketDataProvider(&data1);
18918 session_deps_.socket_factory->AddSocketDataProvider(&data2);
18919
18920 SSLSocketDataProvider ssl1(ASYNC, OK);
18921 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
18922 SSLSocketDataProvider ssl2(ASYNC, OK);
18923 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
18924
18925 base::TimeTicks start_time = base::TimeTicks::Now();
18926 base::TimeTicks restart_time;
18927
18928 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18929 auto trans =
18930 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18931
18932 TestCompletionCallback callback1;
18933
18934 int rv = trans->Start(&request_, callback1.callback(), NetLogWithSource());
18935 EXPECT_THAT(callback1.GetResult(rv), IsOk());
18936
18937 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18938
18939 TestCompletionCallback callback2;
18940
18941 // Wait 10 ms then restart with auth
18942 FastForwardBy(kSleepDuration);
18943 restart_time = base::TimeTicks::Now();
18944 rv =
18945 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
18946 EXPECT_THAT(callback2.GetResult(rv), IsOk());
18947
18948 std::string response_data;
18949 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
18950 EXPECT_EQ("hello world", response_data);
18951
18952 trans.reset();
18953
18954 // One 401 report for the auth challenge, then a 200 report for the successful
18955 // retry. Note that we don't report the error draining the body, as the first
18956 // request already generated a report for the auth challenge.
18957 ASSERT_EQ(2u, network_error_logging_service()->errors().size());
18958
18959 // Check error report contents
18960 CheckReport(0 /* index */, 401 /* status_code */, OK);
18961 CheckReport(1 /* index */, 200 /* status_code */, OK);
18962
18963 const NetworkErrorLoggingService::RequestDetails& error1 =
18964 network_error_logging_service()->errors()[0];
18965 const NetworkErrorLoggingService::RequestDetails& error2 =
18966 network_error_logging_service()->errors()[1];
18967
18968 // Sanity-check elapsed time values
18969 EXPECT_EQ(error1.elapsed_time, restart_time - start_time - kSleepDuration);
18970 // Check that the start time is refreshed when restarting with auth.
18971 EXPECT_EQ(error2.elapsed_time, base::TimeTicks::Now() - restart_time);
18972}
18973
18974TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18975 CreateReportRetryKeepAliveConnectionReset) {
18976 std::string extra_header_string = extra_headers_.ToString();
18977 MockWrite data_writes1[] = {
18978 MockWrite("GET / HTTP/1.1\r\n"
18979 "Host: www.example.org\r\n"
18980 "Connection: keep-alive\r\n"),
18981 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18982 MockWrite("GET / HTTP/1.1\r\n"
18983 "Host: www.example.org\r\n"
18984 "Connection: keep-alive\r\n"),
18985 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18986 };
18987
18988 MockRead data_reads1[] = {
18989 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
18990 MockRead("hello"),
18991 // Connection is reset
18992 MockRead(ASYNC, ERR_CONNECTION_RESET),
18993 };
18994
18995 // Successful retry
18996 MockRead data_reads2[] = {
18997 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
18998 MockRead("world"),
18999 MockRead(ASYNC, OK),
19000 };
19001
19002 StaticSocketDataProvider data1(data_reads1, data_writes1);
19003 StaticSocketDataProvider data2(data_reads2, base::span<MockWrite>());
19004 session_deps_.socket_factory->AddSocketDataProvider(&data1);
19005 session_deps_.socket_factory->AddSocketDataProvider(&data2);
19006
19007 SSLSocketDataProvider ssl1(ASYNC, OK);
19008 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
19009 SSLSocketDataProvider ssl2(ASYNC, OK);
19010 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
19011
19012 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19013 auto trans1 =
19014 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19015
19016 TestCompletionCallback callback1;
19017
19018 int rv = trans1->Start(&request_, callback1.callback(), NetLogWithSource());
19019 EXPECT_THAT(callback1.GetResult(rv), IsOk());
19020
19021 std::string response_data;
19022 ASSERT_THAT(ReadTransaction(trans1.get(), &response_data), IsOk());
19023 EXPECT_EQ("hello", response_data);
19024
19025 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
19026
19027 auto trans2 =
19028 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19029
19030 TestCompletionCallback callback2;
19031
19032 rv = trans2->Start(&request_, callback2.callback(), NetLogWithSource());
19033 EXPECT_THAT(callback2.GetResult(rv), IsOk());
19034
19035 ASSERT_THAT(ReadTransaction(trans2.get(), &response_data), IsOk());
19036 EXPECT_EQ("world", response_data);
19037
19038 trans1.reset();
19039 trans2.reset();
19040
19041 // One OK report from first request, then a ERR_CONNECTION_RESET report from
19042 // the second request, then an OK report from the successful retry.
19043 ASSERT_EQ(3u, network_error_logging_service()->errors().size());
19044
19045 // Check error report contents
19046 CheckReport(0 /* index */, 200 /* status_code */, OK);
19047 CheckReport(1 /* index */, 0 /* status_code */, ERR_CONNECTION_RESET);
19048 CheckReport(2 /* index */, 200 /* status_code */, OK);
19049}
19050
19051TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
19052 CreateReportRetryKeepAlive408) {
19053 std::string extra_header_string = extra_headers_.ToString();
19054 MockWrite data_writes1[] = {
19055 MockWrite("GET / HTTP/1.1\r\n"
19056 "Host: www.example.org\r\n"
19057 "Connection: keep-alive\r\n"),
19058 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
19059 MockWrite("GET / HTTP/1.1\r\n"
19060 "Host: www.example.org\r\n"
19061 "Connection: keep-alive\r\n"),
19062 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
19063 };
19064
19065 MockRead data_reads1[] = {
19066 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
19067 MockRead("hello"),
19068 // 408 Request Timeout
19069 MockRead(SYNCHRONOUS,
19070 "HTTP/1.1 408 Request Timeout\r\n"
19071 "Connection: Keep-Alive\r\n"
19072 "Content-Length: 6\r\n\r\n"
19073 "Pickle"),
19074 };
19075
19076 // Successful retry
19077 MockRead data_reads2[] = {
19078 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
19079 MockRead("world"),
19080 MockRead(ASYNC, OK),
19081 };
19082
19083 StaticSocketDataProvider data1(data_reads1, data_writes1);
19084 StaticSocketDataProvider data2(data_reads2, base::span<MockWrite>());
19085 session_deps_.socket_factory->AddSocketDataProvider(&data1);
19086 session_deps_.socket_factory->AddSocketDataProvider(&data2);
19087
19088 SSLSocketDataProvider ssl1(ASYNC, OK);
19089 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
19090 SSLSocketDataProvider ssl2(ASYNC, OK);
19091 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
19092
19093 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19094 auto trans1 =
19095 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19096
19097 TestCompletionCallback callback1;
19098
19099 int rv = trans1->Start(&request_, callback1.callback(), NetLogWithSource());
19100 EXPECT_THAT(callback1.GetResult(rv), IsOk());
19101
19102 std::string response_data;
19103 ASSERT_THAT(ReadTransaction(trans1.get(), &response_data), IsOk());
19104 EXPECT_EQ("hello", response_data);
19105
19106 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
19107
19108 auto trans2 =
19109 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19110
19111 TestCompletionCallback callback2;
19112
19113 rv = trans2->Start(&request_, callback2.callback(), NetLogWithSource());
19114 EXPECT_THAT(callback2.GetResult(rv), IsOk());
19115
19116 ASSERT_THAT(ReadTransaction(trans2.get(), &response_data), IsOk());
19117 EXPECT_EQ("world", response_data);
19118
19119 trans1.reset();
19120 trans2.reset();
19121
19122 // One 200 report from first request, then a 408 report from
19123 // the second request, then a 200 report from the successful retry.
19124 ASSERT_EQ(3u, network_error_logging_service()->errors().size());
19125
19126 // Check error report contents
19127 CheckReport(0 /* index */, 200 /* status_code */, OK);
19128 CheckReport(1 /* index */, 408 /* status_code */, OK);
19129 CheckReport(2 /* index */, 200 /* status_code */, OK);
19130}
19131
19132TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
19133 CreateReportRetry421WithoutConnectionPooling) {
19134 // Two hosts resolve to the same IP address.
19135 const std::string ip_addr = "1.2.3.4";
19136 IPAddress ip;
19137 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
19138 IPEndPoint peer_addr = IPEndPoint(ip, 443);
19139
19140 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
19141 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
19142 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
19143
19144 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19145
19146 // Two requests on the first connection.
19147 spdy::SpdySerializedFrame req1(
19148 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
19149 spdy_util_.UpdateWithStreamDestruction(1);
19150 spdy::SpdySerializedFrame req2(
19151 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
19152 spdy::SpdySerializedFrame rst(
19153 spdy_util_.ConstructSpdyRstStream(3, spdy::ERROR_CODE_CANCEL));
19154 MockWrite writes1[] = {
19155 CreateMockWrite(req1, 0),
19156 CreateMockWrite(req2, 3),
19157 CreateMockWrite(rst, 6),
19158 };
19159
19160 // The first one succeeds, the second gets error 421 Misdirected Request.
19161 spdy::SpdySerializedFrame resp1(
19162 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
19163 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
19164 spdy::SpdyHeaderBlock response_headers;
19165 response_headers[spdy::kHttp2StatusHeader] = "421";
19166 spdy::SpdySerializedFrame resp2(
19167 spdy_util_.ConstructSpdyReply(3, std::move(response_headers)));
19168 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
19169 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
19170
19171 MockConnect connect1(ASYNC, OK, peer_addr);
19172 SequencedSocketData data1(connect1, reads1, writes1);
19173 session_deps_.socket_factory->AddSocketDataProvider(&data1);
19174
19175 AddSSLSocketData();
19176
19177 // Retry the second request on a second connection.
19178 SpdyTestUtil spdy_util2;
19179 spdy::SpdySerializedFrame req3(
19180 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
19181 MockWrite writes2[] = {
19182 CreateMockWrite(req3, 0),
19183 };
19184
19185 spdy::SpdySerializedFrame resp3(
19186 spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
19187 spdy::SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
19188 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
19189 MockRead(ASYNC, 0, 3)};
19190
19191 MockConnect connect2(ASYNC, OK, peer_addr);
19192 SequencedSocketData data2(connect2, reads2, writes2);
19193 session_deps_.socket_factory->AddSocketDataProvider(&data2);
19194
19195 AddSSLSocketData();
19196
19197 // Preload mail.example.org into HostCache.
Eric Orthf4db66a2019-02-19 21:35:3319198 int rv = session_deps_.host_resolver->LoadIntoCache(
19199 HostPortPair("mail.example.com", 443), base::nullopt);
19200 EXPECT_THAT(rv, IsOk());
Lily Chenfec60d92019-01-24 01:16:4219201
19202 HttpRequestInfo request1;
19203 request1.method = "GET";
19204 request1.url = GURL("https://www.example.org/");
19205 request1.load_flags = 0;
19206 request1.traffic_annotation =
19207 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19208 auto trans1 =
19209 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19210
Eric Orthf4db66a2019-02-19 21:35:3319211 TestCompletionCallback callback;
Lily Chenfec60d92019-01-24 01:16:4219212 rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
19213 EXPECT_THAT(callback.GetResult(rv), IsOk());
19214
19215 const HttpResponseInfo* response = trans1->GetResponseInfo();
19216 ASSERT_TRUE(response);
19217 ASSERT_TRUE(response->headers);
19218 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
19219 EXPECT_TRUE(response->was_fetched_via_spdy);
19220 EXPECT_TRUE(response->was_alpn_negotiated);
19221 std::string response_data;
19222 ASSERT_THAT(ReadTransaction(trans1.get(), &response_data), IsOk());
19223 EXPECT_EQ("hello!", response_data);
19224
19225 trans1.reset();
19226
19227 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
19228
19229 HttpRequestInfo request2;
19230 request2.method = "GET";
19231 request2.url = GURL("https://mail.example.org/");
19232 request2.load_flags = 0;
19233 request2.traffic_annotation =
19234 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19235 auto trans2 =
19236 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19237
19238 BoundTestNetLog log;
19239 rv = trans2->Start(&request2, callback.callback(), log.bound());
19240 EXPECT_THAT(callback.GetResult(rv), IsOk());
19241
19242 response = trans2->GetResponseInfo();
19243 ASSERT_TRUE(response);
19244 ASSERT_TRUE(response->headers);
19245 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
19246 EXPECT_TRUE(response->was_fetched_via_spdy);
19247 EXPECT_TRUE(response->was_alpn_negotiated);
19248 ASSERT_THAT(ReadTransaction(trans2.get(), &response_data), IsOk());
19249 EXPECT_EQ("hello!", response_data);
19250
19251 trans2.reset();
19252
19253 // One 200 report from the first request, then a 421 report from the
19254 // second request, then a 200 report from the successful retry.
19255 ASSERT_EQ(3u, network_error_logging_service()->errors().size());
19256
19257 // Check error report contents
19258 const NetworkErrorLoggingService::RequestDetails& error1 =
19259 network_error_logging_service()->errors()[0];
19260 EXPECT_EQ(GURL("https://www.example.org/"), error1.uri);
19261 EXPECT_TRUE(error1.referrer.is_empty());
19262 EXPECT_EQ("", error1.user_agent);
19263 EXPECT_EQ(ip, error1.server_ip);
19264 EXPECT_EQ("h2", error1.protocol);
19265 EXPECT_EQ("GET", error1.method);
19266 EXPECT_EQ(200, error1.status_code);
19267 EXPECT_EQ(OK, error1.type);
19268 EXPECT_EQ(0, error1.reporting_upload_depth);
19269
19270 const NetworkErrorLoggingService::RequestDetails& error2 =
19271 network_error_logging_service()->errors()[1];
19272 EXPECT_EQ(GURL("https://mail.example.org/"), error2.uri);
19273 EXPECT_TRUE(error2.referrer.is_empty());
19274 EXPECT_EQ("", error2.user_agent);
19275 EXPECT_EQ(ip, error2.server_ip);
19276 EXPECT_EQ("h2", error2.protocol);
19277 EXPECT_EQ("GET", error2.method);
19278 EXPECT_EQ(421, error2.status_code);
19279 EXPECT_EQ(OK, error2.type);
19280 EXPECT_EQ(0, error2.reporting_upload_depth);
19281
19282 const NetworkErrorLoggingService::RequestDetails& error3 =
19283 network_error_logging_service()->errors()[2];
19284 EXPECT_EQ(GURL("https://mail.example.org/"), error3.uri);
19285 EXPECT_TRUE(error3.referrer.is_empty());
19286 EXPECT_EQ("", error3.user_agent);
19287 EXPECT_EQ(ip, error3.server_ip);
19288 EXPECT_EQ("h2", error3.protocol);
19289 EXPECT_EQ("GET", error3.method);
19290 EXPECT_EQ(200, error3.status_code);
19291 EXPECT_EQ(OK, error3.type);
19292 EXPECT_EQ(0, error3.reporting_upload_depth);
Douglas Creageref5eecdc2018-11-09 20:50:3619293}
19294
Lily Chend3930e72019-03-01 19:31:1119295TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
19296 CreateReportCancelAfterStart) {
19297 StaticSocketDataProvider data;
19298 data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_IO_PENDING));
19299 session_deps_.socket_factory->AddSocketDataProvider(&data);
19300
19301 TestCompletionCallback callback;
19302 auto session = CreateSession(&session_deps_);
19303 auto trans =
19304 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19305 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
19306 EXPECT_EQ(rv, ERR_IO_PENDING);
19307
19308 // Cancel after start.
19309 trans.reset();
19310
19311 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
19312 CheckReport(0 /* index */, 0 /* status_code */, ERR_ABORTED,
19313 IPAddress() /* server_ip */);
19314}
19315
19316TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
19317 CreateReportCancelBeforeReadingBody) {
19318 std::string extra_header_string = extra_headers_.ToString();
19319 MockWrite data_writes[] = {
19320 MockWrite("GET / HTTP/1.1\r\n"
19321 "Host: www.example.org\r\n"
19322 "Connection: keep-alive\r\n"),
19323 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
19324 };
19325 MockRead data_reads[] = {
19326 MockRead("HTTP/1.0 200 OK\r\n"),
19327 MockRead("Content-Length: 100\r\n\r\n"), // Body is never read.
19328 };
19329
19330 StaticSocketDataProvider data(data_reads, data_writes);
19331 session_deps_.socket_factory->AddSocketDataProvider(&data);
19332
19333 SSLSocketDataProvider ssl(ASYNC, OK);
19334 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
19335
19336 TestCompletionCallback callback;
19337 auto session = CreateSession(&session_deps_);
19338 auto trans =
19339 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19340 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
19341 EXPECT_THAT(callback.GetResult(rv), IsOk());
19342
19343 const HttpResponseInfo* response = trans->GetResponseInfo();
19344 ASSERT_TRUE(response);
19345
19346 EXPECT_TRUE(response->headers);
19347 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
19348
19349 // Cancel before reading the body.
19350 trans.reset();
19351
19352 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
19353 CheckReport(0 /* index */, 200 /* status_code */, ERR_ABORTED);
19354}
19355
Lily Chen00196ab62018-12-04 19:52:2919356TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, DontCreateReportHttp) {
19357 base::HistogramTester histograms;
19358 RequestPolicy();
19359 EXPECT_EQ(1u, network_error_logging_service()->headers().size());
19360 EXPECT_EQ(1u, network_error_logging_service()->errors().size());
19361
19362 // Make HTTP request
19363 std::string extra_header_string = extra_headers_.ToString();
19364 MockRead data_reads[] = {
19365 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
19366 MockRead("hello world"),
19367 MockRead(SYNCHRONOUS, OK),
19368 };
19369 MockWrite data_writes[] = {
19370 MockWrite("GET / HTTP/1.1\r\n"
19371 "Host: www.example.org\r\n"
19372 "Connection: keep-alive\r\n"),
19373 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
19374 };
19375
Lily Chend3930e72019-03-01 19:31:1119376 StaticSocketDataProvider data(data_reads, data_writes);
19377 session_deps_.socket_factory->AddSocketDataProvider(&data);
Lily Chen00196ab62018-12-04 19:52:2919378
Lily Chenfec60d92019-01-24 01:16:4219379 // Insecure url
19380 url_ = "http://www.example.org/";
19381 request_.url = GURL(url_);
19382
Lily Chen00196ab62018-12-04 19:52:2919383 TestCompletionCallback callback;
19384 auto session = CreateSession(&session_deps_);
Lily Chenfec60d92019-01-24 01:16:4219385 auto trans =
19386 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19387 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
19388 EXPECT_THAT(callback.GetResult(rv), IsOk());
19389
19390 std::string response_data;
19391 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
19392 EXPECT_EQ("hello world", response_data);
Lily Chen00196ab62018-12-04 19:52:2919393
19394 // Insecure request does not generate a report
19395 histograms.ExpectBucketCount(
19396 NetworkErrorLoggingService::kRequestOutcomeHistogram,
Tsuyoshi Horo0b042232019-03-06 01:11:0519397 NetworkErrorLoggingService::RequestOutcome::kDiscardedInsecureOrigin, 1);
Lily Chen00196ab62018-12-04 19:52:2919398
19399 EXPECT_EQ(1u, network_error_logging_service()->errors().size());
19400}
19401
19402TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
19403 DontCreateReportHttpError) {
19404 base::HistogramTester histograms;
19405 RequestPolicy();
19406 EXPECT_EQ(1u, network_error_logging_service()->headers().size());
19407 EXPECT_EQ(1u, network_error_logging_service()->errors().size());
19408
19409 // Make HTTP request that fails
19410 MockRead data_reads[] = {
19411 MockRead("hello world"),
19412 MockRead(SYNCHRONOUS, OK),
19413 };
19414
19415 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
19416 session_deps_.socket_factory->AddSocketDataProvider(&data);
19417
Lily Chenfec60d92019-01-24 01:16:4219418 url_ = "http://www.originwithoutpolicy.com:2000/";
19419 request_.url = GURL(url_);
19420
Lily Chen00196ab62018-12-04 19:52:2919421 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19422
Lily Chen00196ab62018-12-04 19:52:2919423 auto trans =
19424 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Lily Chen00196ab62018-12-04 19:52:2919425 TestCompletionCallback callback;
Lily Chenfec60d92019-01-24 01:16:4219426 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
Lily Chen00196ab62018-12-04 19:52:2919427 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_INVALID_HTTP_RESPONSE));
19428
19429 // Insecure request does not generate a report, regardless of existence of a
19430 // policy for the origin.
19431 histograms.ExpectBucketCount(
19432 NetworkErrorLoggingService::kRequestOutcomeHistogram,
Tsuyoshi Horo0b042232019-03-06 01:11:0519433 NetworkErrorLoggingService::RequestOutcome::kDiscardedInsecureOrigin, 1);
Lily Chen00196ab62018-12-04 19:52:2919434
19435 EXPECT_EQ(1u, network_error_logging_service()->errors().size());
19436}
19437
Lily Chen90ae93cc2019-02-14 01:15:3919438// Don't report on proxy auth challenges, don't report if connecting through a
19439// proxy.
19440TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, DontCreateReportProxy) {
19441 HttpRequestInfo request;
19442 request.method = "GET";
19443 request.url = GURL("https://www.example.org/");
19444 request.traffic_annotation =
19445 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19446
19447 // Configure against proxy server "myproxy:70".
19448 session_deps_.proxy_resolution_service =
19449 ProxyResolutionService::CreateFixedFromPacResult(
19450 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
19451 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19452
19453 // Since we have proxy, should try to establish tunnel.
19454 MockWrite data_writes1[] = {
19455 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
19456 "Host: www.example.org:443\r\n"
19457 "Proxy-Connection: keep-alive\r\n\r\n"),
19458 };
19459
19460 // The proxy responds to the connect with a 407, using a non-persistent
19461 // connection.
19462 MockRead data_reads1[] = {
19463 // No credentials.
19464 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
19465 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
19466 MockRead("Proxy-Connection: close\r\n\r\n"),
19467 };
19468
19469 MockWrite data_writes2[] = {
19470 // After calling trans->RestartWithAuth(), this is the request we should
19471 // be issuing -- the final header line contains the credentials.
19472 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
19473 "Host: www.example.org:443\r\n"
19474 "Proxy-Connection: keep-alive\r\n"
19475 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
19476
19477 MockWrite("GET / HTTP/1.1\r\n"
19478 "Host: www.example.org\r\n"
19479 "Connection: keep-alive\r\n\r\n"),
19480 };
19481
19482 MockRead data_reads2[] = {
19483 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
19484
19485 MockRead("HTTP/1.1 200 OK\r\n"),
19486 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
19487 MockRead("Content-Length: 5\r\n\r\n"),
19488 MockRead(SYNCHRONOUS, "hello"),
19489 };
19490
19491 StaticSocketDataProvider data1(data_reads1, data_writes1);
19492 session_deps_.socket_factory->AddSocketDataProvider(&data1);
19493 StaticSocketDataProvider data2(data_reads2, data_writes2);
19494 session_deps_.socket_factory->AddSocketDataProvider(&data2);
19495 SSLSocketDataProvider ssl(ASYNC, OK);
19496 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
19497
19498 TestCompletionCallback callback1;
19499
19500 auto trans =
19501 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19502
19503 int rv = trans->Start(&request, callback1.callback(), NetLogWithSource());
19504 EXPECT_THAT(callback1.GetResult(rv), IsOk());
19505
19506 const HttpResponseInfo* response = trans->GetResponseInfo();
19507 EXPECT_EQ(407, response->headers->response_code());
19508
19509 std::string response_data;
19510 rv = ReadTransaction(trans.get(), &response_data);
19511 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
19512
19513 // No NEL report is generated for the 407.
19514 EXPECT_EQ(0u, network_error_logging_service()->errors().size());
19515
19516 TestCompletionCallback callback2;
19517
19518 rv =
19519 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
19520 EXPECT_THAT(callback2.GetResult(rv), IsOk());
19521
19522 response = trans->GetResponseInfo();
19523 EXPECT_EQ(200, response->headers->response_code());
19524
19525 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
19526 EXPECT_EQ("hello", response_data);
19527
19528 trans.reset();
19529
19530 // No NEL report is generated because we are behind a proxy.
19531 EXPECT_EQ(0u, network_error_logging_service()->errors().size());
19532}
19533
Douglas Creageref5eecdc2018-11-09 20:50:3619534TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
19535 ReportContainsUploadDepth) {
19536 reporting_upload_depth_ = 7;
Lily Chenfec60d92019-01-24 01:16:4219537 request_.reporting_upload_depth = reporting_upload_depth_;
Douglas Creageref5eecdc2018-11-09 20:50:3619538 RequestPolicy();
19539 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
Lily Chenfec60d92019-01-24 01:16:4219540 const NetworkErrorLoggingService::RequestDetails& error =
19541 network_error_logging_service()->errors()[0];
Douglas Creageref5eecdc2018-11-09 20:50:3619542 EXPECT_EQ(7, error.reporting_upload_depth);
19543}
19544
Lily Chenfec60d92019-01-24 01:16:4219545TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, ReportElapsedTime) {
19546 std::string extra_header_string = extra_headers_.ToString();
19547 static const base::TimeDelta kSleepDuration =
19548 base::TimeDelta::FromMilliseconds(10);
19549
19550 std::vector<MockWrite> data_writes = {
19551 MockWrite(ASYNC, 0,
19552 "GET / HTTP/1.1\r\n"
19553 "Host: www.example.org\r\n"
19554 "Connection: keep-alive\r\n"),
19555 MockWrite(ASYNC, 1, extra_header_string.data()),
19556 };
19557
19558 std::vector<MockRead> data_reads = {
19559 // Write one byte of the status line, followed by a pause.
19560 MockRead(ASYNC, 2, "H"),
19561 MockRead(ASYNC, ERR_IO_PENDING, 3),
19562 MockRead(ASYNC, 4, "TTP/1.1 200 OK\r\n\r\n"),
19563 MockRead(ASYNC, 5, "hello world"),
19564 MockRead(SYNCHRONOUS, OK, 6),
19565 };
19566
19567 SequencedSocketData data(data_reads, data_writes);
19568 session_deps_.socket_factory->AddSocketDataProvider(&data);
19569
19570 SSLSocketDataProvider ssl(ASYNC, OK);
19571 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
19572
19573 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19574
19575 auto trans =
19576 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19577
19578 TestCompletionCallback callback;
19579
19580 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
19581 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
19582
19583 data.RunUntilPaused();
19584 ASSERT_TRUE(data.IsPaused());
19585 FastForwardBy(kSleepDuration);
19586 data.Resume();
19587
19588 EXPECT_THAT(callback.GetResult(rv), IsOk());
19589
19590 std::string response_data;
19591 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
19592 EXPECT_EQ("hello world", response_data);
19593
19594 trans.reset();
19595
Douglas Creageref5eecdc2018-11-09 20:50:3619596 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
Lily Chenfec60d92019-01-24 01:16:4219597
19598 CheckReport(0 /* index */, 200 /* status_code */, OK);
19599
19600 const NetworkErrorLoggingService::RequestDetails& error =
19601 network_error_logging_service()->errors()[0];
19602
19603 // Sanity-check elapsed time in error report
19604 EXPECT_EQ(kSleepDuration, error.elapsed_time);
Douglas Creageref5eecdc2018-11-09 20:50:3619605}
Lily Chenfec60d92019-01-24 01:16:4219606
Douglas Creager3cb042052018-11-06 23:08:5219607#endif // BUILDFLAG(ENABLE_REPORTING)
19608
[email protected]89ceba9a2009-03-21 03:46:0619609} // namespace net