blob: 53e1a85638d2925a006958056f06439f2bf30d40 [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"
[email protected]a34f61ee2014-03-18 20:59:4925#include "base/run_loop.h"
Avi Drissman4365a4782018-12-28 19:26:2426#include "base/stl_util.h"
Bence Békyd74f4382018-02-20 18:26:1927#include "base/strings/string_piece.h"
[email protected]125ef482013-06-11 18:32:4728#include "base/strings/string_util.h"
[email protected]750b2f3c2013-06-07 18:41:0529#include "base/strings/utf_string_conversions.h"
Douglas Creager3cb042052018-11-06 23:08:5230#include "base/test/metrics/histogram_tester.h"
Matt Menkeecfecfc72019-02-05 19:15:2831#include "base/test/scoped_task_environment.h"
Douglas Creager134b52e2018-11-09 18:00:1432#include "base/test/simple_test_clock.h"
33#include "base/test/simple_test_tick_clock.h"
[email protected]f36a8132011-09-02 18:36:3334#include "base/test/test_file_util.h"
gabf767595f2016-05-11 18:50:3535#include "base/threading/thread_task_runner_handle.h"
[email protected]277d5942010-08-11 21:02:3536#include "net/base/auth.h"
mmenkecbc2b712014-10-09 20:29:0737#include "net/base/chunked_upload_data_stream.h"
Bence Békya25e3f72018-02-13 21:13:3938#include "net/base/completion_once_callback.h"
mmenkecbc2b712014-10-09 20:29:0739#include "net/base/elements_upload_data_stream.h"
[email protected]58e32bb2013-01-21 18:23:2540#include "net/base/load_timing_info.h"
41#include "net/base/load_timing_info_test_util.h"
Adam Rice425cf122015-01-19 06:18:2442#include "net/base/net_errors.h"
tbansal28e68f82016-02-04 02:56:1543#include "net/base/proxy_delegate.h"
Lily Houghton582d4622018-01-22 22:43:4044#include "net/base/proxy_server.h"
[email protected]ac790b42009-12-02 04:31:3145#include "net/base/request_priority.h"
initial.commit586acc5fe2008-07-26 22:42:5246#include "net/base/test_completion_callback.h"
tbansal28e68f82016-02-04 02:56:1547#include "net/base/test_proxy_delegate.h"
[email protected]b2d26cfd2012-12-11 10:36:0648#include "net/base/upload_bytes_element_reader.h"
[email protected]d98961652012-09-11 20:27:2149#include "net/base/upload_file_element_reader.h"
Bence Béky230ac612017-08-30 19:17:0850#include "net/cert/cert_status_flags.h"
[email protected]6e7845ae2013-03-29 21:48:1151#include "net/cert/mock_cert_verifier.h"
[email protected]bc71b8772013-04-10 20:55:1652#include "net/dns/host_cache.h"
[email protected]f2cb3cf2013-03-21 01:40:5353#include "net/dns/mock_host_resolver.h"
[email protected]df41d0d82014-03-13 00:43:2454#include "net/http/http_auth_challenge_tokenizer.h"
[email protected]3c32c5f2010-05-18 15:18:1255#include "net/http/http_auth_handler_digest.h"
[email protected]3fd9dae2010-06-21 11:39:0056#include "net/http/http_auth_handler_mock.h"
[email protected]385a4672009-03-11 22:21:2957#include "net/http/http_auth_handler_ntlm.h"
aberentbba302d2015-12-03 10:20:1958#include "net/http/http_auth_scheme.h"
[email protected]0877e3d2009-10-17 22:29:5759#include "net/http/http_basic_stream.h"
initial.commit586acc5fe2008-07-26 22:42:5260#include "net/http/http_network_session.h"
[email protected]87bfa3f2010-09-30 14:54:5661#include "net/http/http_network_session_peer.h"
Adam Rice425cf122015-01-19 06:18:2462#include "net/http/http_request_headers.h"
mmenke5f94fda2016-06-02 20:54:1363#include "net/http/http_response_info.h"
[email protected]17291a022011-10-10 07:32:5364#include "net/http/http_server_properties_impl.h"
[email protected]0877e3d2009-10-17 22:29:5765#include "net/http/http_stream.h"
[email protected]8e6441ca2010-08-19 05:56:3866#include "net/http/http_stream_factory.h"
[email protected]c41737d2014-05-14 07:47:1967#include "net/http/http_transaction_test_util.h"
eroman87c53d62015-04-02 06:51:0768#include "net/log/net_log.h"
mikecirone8b85c432016-09-08 19:11:0069#include "net/log/net_log_event_type.h"
mikecironef22f9812016-10-04 03:40:1970#include "net/log/net_log_source.h"
vishal.b62985ca92015-04-17 08:45:5171#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4672#include "net/log/test_net_log_entry.h"
73#include "net/log/test_net_log_util.h"
Lily Houghton582d4622018-01-22 22:43:4074#include "net/proxy_resolution/mock_proxy_resolver.h"
75#include "net/proxy_resolution/proxy_config_service_fixed.h"
76#include "net/proxy_resolution/proxy_info.h"
Lily Houghtonffe89daa02018-03-09 18:30:0377#include "net/proxy_resolution/proxy_resolution_service.h"
Lily Houghton582d4622018-01-22 22:43:4078#include "net/proxy_resolution/proxy_resolver.h"
79#include "net/proxy_resolution/proxy_resolver_factory.h"
[email protected]f7984fc62009-06-22 23:26:4480#include "net/socket/client_socket_factory.h"
mmenked3641e12016-01-28 16:06:1581#include "net/socket/client_socket_pool.h"
[email protected]483fa202013-05-14 01:07:0382#include "net/socket/client_socket_pool_manager.h"
ttuttle1f2d7e92015-04-28 16:17:4783#include "net/socket/connection_attempts.h"
[email protected]a42dbd142011-11-17 16:42:0284#include "net/socket/mock_client_socket_pool_manager.h"
[email protected]bb88e1d32013-05-03 23:11:0785#include "net/socket/next_proto.h"
Paul Jensena457017a2018-01-19 23:52:0486#include "net/socket/socket_tag.h"
[email protected]f7984fc62009-06-22 23:26:4487#include "net/socket/socket_test_util.h"
Matt Menke4b412da2019-01-25 19:31:1288#include "net/socket/socks_connect_job.h"
[email protected]f7984fc62009-06-22 23:26:4489#include "net/socket/ssl_client_socket.h"
Bence Béky94658bf2018-05-11 19:22:5890#include "net/spdy/spdy_session.h"
91#include "net/spdy/spdy_session_pool.h"
92#include "net/spdy/spdy_test_util_common.h"
nharperb7441ef2016-01-25 23:54:1493#include "net/ssl/default_channel_id_store.h"
[email protected]536fd0b2013-03-14 17:41:5794#include "net/ssl/ssl_cert_request_info.h"
[email protected]e86839fd2013-08-14 18:29:0395#include "net/ssl/ssl_config_service.h"
[email protected]536fd0b2013-03-14 17:41:5796#include "net/ssl/ssl_info.h"
svaldez7872fd02015-11-19 21:10:5497#include "net/ssl/ssl_private_key.h"
[email protected]6e7845ae2013-03-29 21:48:1198#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:0199#include "net/test/gtest_util.h"
rsleevia69c79a2016-06-22 03:28:43100#include "net/test/test_data_directory.h"
Bence Béky98447b12018-05-08 03:14:01101#include "net/test/test_with_scoped_task_environment.h"
Victor Vasiliev27cc7712019-01-24 11:50:14102#include "net/third_party/quiche/src/spdy/core/spdy_framer.h"
[email protected]baee31a2018-01-18 06:10:23103#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
[email protected]831e4a32013-11-14 02:14:44104#include "net/websockets/websocket_handshake_stream_base.h"
Bence Békydca6bd92018-01-30 13:43:06105#include "net/websockets/websocket_test_util.h"
bncf4588402015-11-24 13:33:18106#include "testing/gmock/include/gmock/gmock.h"
initial.commit586acc5fe2008-07-26 22:42:52107#include "testing/gtest/include/gtest/gtest.h"
[email protected]23887f04f2008-12-02 19:20:15108#include "testing/platform_test.h"
[email protected]795cbf82013-07-22 09:37:27109#include "url/gurl.h"
initial.commit586acc5fe2008-07-26 22:42:52110
Zentaro Kavanagh5b27a6e22017-09-25 23:00:37111#if defined(NTLM_PORTABLE)
112#include "base/base64.h"
113#include "net/ntlm/ntlm_test_data.h"
114#endif
115
Douglas Creager3cb042052018-11-06 23:08:52116#if BUILDFLAG(ENABLE_REPORTING)
117#include "net/network_error_logging/network_error_logging_service.h"
118#include "net/network_error_logging/network_error_logging_test_util.h"
Douglas Creager134b52e2018-11-09 18:00:14119#include "net/reporting/reporting_cache.h"
120#include "net/reporting/reporting_client.h"
121#include "net/reporting/reporting_header_parser.h"
122#include "net/reporting/reporting_service.h"
123#include "net/reporting/reporting_test_util.h"
Douglas Creager3cb042052018-11-06 23:08:52124#endif // BUILDFLAG(ENABLE_REPORTING)
125
robpercival214763f2016-07-01 23:27:01126using net::test::IsError;
127using net::test::IsOk;
128
[email protected]ad65a3e2013-12-25 18:18:01129using base::ASCIIToUTF16;
130
initial.commit586acc5fe2008-07-26 22:42:52131//-----------------------------------------------------------------------------
132
ttuttle859dc7a2015-04-23 19:42:29133namespace net {
134
[email protected]13c8a092010-07-29 06:15:44135namespace {
136
[email protected]42cba2fb2013-03-29 19:58:57137const base::string16 kBar(ASCIIToUTF16("bar"));
138const base::string16 kBar2(ASCIIToUTF16("bar2"));
139const base::string16 kBar3(ASCIIToUTF16("bar3"));
140const base::string16 kBaz(ASCIIToUTF16("baz"));
141const base::string16 kFirst(ASCIIToUTF16("first"));
142const base::string16 kFoo(ASCIIToUTF16("foo"));
143const base::string16 kFoo2(ASCIIToUTF16("foo2"));
144const base::string16 kFoo3(ASCIIToUTF16("foo3"));
145const base::string16 kFou(ASCIIToUTF16("fou"));
146const base::string16 kSecond(ASCIIToUTF16("second"));
[email protected]42cba2fb2013-03-29 19:58:57147const base::string16 kWrongPassword(ASCIIToUTF16("wrongpassword"));
[email protected]13c8a092010-07-29 06:15:44148
bnc2df4b522016-07-08 18:17:43149const char kAlternativeServiceHttpHeader[] =
150 "Alt-Svc: h2=\"mail.example.org:443\"\r\n";
151
ttuttle859dc7a2015-04-23 19:42:29152int GetIdleSocketCountInTransportSocketPool(HttpNetworkSession* session) {
153 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
154 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02155}
156
ttuttle859dc7a2015-04-23 19:42:29157bool IsTransportSocketPoolStalled(HttpNetworkSession* session) {
158 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
159 ->IsStalled();
[email protected]043b68c82013-08-22 23:41:52160}
161
[email protected]f3da152d2012-06-02 01:00:57162// Takes in a Value created from a NetLogHttpResponseParameter, and returns
163// a JSONified list of headers as a single string. Uses single quotes instead
164// of double quotes for easier comparison. Returns false on failure.
[email protected]ea5ef4c2013-06-13 22:50:27165bool GetHeaders(base::DictionaryValue* params, std::string* headers) {
[email protected]f3da152d2012-06-02 01:00:57166 if (!params)
167 return false;
[email protected]ea5ef4c2013-06-13 22:50:27168 base::ListValue* header_list;
[email protected]f3da152d2012-06-02 01:00:57169 if (!params->GetList("headers", &header_list))
170 return false;
171 std::string double_quote_headers;
estade8d046462015-05-16 01:02:34172 base::JSONWriter::Write(*header_list, &double_quote_headers);
[email protected]466c9862013-12-03 22:05:28173 base::ReplaceChars(double_quote_headers, "\"", "'", headers);
[email protected]f3da152d2012-06-02 01:00:57174 return true;
175}
176
[email protected]029c83b62013-01-24 05:28:20177// Tests LoadTimingInfo in the case a socket is reused and no PAC script is
178// used.
ttuttle859dc7a2015-04-23 19:42:29179void TestLoadTimingReused(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20180 EXPECT_TRUE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19181 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]58e32bb2013-01-21 18:23:25182
[email protected]029c83b62013-01-24 05:28:20183 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
184 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
185
ttuttle859dc7a2015-04-23 19:42:29186 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20187 EXPECT_FALSE(load_timing_info.send_start.is_null());
[email protected]58e32bb2013-01-21 18:23:25188
189 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]58e32bb2013-01-21 18:23:25190
[email protected]3b23a222013-05-15 21:33:25191 // Set at a higher level.
[email protected]58e32bb2013-01-21 18:23:25192 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
193 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25194 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25195}
196
[email protected]029c83b62013-01-24 05:28:20197// Tests LoadTimingInfo in the case a new socket is used and no PAC script is
198// used.
ttuttle859dc7a2015-04-23 19:42:29199void TestLoadTimingNotReused(const LoadTimingInfo& load_timing_info,
[email protected]58e32bb2013-01-21 18:23:25200 int connect_timing_flags) {
[email protected]029c83b62013-01-24 05:28:20201 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19202 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20203
204 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
205 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
206
ttuttle859dc7a2015-04-23 19:42:29207 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
208 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20209 EXPECT_LE(load_timing_info.connect_timing.connect_end,
210 load_timing_info.send_start);
211
212 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20213
[email protected]3b23a222013-05-15 21:33:25214 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20215 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
216 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25217 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20218}
219
220// Tests LoadTimingInfo in the case a socket is reused and a PAC script is
221// used.
ttuttle859dc7a2015-04-23 19:42:29222void TestLoadTimingReusedWithPac(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20223 EXPECT_TRUE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19224 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20225
ttuttle859dc7a2015-04-23 19:42:29226 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20227
228 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
229 EXPECT_LE(load_timing_info.proxy_resolve_start,
230 load_timing_info.proxy_resolve_end);
231 EXPECT_LE(load_timing_info.proxy_resolve_end,
232 load_timing_info.send_start);
233 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20234
[email protected]3b23a222013-05-15 21:33:25235 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20236 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
237 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25238 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20239}
240
241// Tests LoadTimingInfo in the case a new socket is used and a PAC script is
242// used.
ttuttle859dc7a2015-04-23 19:42:29243void TestLoadTimingNotReusedWithPac(const LoadTimingInfo& load_timing_info,
[email protected]029c83b62013-01-24 05:28:20244 int connect_timing_flags) {
245 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19246 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20247
248 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
249 EXPECT_LE(load_timing_info.proxy_resolve_start,
250 load_timing_info.proxy_resolve_end);
251 EXPECT_LE(load_timing_info.proxy_resolve_end,
252 load_timing_info.connect_timing.connect_start);
ttuttle859dc7a2015-04-23 19:42:29253 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
254 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20255 EXPECT_LE(load_timing_info.connect_timing.connect_end,
256 load_timing_info.send_start);
257
258 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20259
[email protected]3b23a222013-05-15 21:33:25260 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20261 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
262 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25263 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25264}
265
Matt Menke2436b2f2018-12-11 18:07:11266// ProxyResolver that records URLs passed to it, and that can be told what
267// result to return.
268class CapturingProxyResolver : public ProxyResolver {
269 public:
270 CapturingProxyResolver()
271 : proxy_server_(ProxyServer::SCHEME_HTTP, HostPortPair("myproxy", 80)) {}
272 ~CapturingProxyResolver() override = default;
273
274 int GetProxyForURL(const GURL& url,
275 ProxyInfo* results,
276 CompletionOnceCallback callback,
277 std::unique_ptr<Request>* request,
278 const NetLogWithSource& net_log) override {
279 results->UseProxyServer(proxy_server_);
280 resolved_.push_back(url);
281 return OK;
282 }
283
284 // Sets whether the resolver should use direct connections, instead of a
285 // proxy.
286 void set_proxy_server(ProxyServer proxy_server) {
287 proxy_server_ = proxy_server;
288 }
289
290 const std::vector<GURL>& resolved() const { return resolved_; }
291
292 private:
293 std::vector<GURL> resolved_;
294
295 ProxyServer proxy_server_;
296
297 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
298};
299
300class CapturingProxyResolverFactory : public ProxyResolverFactory {
301 public:
302 explicit CapturingProxyResolverFactory(CapturingProxyResolver* resolver)
303 : ProxyResolverFactory(false), resolver_(resolver) {}
304
305 int CreateProxyResolver(const scoped_refptr<PacFileData>& pac_script,
306 std::unique_ptr<ProxyResolver>* resolver,
307 CompletionOnceCallback callback,
308 std::unique_ptr<Request>* request) override {
309 *resolver = std::make_unique<ForwardingProxyResolver>(resolver_);
310 return OK;
311 }
312
313 private:
314 ProxyResolver* resolver_;
315};
316
danakj1fd259a02016-04-16 03:17:09317std::unique_ptr<HttpNetworkSession> CreateSession(
mmenkee65e7af2015-10-13 17:16:42318 SpdySessionDependencies* session_deps) {
[email protected]c6bf8152012-12-02 07:43:34319 return SpdySessionDependencies::SpdyCreateSession(session_deps);
[email protected]e8d536192008-10-17 22:21:14320}
321
xunjieli96f2a402017-06-05 17:24:27322class FailingProxyResolverFactory : public ProxyResolverFactory {
323 public:
324 FailingProxyResolverFactory() : ProxyResolverFactory(false) {}
325
326 // ProxyResolverFactory override.
Lily Houghton99597862018-03-07 16:40:42327 int CreateProxyResolver(const scoped_refptr<PacFileData>& script_data,
328 std::unique_ptr<ProxyResolver>* result,
Bence Békycc5b88a2018-05-25 20:24:17329 CompletionOnceCallback callback,
Lily Houghton99597862018-03-07 16:40:42330 std::unique_ptr<Request>* request) override {
xunjieli96f2a402017-06-05 17:24:27331 return ERR_PAC_SCRIPT_FAILED;
332 }
333};
334
David Benjamin5cb91132018-04-06 05:54:49335class TestSSLConfigService : public SSLConfigService {
336 public:
337 explicit TestSSLConfigService(const SSLConfig& config) : config_(config) {}
Ryan Sleevib8449e02018-07-15 04:31:07338 ~TestSSLConfigService() override = default;
David Benjamin5cb91132018-04-06 05:54:49339
340 void GetSSLConfig(SSLConfig* config) override { *config = config_; }
341
Nick Harper89bc7212018-07-31 19:07:57342 bool CanShareConnectionWithClientCerts(
343 const std::string& hostname) const override {
344 return false;
345 }
346
David Benjamin5cb91132018-04-06 05:54:49347 private:
David Benjamin5cb91132018-04-06 05:54:49348 SSLConfig config_;
349};
350
[email protected]448d4ca52012-03-04 04:12:23351} // namespace
352
Bence Béky98447b12018-05-08 03:14:01353class HttpNetworkTransactionTest : public PlatformTest,
354 public WithScopedTaskEnvironment {
[email protected]483fa202013-05-14 01:07:03355 public:
bncd16676a2016-07-20 16:23:01356 ~HttpNetworkTransactionTest() override {
[email protected]483fa202013-05-14 01:07:03357 // Important to restore the per-pool limit first, since the pool limit must
358 // always be greater than group limit, and the tests reduce both limits.
359 ClientSocketPoolManager::set_max_sockets_per_pool(
360 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
361 ClientSocketPoolManager::set_max_sockets_per_group(
362 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
363 }
364
[email protected]e3ceb682011-06-28 23:55:46365 protected:
[email protected]23e482282013-06-14 16:08:02366 HttpNetworkTransactionTest()
Andrew Comminos517a92c2019-01-14 17:49:56367 : WithScopedTaskEnvironment(
368 base::test::ScopedTaskEnvironment::MainThreadType::IO_MOCK_TIME,
369 base::test::ScopedTaskEnvironment::NowSource::
370 MAIN_THREAD_MOCK_TIME),
371 ssl_(ASYNC, OK),
bnc032658ba2016-09-26 18:17:15372 old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
[email protected]483fa202013-05-14 01:07:03373 HttpNetworkSession::NORMAL_SOCKET_POOL)),
374 old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
375 HttpNetworkSession::NORMAL_SOCKET_POOL)) {
bnca86731e2017-04-17 12:31:28376 session_deps_.enable_http2_alternative_service = true;
[email protected]483fa202013-05-14 01:07:03377 }
[email protected]bb88e1d32013-05-03 23:11:07378
[email protected]e3ceb682011-06-28 23:55:46379 struct SimpleGetHelperResult {
380 int rv;
381 std::string status_line;
382 std::string response_data;
sclittlefb249892015-09-10 21:33:22383 int64_t total_received_bytes;
384 int64_t total_sent_bytes;
[email protected]58e32bb2013-01-21 18:23:25385 LoadTimingInfo load_timing_info;
ttuttle1f2d7e92015-04-28 16:17:47386 ConnectionAttempts connection_attempts;
ttuttled9dbc652015-09-29 20:00:59387 IPEndPoint remote_endpoint_after_start;
[email protected]e3ceb682011-06-28 23:55:46388 };
389
dcheng67be2b1f2014-10-27 21:47:29390 void SetUp() override {
[email protected]0b0bf032010-09-21 18:08:50391 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55392 base::RunLoop().RunUntilIdle();
Andrew Comminos517a92c2019-01-14 17:49:56393 // Set an initial delay to ensure that the first call to TimeTicks::Now()
394 // before incrementing the counter does not return a null value.
395 FastForwardBy(TimeDelta::FromSeconds(1));
[email protected]2ff8b312010-04-26 22:20:54396 }
397
dcheng67be2b1f2014-10-27 21:47:29398 void TearDown() override {
[email protected]0b0bf032010-09-21 18:08:50399 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55400 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09401 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:55402 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09403 PlatformTest::TearDown();
[email protected]0b0bf032010-09-21 18:08:50404 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55405 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09406 }
407
Andrew Comminos1f2ff1cc2018-12-14 05:22:38408 void Check100ResponseTiming(bool use_spdy);
409
[email protected]202965992011-12-07 23:04:51410 // Either |write_failure| specifies a write failure or |read_failure|
411 // specifies a read failure when using a reused socket. In either case, the
412 // failure should cause the network transaction to resend the request, and the
413 // other argument should be NULL.
414 void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
415 const MockRead* read_failure);
initial.commit586acc5fe2008-07-26 22:42:52416
[email protected]a34f61ee2014-03-18 20:59:49417 // Either |write_failure| specifies a write failure or |read_failure|
418 // specifies a read failure when using a reused socket. In either case, the
419 // failure should cause the network transaction to resend the request, and the
420 // other argument should be NULL.
421 void PreconnectErrorResendRequestTest(const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:10422 const MockRead* read_failure,
423 bool use_spdy);
[email protected]a34f61ee2014-03-18 20:59:49424
Ryan Sleevib8d7ea02018-05-07 20:01:01425 SimpleGetHelperResult SimpleGetHelperForData(
426 base::span<StaticSocketDataProvider*> providers) {
[email protected]ff007e162009-05-23 09:13:15427 SimpleGetHelperResult out;
initial.commit586acc5fe2008-07-26 22:42:52428
[email protected]ff007e162009-05-23 09:13:15429 HttpRequestInfo request;
430 request.method = "GET";
bncce36dca22015-04-21 22:11:23431 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:10432 request.traffic_annotation =
433 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:52434
vishal.b62985ca92015-04-17 08:45:51435 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:07436 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:09437 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16438 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:27439
Ryan Sleevib8d7ea02018-05-07 20:01:01440 for (auto* provider : providers) {
441 session_deps_.socket_factory->AddSocketDataProvider(provider);
[email protected]5a60c8b2011-10-19 20:14:29442 }
initial.commit586acc5fe2008-07-26 22:42:52443
[email protected]49639fa2011-12-20 23:22:41444 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52445
eroman24bc6a12015-05-06 19:55:48446 EXPECT_TRUE(log.bound().IsCapturing());
bnc691fda62016-08-12 00:43:16447 int rv = trans.Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:01448 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:52449
[email protected]ff007e162009-05-23 09:13:15450 out.rv = callback.WaitForResult();
bnc691fda62016-08-12 00:43:16451 out.total_received_bytes = trans.GetTotalReceivedBytes();
452 out.total_sent_bytes = trans.GetTotalSentBytes();
[email protected]58e32bb2013-01-21 18:23:25453
454 // Even in the failure cases that use this function, connections are always
455 // successfully established before the error.
bnc691fda62016-08-12 00:43:16456 EXPECT_TRUE(trans.GetLoadTimingInfo(&out.load_timing_info));
[email protected]58e32bb2013-01-21 18:23:25457 TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
458
[email protected]ff007e162009-05-23 09:13:15459 if (out.rv != OK)
460 return out;
461
bnc691fda62016-08-12 00:43:16462 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50463 // Can't use ASSERT_* inside helper functions like this, so
464 // return an error.
wezca1070932016-05-26 20:30:52465 if (!response || !response->headers) {
[email protected]fe2255a2011-09-20 19:37:50466 out.rv = ERR_UNEXPECTED;
467 return out;
468 }
[email protected]ff007e162009-05-23 09:13:15469 out.status_line = response->headers->GetStatusLine();
470
[email protected]80a09a82012-11-16 17:40:06471 EXPECT_EQ("127.0.0.1", response->socket_address.host());
472 EXPECT_EQ(80, response->socket_address.port());
[email protected]6d81b482011-02-22 19:47:19473
ttuttled9dbc652015-09-29 20:00:59474 bool got_endpoint =
bnc691fda62016-08-12 00:43:16475 trans.GetRemoteEndpoint(&out.remote_endpoint_after_start);
ttuttled9dbc652015-09-29 20:00:59476 EXPECT_EQ(got_endpoint,
477 out.remote_endpoint_after_start.address().size() > 0);
478
bnc691fda62016-08-12 00:43:16479 rv = ReadTransaction(&trans, &out.response_data);
robpercival214763f2016-07-01 23:27:01480 EXPECT_THAT(rv, IsOk());
[email protected]b2fcd0e2010-12-01 15:19:40481
mmenke43758e62015-05-04 21:09:46482 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40483 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:39484 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00485 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
486 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:39487 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00488 entries, pos, NetLogEventType::HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
489 NetLogEventPhase::NONE);
[email protected]ff007e162009-05-23 09:13:15490
[email protected]f3da152d2012-06-02 01:00:57491 std::string line;
492 EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
493 EXPECT_EQ("GET / HTTP/1.1\r\n", line);
494
[email protected]79e1fd62013-06-20 06:50:04495 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:16496 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:04497 std::string value;
498 EXPECT_TRUE(request_headers.GetHeader("Host", &value));
bncce36dca22015-04-21 22:11:23499 EXPECT_EQ("www.example.org", value);
[email protected]79e1fd62013-06-20 06:50:04500 EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
501 EXPECT_EQ("keep-alive", value);
502
503 std::string response_headers;
504 EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
bncce36dca22015-04-21 22:11:23505 EXPECT_EQ("['Host: www.example.org','Connection: keep-alive']",
[email protected]79e1fd62013-06-20 06:50:04506 response_headers);
[email protected]3deb9a52010-11-11 00:24:40507
bnc691fda62016-08-12 00:43:16508 out.total_received_bytes = trans.GetTotalReceivedBytes();
sclittlefb249892015-09-10 21:33:22509 // The total number of sent bytes should not have changed.
bnc691fda62016-08-12 00:43:16510 EXPECT_EQ(out.total_sent_bytes, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:22511
bnc691fda62016-08-12 00:43:16512 trans.GetConnectionAttempts(&out.connection_attempts);
[email protected]aecfbf22008-10-16 02:02:47513 return out;
[email protected]ff007e162009-05-23 09:13:15514 }
initial.commit586acc5fe2008-07-26 22:42:52515
Ryan Sleevib8d7ea02018-05-07 20:01:01516 SimpleGetHelperResult SimpleGetHelper(base::span<const MockRead> data_reads) {
sclittlefb249892015-09-10 21:33:22517 MockWrite data_writes[] = {
518 MockWrite("GET / HTTP/1.1\r\n"
519 "Host: www.example.org\r\n"
520 "Connection: keep-alive\r\n\r\n"),
521 };
[email protected]5a60c8b2011-10-19 20:14:29522
Ryan Sleevib8d7ea02018-05-07 20:01:01523 StaticSocketDataProvider reads(data_reads, data_writes);
sclittlefb249892015-09-10 21:33:22524 StaticSocketDataProvider* data[] = {&reads};
Ryan Sleevib8d7ea02018-05-07 20:01:01525 SimpleGetHelperResult out = SimpleGetHelperForData(data);
sclittlefb249892015-09-10 21:33:22526
Ryan Sleevib8d7ea02018-05-07 20:01:01527 EXPECT_EQ(CountWriteBytes(data_writes), out.total_sent_bytes);
sclittlefb249892015-09-10 21:33:22528 return out;
[email protected]b8015c42013-12-24 15:18:19529 }
530
bnc032658ba2016-09-26 18:17:15531 void AddSSLSocketData() {
532 ssl_.next_proto = kProtoHTTP2;
Ryan Sleevi4f832092017-11-21 23:25:49533 ssl_.ssl_info.cert =
534 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
535 ASSERT_TRUE(ssl_.ssl_info.cert);
bnc032658ba2016-09-26 18:17:15536 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_);
537 }
538
[email protected]ff007e162009-05-23 09:13:15539 void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
540 int expected_status);
initial.commit586acc5fe2008-07-26 22:42:52541
[email protected]ff007e162009-05-23 09:13:15542 void ConnectStatusHelper(const MockRead& status);
[email protected]bb88e1d32013-05-03 23:11:07543
[email protected]bb88e1d32013-05-03 23:11:07544 void CheckErrorIsPassedBack(int error, IoMode mode);
545
Douglas Creager134b52e2018-11-09 18:00:14546 // These clocks are defined here, even though they're only used in the
547 // Reporting tests below, since they need to be destroyed after
548 // |session_deps_|.
549 base::SimpleTestClock clock_;
550 base::SimpleTestTickClock tick_clock_;
551
[email protected]4bd46222013-05-14 19:32:23552 SpdyTestUtil spdy_util_;
[email protected]bb88e1d32013-05-03 23:11:07553 SpdySessionDependencies session_deps_;
bnc032658ba2016-09-26 18:17:15554 SSLSocketDataProvider ssl_;
[email protected]483fa202013-05-14 01:07:03555
556 // Original socket limits. Some tests set these. Safest to always restore
557 // them once each test has been run.
558 int old_max_group_sockets_;
559 int old_max_pool_sockets_;
[email protected]ff007e162009-05-23 09:13:15560};
[email protected]231d5a32008-09-13 00:45:27561
[email protected]448d4ca52012-03-04 04:12:23562namespace {
563
ryansturm49a8cb12016-06-15 16:51:09564class BeforeHeadersSentHandler {
[email protected]597a1ab2014-06-26 08:12:27565 public:
ryansturm49a8cb12016-06-15 16:51:09566 BeforeHeadersSentHandler()
567 : observed_before_headers_sent_with_proxy_(false),
568 observed_before_headers_sent_(false) {}
[email protected]597a1ab2014-06-26 08:12:27569
ryansturm49a8cb12016-06-15 16:51:09570 void OnBeforeHeadersSent(const ProxyInfo& proxy_info,
571 HttpRequestHeaders* request_headers) {
572 observed_before_headers_sent_ = true;
573 if (!proxy_info.is_http() && !proxy_info.is_https() &&
574 !proxy_info.is_quic()) {
575 return;
576 }
577 observed_before_headers_sent_with_proxy_ = true;
[email protected]597a1ab2014-06-26 08:12:27578 observed_proxy_server_uri_ = proxy_info.proxy_server().ToURI();
579 }
580
ryansturm49a8cb12016-06-15 16:51:09581 bool observed_before_headers_sent_with_proxy() const {
582 return observed_before_headers_sent_with_proxy_;
583 }
584
585 bool observed_before_headers_sent() const {
586 return observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27587 }
588
589 std::string observed_proxy_server_uri() const {
590 return observed_proxy_server_uri_;
591 }
592
593 private:
ryansturm49a8cb12016-06-15 16:51:09594 bool observed_before_headers_sent_with_proxy_;
595 bool observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27596 std::string observed_proxy_server_uri_;
597
ryansturm49a8cb12016-06-15 16:51:09598 DISALLOW_COPY_AND_ASSIGN(BeforeHeadersSentHandler);
[email protected]597a1ab2014-06-26 08:12:27599};
600
[email protected]15a5ccf82008-10-23 19:57:43601// Fill |str| with a long header list that consumes >= |size| bytes.
602void FillLargeHeadersString(std::string* str, int size) {
thestig9d3bb0c2015-01-24 00:49:51603 const char row[] =
[email protected]4ddaf2502008-10-23 18:26:19604 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
605 const int sizeof_row = strlen(row);
606 const int num_rows = static_cast<int>(
607 ceil(static_cast<float>(size) / sizeof_row));
608 const int sizeof_data = num_rows * sizeof_row;
609 DCHECK(sizeof_data >= size);
[email protected]15a5ccf82008-10-23 19:57:43610 str->reserve(sizeof_data);
[email protected]372d34a2008-11-05 21:30:51611
[email protected]4ddaf2502008-10-23 18:26:19612 for (int i = 0; i < num_rows; ++i)
[email protected]15a5ccf82008-10-23 19:57:43613 str->append(row, sizeof_row);
[email protected]4ddaf2502008-10-23 18:26:19614}
615
thakis84dff942015-07-28 20:47:38616#if defined(NTLM_PORTABLE)
Zentaro Kavanagh6ccee512017-09-28 18:34:09617uint64_t MockGetMSTime() {
618 // Tue, 23 May 2017 20:13:07 +0000
619 return 131400439870000000;
620}
621
[email protected]385a4672009-03-11 22:21:29622// Alternative functions that eliminate randomness and dependency on the local
623// host name so that the generated NTLM messages are reproducible.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:37624void MockGenerateRandom(uint8_t* output, size_t n) {
625 // This is set to 0xaa because the client challenge for testing in
626 // [MS-NLMP] Section 4.2.1 is 8 bytes of 0xaa.
627 memset(output, 0xaa, n);
[email protected]385a4672009-03-11 22:21:29628}
629
[email protected]fe2bc6a2009-03-23 16:52:20630std::string MockGetHostName() {
Zentaro Kavanagh5b27a6e22017-09-25 23:00:37631 return ntlm::test::kHostnameAscii;
[email protected]385a4672009-03-11 22:21:29632}
thakis84dff942015-07-28 20:47:38633#endif // defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29634
[email protected]e60e47a2010-07-14 03:37:18635template<typename ParentPool>
636class CaptureGroupNameSocketPool : public ParentPool {
[email protected]04e5be32009-06-26 20:00:31637 public:
[email protected]9e1bdd32011-02-03 21:48:34638 CaptureGroupNameSocketPool(HostResolver* host_resolver,
639 CertVerifier* cert_verifier);
[email protected]e60e47a2010-07-14 03:37:18640
[email protected]d80a4322009-08-14 07:07:49641 const std::string last_group_name_received() const {
642 return last_group_name_;
643 }
644
Tarun Bansal162eabe52018-01-20 01:16:39645 bool socket_requested() const { return socket_requested_; }
646
dmichaeld6e570d2014-12-18 22:30:57647 int RequestSocket(const std::string& group_name,
648 const void* socket_params,
649 RequestPriority priority,
Paul Jensen8d6f87ec2018-01-13 00:46:54650 const SocketTag& socket_tag,
mmenked3641e12016-01-28 16:06:15651 ClientSocketPool::RespectLimits respect_limits,
dmichaeld6e570d2014-12-18 22:30:57652 ClientSocketHandle* handle,
Bence Béky5a8662b2018-07-03 13:04:03653 CompletionOnceCallback callback,
tfarina42834112016-09-22 13:38:20654 const NetLogWithSource& net_log) override {
[email protected]04e5be32009-06-26 20:00:31655 last_group_name_ = group_name;
Tarun Bansal162eabe52018-01-20 01:16:39656 socket_requested_ = true;
[email protected]04e5be32009-06-26 20:00:31657 return ERR_IO_PENDING;
658 }
dmichaeld6e570d2014-12-18 22:30:57659 void CancelRequest(const std::string& group_name,
660 ClientSocketHandle* handle) override {}
661 void ReleaseSocket(const std::string& group_name,
danakj1fd259a02016-04-16 03:17:09662 std::unique_ptr<StreamSocket> socket,
dmichaeld6e570d2014-12-18 22:30:57663 int id) override {}
664 void CloseIdleSockets() override {}
xunjieli92feb332017-03-03 17:19:23665 void CloseIdleSocketsInGroup(const std::string& group_name) override {}
dmichaeld6e570d2014-12-18 22:30:57666 int IdleSocketCount() const override { return 0; }
667 int IdleSocketCountInGroup(const std::string& group_name) const override {
[email protected]04e5be32009-06-26 20:00:31668 return 0;
669 }
dmichaeld6e570d2014-12-18 22:30:57670 LoadState GetLoadState(const std::string& group_name,
671 const ClientSocketHandle* handle) const override {
[email protected]04e5be32009-06-26 20:00:31672 return LOAD_STATE_IDLE;
673 }
[email protected]d80a4322009-08-14 07:07:49674
675 private:
[email protected]04e5be32009-06-26 20:00:31676 std::string last_group_name_;
Tarun Bansal162eabe52018-01-20 01:16:39677 bool socket_requested_ = false;
[email protected]04e5be32009-06-26 20:00:31678};
679
[email protected]ab739042011-04-07 15:22:28680typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
681CaptureGroupNameTransportSocketPool;
[email protected]e60e47a2010-07-14 03:37:18682
rkaplowd90695c2015-03-25 22:12:41683template <typename ParentPool>
[email protected]e60e47a2010-07-14 03:37:18684CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34685 HostResolver* host_resolver,
686 CertVerifier* /* cert_verifier */)
Matt Menkecb77b5402019-01-28 17:11:23687 : ParentPool(0,
688 0,
689 NULL,
690 host_resolver,
691 NULL,
692 NULL,
693 NULL,
694 NULL,
695 NULL,
Matt Menkec94d97b2019-02-01 19:28:28696 NULL,
Matt Menke1751ba72019-02-09 02:23:46697 NULL,
Daniel McArdleda3fa942019-02-15 16:41:21698 NULL,
Matt Menkecb77b5402019-01-28 17:11:23699 NULL,
700 NULL,
Matt Menkefa9574f2019-01-28 18:55:27701 NULL,
Matt Menkecb77b5402019-01-28 17:11:23702 NULL) {}
[email protected]e60e47a2010-07-14 03:37:18703
[email protected]231d5a32008-09-13 00:45:27704//-----------------------------------------------------------------------------
705
[email protected]79cb5c12011-09-12 13:12:04706// Helper functions for validating that AuthChallengeInfo's are correctly
707// configured for common cases.
708bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
709 if (!auth_challenge)
710 return false;
711 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43712 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04713 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19714 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04715 return true;
716}
717
718bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
719 if (!auth_challenge)
720 return false;
721 EXPECT_TRUE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43722 EXPECT_EQ("http://myproxy:70", auth_challenge->challenger.Serialize());
723 EXPECT_EQ("MyRealm1", auth_challenge->realm);
724 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
725 return true;
726}
727
728bool CheckBasicSecureProxyAuth(const AuthChallengeInfo* auth_challenge) {
729 if (!auth_challenge)
730 return false;
731 EXPECT_TRUE(auth_challenge->is_proxy);
732 EXPECT_EQ("https://myproxy:70", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04733 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19734 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04735 return true;
736}
737
738bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
739 if (!auth_challenge)
740 return false;
741 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43742 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04743 EXPECT_EQ("digestive", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19744 EXPECT_EQ(kDigestAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04745 return true;
746}
747
thakis84dff942015-07-28 20:47:38748#if defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04749bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
750 if (!auth_challenge)
751 return false;
752 EXPECT_FALSE(auth_challenge->is_proxy);
Zentaro Kavanagh1890a3d2018-01-29 19:52:55753 EXPECT_EQ("https://server", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04754 EXPECT_EQ(std::string(), auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19755 EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04756 return true;
757}
David Benjamin5cb91132018-04-06 05:54:49758
759bool CheckNTLMProxyAuth(const AuthChallengeInfo* auth_challenge) {
760 if (!auth_challenge)
761 return false;
762 EXPECT_TRUE(auth_challenge->is_proxy);
763 EXPECT_EQ("http://server", auth_challenge->challenger.Serialize());
764 EXPECT_EQ(std::string(), auth_challenge->realm);
765 EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
766 return true;
767}
thakis84dff942015-07-28 20:47:38768#endif // defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04769
[email protected]448d4ca52012-03-04 04:12:23770} // namespace
771
bncd16676a2016-07-20 16:23:01772TEST_F(HttpNetworkTransactionTest, Basic) {
danakj1fd259a02016-04-16 03:17:09773 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16774 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]231d5a32008-09-13 00:45:27775}
776
bncd16676a2016-07-20 16:23:01777TEST_F(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27778 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35779 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
780 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06781 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27782 };
Ryan Sleevib8d7ea02018-05-07 20:01:01783 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01784 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27785 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
786 EXPECT_EQ("hello world", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01787 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22788 EXPECT_EQ(reads_size, out.total_received_bytes);
ttuttle1f2d7e92015-04-28 16:17:47789 EXPECT_EQ(0u, out.connection_attempts.size());
ttuttled9dbc652015-09-29 20:00:59790
791 EXPECT_FALSE(out.remote_endpoint_after_start.address().empty());
[email protected]231d5a32008-09-13 00:45:27792}
793
794// Response with no status line.
bncd16676a2016-07-20 16:23:01795TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27796 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35797 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06798 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27799 };
Ryan Sleevib8d7ea02018-05-07 20:01:01800 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41801 EXPECT_THAT(out.rv, IsOk());
802 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
803 EXPECT_EQ("hello world", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01804 int64_t reads_size = CountReadBytes(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41805 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27806}
807
mmenkea7da6da2016-09-01 21:56:52808// Response with no status line, and a weird port. Should fail by default.
809TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPort) {
810 MockRead data_reads[] = {
811 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
812 };
813
Ryan Sleevib8d7ea02018-05-07 20:01:01814 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
mmenkea7da6da2016-09-01 21:56:52815 session_deps_.socket_factory->AddSocketDataProvider(&data);
816
817 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
818
krasinc06a72a2016-12-21 03:42:46819 HttpRequestInfo request;
bnc87dcefc2017-05-25 12:47:58820 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:19821 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenkea7da6da2016-09-01 21:56:52822
mmenkea7da6da2016-09-01 21:56:52823 request.method = "GET";
824 request.url = GURL("http://www.example.com:2000/");
Ramin Halavatib5e433e62018-02-07 07:41:10825 request.traffic_annotation =
826 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
827
mmenkea7da6da2016-09-01 21:56:52828 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20829 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52830 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_INVALID_HTTP_RESPONSE));
831}
832
Shivani Sharmafdcaefd2017-11-02 00:12:26833// Tests that request info can be destroyed after the headers phase is complete.
834TEST_F(HttpNetworkTransactionTest, SimpleGETNoReadDestroyRequestInfo) {
835 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
836 auto trans =
837 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
838
839 MockRead data_reads[] = {
840 MockRead("HTTP/1.0 200 OK\r\n"), MockRead("Connection: keep-alive\r\n"),
841 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, 0),
842 };
Ryan Sleevib8d7ea02018-05-07 20:01:01843 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
Shivani Sharmafdcaefd2017-11-02 00:12:26844 session_deps_.socket_factory->AddSocketDataProvider(&data);
845
846 TestCompletionCallback callback;
847
848 {
849 auto request = std::make_unique<HttpRequestInfo>();
850 request->method = "GET";
851 request->url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:10852 request->traffic_annotation =
853 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Shivani Sharmafdcaefd2017-11-02 00:12:26854
855 int rv =
856 trans->Start(request.get(), callback.callback(), NetLogWithSource());
857
858 EXPECT_THAT(callback.GetResult(rv), IsOk());
859 } // Let request info be destroyed.
860
861 trans.reset();
862}
863
mmenkea7da6da2016-09-01 21:56:52864// Response with no status line, and a weird port. Option to allow weird ports
865// enabled.
866TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPortAllowed) {
867 MockRead data_reads[] = {
868 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
869 };
870
Ryan Sleevib8d7ea02018-05-07 20:01:01871 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
mmenkea7da6da2016-09-01 21:56:52872 session_deps_.socket_factory->AddSocketDataProvider(&data);
873 session_deps_.http_09_on_non_default_ports_enabled = true;
874 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
875
krasinc06a72a2016-12-21 03:42:46876 HttpRequestInfo request;
bnc87dcefc2017-05-25 12:47:58877 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:19878 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenkea7da6da2016-09-01 21:56:52879
mmenkea7da6da2016-09-01 21:56:52880 request.method = "GET";
881 request.url = GURL("http://www.example.com:2000/");
Ramin Halavatib5e433e62018-02-07 07:41:10882 request.traffic_annotation =
883 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
884
mmenkea7da6da2016-09-01 21:56:52885 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20886 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52887 EXPECT_THAT(callback.GetResult(rv), IsOk());
888
889 const HttpResponseInfo* info = trans->GetResponseInfo();
890 ASSERT_TRUE(info->headers);
891 EXPECT_EQ("HTTP/0.9 200 OK", info->headers->GetStatusLine());
892
893 // Don't bother to read the body - that's verified elsewhere, important thing
894 // is that the option to allow HTTP/0.9 on non-default ports is respected.
895}
896
[email protected]231d5a32008-09-13 00:45:27897// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01898TEST_F(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27899 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35900 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06901 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27902 };
Ryan Sleevib8d7ea02018-05-07 20:01:01903 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01904 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27905 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
906 EXPECT_EQ("DATA", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01907 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22908 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27909}
910
911// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01912TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27913 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35914 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06915 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27916 };
Ryan Sleevib8d7ea02018-05-07 20:01:01917 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01918 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27919 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
920 EXPECT_EQ("DATA", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01921 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22922 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27923}
924
925// Beyond 4 bytes of slop and it should fail to find a status line.
bncd16676a2016-07-20 16:23:01926TEST_F(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27927 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35928 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06929 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27930 };
Ryan Sleevib8d7ea02018-05-07 20:01:01931 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41932 EXPECT_THAT(out.rv, IsOk());
933 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
934 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01935 int64_t reads_size = CountReadBytes(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41936 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27937}
938
939// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
bncd16676a2016-07-20 16:23:01940TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27941 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35942 MockRead("\n"),
943 MockRead("\n"),
944 MockRead("Q"),
945 MockRead("J"),
946 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06947 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27948 };
Ryan Sleevib8d7ea02018-05-07 20:01:01949 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01950 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27951 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
952 EXPECT_EQ("DATA", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01953 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22954 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27955}
956
957// Close the connection before enough bytes to have a status line.
bncd16676a2016-07-20 16:23:01958TEST_F(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:27959 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35960 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:06961 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27962 };
Ryan Sleevib8d7ea02018-05-07 20:01:01963 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41964 EXPECT_THAT(out.rv, IsOk());
965 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
966 EXPECT_EQ("HTT", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01967 int64_t reads_size = CountReadBytes(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41968 EXPECT_EQ(reads_size, out.total_received_bytes);
initial.commit586acc5fe2008-07-26 22:42:52969}
970
[email protected]f9d44aa2008-09-23 23:57:17971// Simulate a 204 response, lacking a Content-Length header, sent over a
972// persistent connection. The response should still terminate since a 204
973// cannot have a response body.
bncd16676a2016-07-20 16:23:01974TEST_F(HttpNetworkTransactionTest, StopsReading204) {
[email protected]b8015c42013-12-24 15:18:19975 char junk[] = "junk";
[email protected]f9d44aa2008-09-23 23:57:17976 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35977 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
[email protected]b8015c42013-12-24 15:18:19978 MockRead(junk), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:06979 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:17980 };
Ryan Sleevib8d7ea02018-05-07 20:01:01981 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01982 EXPECT_THAT(out.rv, IsOk());
[email protected]f9d44aa2008-09-23 23:57:17983 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
984 EXPECT_EQ("", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01985 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22986 int64_t response_size = reads_size - strlen(junk);
987 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]f9d44aa2008-09-23 23:57:17988}
989
[email protected]0877e3d2009-10-17 22:29:57990// A simple request using chunked encoding with some extra data after.
bncd16676a2016-07-20 16:23:01991TEST_F(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]b8015c42013-12-24 15:18:19992 std::string final_chunk = "0\r\n\r\n";
993 std::string extra_data = "HTTP/1.1 200 OK\r\n";
994 std::string last_read = final_chunk + extra_data;
[email protected]0877e3d2009-10-17 22:29:57995 MockRead data_reads[] = {
996 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
997 MockRead("5\r\nHello\r\n"),
998 MockRead("1\r\n"),
999 MockRead(" \r\n"),
1000 MockRead("5\r\nworld\r\n"),
[email protected]b8015c42013-12-24 15:18:191001 MockRead(last_read.data()),
[email protected]8ddf8322012-02-23 18:08:061002 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:571003 };
Ryan Sleevib8d7ea02018-05-07 20:01:011004 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011005 EXPECT_THAT(out.rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:571006 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1007 EXPECT_EQ("Hello world", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:011008 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:221009 int64_t response_size = reads_size - extra_data.size();
1010 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]0877e3d2009-10-17 22:29:571011}
1012
[email protected]9fe44f52010-09-23 18:36:001013// Next tests deal with http://crbug.com/56344.
1014
bncd16676a2016-07-20 16:23:011015TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001016 MultipleContentLengthHeadersNoTransferEncoding) {
1017 MockRead data_reads[] = {
1018 MockRead("HTTP/1.1 200 OK\r\n"),
1019 MockRead("Content-Length: 10\r\n"),
1020 MockRead("Content-Length: 5\r\n\r\n"),
1021 };
Ryan Sleevib8d7ea02018-05-07 20:01:011022 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011023 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]9fe44f52010-09-23 18:36:001024}
1025
bncd16676a2016-07-20 16:23:011026TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:041027 DuplicateContentLengthHeadersNoTransferEncoding) {
1028 MockRead data_reads[] = {
1029 MockRead("HTTP/1.1 200 OK\r\n"),
1030 MockRead("Content-Length: 5\r\n"),
1031 MockRead("Content-Length: 5\r\n\r\n"),
1032 MockRead("Hello"),
1033 };
Ryan Sleevib8d7ea02018-05-07 20:01:011034 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011035 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041036 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1037 EXPECT_EQ("Hello", out.response_data);
1038}
1039
bncd16676a2016-07-20 16:23:011040TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:041041 ComplexContentLengthHeadersNoTransferEncoding) {
1042 // More than 2 dupes.
1043 {
1044 MockRead data_reads[] = {
1045 MockRead("HTTP/1.1 200 OK\r\n"),
1046 MockRead("Content-Length: 5\r\n"),
1047 MockRead("Content-Length: 5\r\n"),
1048 MockRead("Content-Length: 5\r\n\r\n"),
1049 MockRead("Hello"),
1050 };
Ryan Sleevib8d7ea02018-05-07 20:01:011051 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011052 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041053 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1054 EXPECT_EQ("Hello", out.response_data);
1055 }
1056 // HTTP/1.0
1057 {
1058 MockRead data_reads[] = {
1059 MockRead("HTTP/1.0 200 OK\r\n"),
1060 MockRead("Content-Length: 5\r\n"),
1061 MockRead("Content-Length: 5\r\n"),
1062 MockRead("Content-Length: 5\r\n\r\n"),
1063 MockRead("Hello"),
1064 };
Ryan Sleevib8d7ea02018-05-07 20:01:011065 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011066 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041067 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
1068 EXPECT_EQ("Hello", out.response_data);
1069 }
1070 // 2 dupes and one mismatched.
1071 {
1072 MockRead data_reads[] = {
1073 MockRead("HTTP/1.1 200 OK\r\n"),
1074 MockRead("Content-Length: 10\r\n"),
1075 MockRead("Content-Length: 10\r\n"),
1076 MockRead("Content-Length: 5\r\n\r\n"),
1077 };
Ryan Sleevib8d7ea02018-05-07 20:01:011078 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011079 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]44b52042010-10-29 22:48:041080 }
1081}
1082
bncd16676a2016-07-20 16:23:011083TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001084 MultipleContentLengthHeadersTransferEncoding) {
1085 MockRead data_reads[] = {
1086 MockRead("HTTP/1.1 200 OK\r\n"),
1087 MockRead("Content-Length: 666\r\n"),
1088 MockRead("Content-Length: 1337\r\n"),
1089 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
1090 MockRead("5\r\nHello\r\n"),
1091 MockRead("1\r\n"),
1092 MockRead(" \r\n"),
1093 MockRead("5\r\nworld\r\n"),
1094 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:061095 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:001096 };
Ryan Sleevib8d7ea02018-05-07 20:01:011097 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011098 EXPECT_THAT(out.rv, IsOk());
[email protected]9fe44f52010-09-23 18:36:001099 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1100 EXPECT_EQ("Hello world", out.response_data);
1101}
1102
[email protected]1628fe92011-10-04 23:04:551103// Next tests deal with http://crbug.com/98895.
1104
1105// Checks that a single Content-Disposition header results in no error.
bncd16676a2016-07-20 16:23:011106TEST_F(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:551107 MockRead data_reads[] = {
1108 MockRead("HTTP/1.1 200 OK\r\n"),
1109 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
1110 MockRead("Content-Length: 5\r\n\r\n"),
1111 MockRead("Hello"),
1112 };
Ryan Sleevib8d7ea02018-05-07 20:01:011113 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011114 EXPECT_THAT(out.rv, IsOk());
[email protected]1628fe92011-10-04 23:04:551115 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1116 EXPECT_EQ("Hello", out.response_data);
1117}
1118
[email protected]54a9c6e52012-03-21 20:10:591119// Checks that two identical Content-Disposition headers result in no error.
bncd16676a2016-07-20 16:23:011120TEST_F(HttpNetworkTransactionTest, TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551121 MockRead data_reads[] = {
1122 MockRead("HTTP/1.1 200 OK\r\n"),
1123 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1124 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1125 MockRead("Content-Length: 5\r\n\r\n"),
1126 MockRead("Hello"),
1127 };
Ryan Sleevib8d7ea02018-05-07 20:01:011128 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011129 EXPECT_THAT(out.rv, IsOk());
[email protected]54a9c6e52012-03-21 20:10:591130 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1131 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:551132}
1133
1134// Checks that two distinct Content-Disposition headers result in an error.
bncd16676a2016-07-20 16:23:011135TEST_F(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551136 MockRead data_reads[] = {
1137 MockRead("HTTP/1.1 200 OK\r\n"),
1138 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1139 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
1140 MockRead("Content-Length: 5\r\n\r\n"),
1141 MockRead("Hello"),
1142 };
Ryan Sleevib8d7ea02018-05-07 20:01:011143 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011144 EXPECT_THAT(out.rv,
1145 IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION));
[email protected]1628fe92011-10-04 23:04:551146}
1147
[email protected]54a9c6e52012-03-21 20:10:591148// Checks that two identical Location headers result in no error.
1149// Also tests Location header behavior.
bncd16676a2016-07-20 16:23:011150TEST_F(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551151 MockRead data_reads[] = {
1152 MockRead("HTTP/1.1 302 Redirect\r\n"),
1153 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:591154 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:551155 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061156 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551157 };
1158
1159 HttpRequestInfo request;
1160 request.method = "GET";
1161 request.url = GURL("http://redirect.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101162 request.traffic_annotation =
1163 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1628fe92011-10-04 23:04:551164
danakj1fd259a02016-04-16 03:17:091165 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161166 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1628fe92011-10-04 23:04:551167
Ryan Sleevib8d7ea02018-05-07 20:01:011168 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071169 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:551170
[email protected]49639fa2011-12-20 23:22:411171 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:551172
tfarina42834112016-09-22 13:38:201173 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011174 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1628fe92011-10-04 23:04:551175
robpercival214763f2016-07-01 23:27:011176 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]1628fe92011-10-04 23:04:551177
bnc691fda62016-08-12 00:43:161178 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521179 ASSERT_TRUE(response);
1180 ASSERT_TRUE(response->headers);
[email protected]1628fe92011-10-04 23:04:551181 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
1182 std::string url;
1183 EXPECT_TRUE(response->headers->IsRedirect(&url));
1184 EXPECT_EQ("http://good.com/", url);
tbansal2ecbbc72016-10-06 17:15:471185 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]1628fe92011-10-04 23:04:551186}
1187
[email protected]1628fe92011-10-04 23:04:551188// Checks that two distinct Location headers result in an error.
bncd16676a2016-07-20 16:23:011189TEST_F(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551190 MockRead data_reads[] = {
1191 MockRead("HTTP/1.1 302 Redirect\r\n"),
1192 MockRead("Location: http://good.com/\r\n"),
1193 MockRead("Location: http://evil.com/\r\n"),
1194 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061195 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551196 };
Ryan Sleevib8d7ea02018-05-07 20:01:011197 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011198 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION));
[email protected]1628fe92011-10-04 23:04:551199}
1200
[email protected]ef0faf2e72009-03-05 23:27:231201// Do a request using the HEAD method. Verify that we don't try to read the
1202// message body (since HEAD has none).
bncd16676a2016-07-20 16:23:011203TEST_F(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:421204 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:231205 request.method = "HEAD";
bncce36dca22015-04-21 22:11:231206 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:101207 request.traffic_annotation =
1208 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ef0faf2e72009-03-05 23:27:231209
danakj1fd259a02016-04-16 03:17:091210 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161211 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:091212 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:161213 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:091214 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
1215 base::Unretained(&headers_handler)));
[email protected]cb9bf6ca2011-01-28 13:15:271216
[email protected]ef0faf2e72009-03-05 23:27:231217 MockWrite data_writes1[] = {
csharrisonf473dd192015-08-18 13:54:131218 MockWrite("HEAD / HTTP/1.1\r\n"
1219 "Host: www.example.org\r\n"
1220 "Connection: keep-alive\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231221 };
1222 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:231223 MockRead("HTTP/1.1 404 Not Found\r\n"), MockRead("Server: Blah\r\n"),
1224 MockRead("Content-Length: 1234\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231225
mmenked39192ee2015-12-09 00:57:231226 // No response body because the test stops reading here.
1227 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]ef0faf2e72009-03-05 23:27:231228 };
1229
Ryan Sleevib8d7ea02018-05-07 20:01:011230 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:071231 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:231232
[email protected]49639fa2011-12-20 23:22:411233 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:231234
tfarina42834112016-09-22 13:38:201235 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011236 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ef0faf2e72009-03-05 23:27:231237
1238 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:011239 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231240
bnc691fda62016-08-12 00:43:161241 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521242 ASSERT_TRUE(response);
[email protected]ef0faf2e72009-03-05 23:27:231243
1244 // Check that the headers got parsed.
wezca1070932016-05-26 20:30:521245 EXPECT_TRUE(response->headers);
[email protected]ef0faf2e72009-03-05 23:27:231246 EXPECT_EQ(1234, response->headers->GetContentLength());
1247 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471248 EXPECT_TRUE(response->proxy_server.is_direct());
ryansturm49a8cb12016-06-15 16:51:091249 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
1250 EXPECT_FALSE(headers_handler.observed_before_headers_sent_with_proxy());
[email protected]ef0faf2e72009-03-05 23:27:231251
1252 std::string server_header;
olli.raulaee489a52016-01-25 08:37:101253 size_t iter = 0;
[email protected]ef0faf2e72009-03-05 23:27:231254 bool has_server_header = response->headers->EnumerateHeader(
1255 &iter, "Server", &server_header);
1256 EXPECT_TRUE(has_server_header);
1257 EXPECT_EQ("Blah", server_header);
1258
1259 // Reading should give EOF right away, since there is no message body
1260 // (despite non-zero content-length).
1261 std::string response_data;
bnc691fda62016-08-12 00:43:161262 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011263 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231264 EXPECT_EQ("", response_data);
1265}
1266
bncd16676a2016-07-20 16:23:011267TEST_F(HttpNetworkTransactionTest, ReuseConnection) {
danakj1fd259a02016-04-16 03:17:091268 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:521269
1270 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351271 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1272 MockRead("hello"),
1273 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1274 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061275 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521276 };
Ryan Sleevib8d7ea02018-05-07 20:01:011277 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071278 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521279
[email protected]0b0bf032010-09-21 18:08:501280 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521281 "hello", "world"
1282 };
1283
1284 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:421285 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521286 request.method = "GET";
bncce36dca22015-04-21 22:11:231287 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:101288 request.traffic_annotation =
1289 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:521290
bnc691fda62016-08-12 00:43:161291 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271292
[email protected]49639fa2011-12-20 23:22:411293 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521294
tfarina42834112016-09-22 13:38:201295 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011296 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521297
1298 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011299 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521300
bnc691fda62016-08-12 00:43:161301 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521302 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521303
wezca1070932016-05-26 20:30:521304 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251305 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471306 EXPECT_TRUE(response->proxy_server.is_direct());
initial.commit586acc5fe2008-07-26 22:42:521307
1308 std::string response_data;
bnc691fda62016-08-12 00:43:161309 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011310 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251311 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521312 }
1313}
1314
bncd16676a2016-07-20 16:23:011315TEST_F(HttpNetworkTransactionTest, Ignores100) {
danakj1fd259a02016-04-16 03:17:091316 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:221317 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:191318 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:221319 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:271320
[email protected]1c773ea12009-04-28 19:58:421321 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521322 request.method = "POST";
1323 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271324 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:101325 request.traffic_annotation =
1326 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:521327
shivanishab9a143952016-09-19 17:23:411328 // Check the upload progress returned before initialization is correct.
1329 UploadProgress progress = request.upload_data_stream->GetUploadProgress();
1330 EXPECT_EQ(0u, progress.size());
1331 EXPECT_EQ(0u, progress.position());
1332
danakj1fd259a02016-04-16 03:17:091333 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161334 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271335
initial.commit586acc5fe2008-07-26 22:42:521336 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351337 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1338 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1339 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061340 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521341 };
Ryan Sleevib8d7ea02018-05-07 20:01:011342 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071343 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521344
[email protected]49639fa2011-12-20 23:22:411345 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521346
tfarina42834112016-09-22 13:38:201347 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011348 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521349
1350 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011351 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521352
bnc691fda62016-08-12 00:43:161353 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521354 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521355
wezca1070932016-05-26 20:30:521356 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251357 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521358
1359 std::string response_data;
bnc691fda62016-08-12 00:43:161360 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011361 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251362 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521363}
1364
[email protected]3a2d3662009-03-27 03:49:141365// This test is almost the same as Ignores100 above, but the response contains
1366// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571367// HTTP/1.1 and the two status headers are read in one read.
bncd16676a2016-07-20 16:23:011368TEST_F(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421369 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141370 request.method = "GET";
1371 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101372 request.traffic_annotation =
1373 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3a2d3662009-03-27 03:49:141374
danakj1fd259a02016-04-16 03:17:091375 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161376 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271377
[email protected]3a2d3662009-03-27 03:49:141378 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571379 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1380 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141381 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061382 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141383 };
Ryan Sleevib8d7ea02018-05-07 20:01:011384 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071385 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141386
[email protected]49639fa2011-12-20 23:22:411387 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141388
tfarina42834112016-09-22 13:38:201389 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011390 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3a2d3662009-03-27 03:49:141391
1392 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011393 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141394
bnc691fda62016-08-12 00:43:161395 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521396 ASSERT_TRUE(response);
[email protected]3a2d3662009-03-27 03:49:141397
wezca1070932016-05-26 20:30:521398 EXPECT_TRUE(response->headers);
[email protected]3a2d3662009-03-27 03:49:141399 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1400
1401 std::string response_data;
bnc691fda62016-08-12 00:43:161402 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011403 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141404 EXPECT_EQ("hello world", response_data);
1405}
1406
Andrew Comminos517a92c2019-01-14 17:49:561407TEST_F(HttpNetworkTransactionTest, LoadTimingMeasuresTimeToFirstByteForHttp) {
1408 static const base::TimeDelta kDelayAfterFirstByte =
Andrew Comminos1f2ff1cc2018-12-14 05:22:381409 base::TimeDelta::FromMilliseconds(10);
1410
1411 HttpRequestInfo request;
1412 request.method = "GET";
1413 request.url = GURL("http://www.foo.com/");
1414 request.traffic_annotation =
1415 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1416
1417 std::vector<MockWrite> data_writes = {
1418 MockWrite(ASYNC, 0,
1419 "GET / HTTP/1.1\r\n"
1420 "Host: www.foo.com\r\n"
1421 "Connection: keep-alive\r\n\r\n"),
1422 };
1423
1424 std::vector<MockRead> data_reads = {
1425 // Write one byte of the status line, followed by a pause.
1426 MockRead(ASYNC, 1, "H"),
1427 MockRead(ASYNC, ERR_IO_PENDING, 2),
1428 MockRead(ASYNC, 3, "TTP/1.1 200 OK\r\n\r\n"),
1429 MockRead(ASYNC, 4, "hello world"),
1430 MockRead(SYNCHRONOUS, OK, 5),
1431 };
1432
1433 SequencedSocketData data(data_reads, data_writes);
1434 session_deps_.socket_factory->AddSocketDataProvider(&data);
1435
1436 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1437
1438 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1439
1440 TestCompletionCallback callback;
1441
1442 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1443 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1444
1445 data.RunUntilPaused();
1446 ASSERT_TRUE(data.IsPaused());
Andrew Comminos517a92c2019-01-14 17:49:561447 FastForwardBy(kDelayAfterFirstByte);
Andrew Comminos1f2ff1cc2018-12-14 05:22:381448 data.Resume();
1449
1450 rv = callback.WaitForResult();
1451 EXPECT_THAT(rv, IsOk());
1452
1453 const HttpResponseInfo* response = trans.GetResponseInfo();
1454 ASSERT_TRUE(response);
1455
1456 EXPECT_TRUE(response->headers);
1457 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1458
1459 LoadTimingInfo load_timing_info;
1460 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
1461 EXPECT_FALSE(load_timing_info.receive_headers_start.is_null());
1462 EXPECT_FALSE(load_timing_info.connect_timing.connect_end.is_null());
Andrew Comminos517a92c2019-01-14 17:49:561463 // Ensure we didn't include the delay in the TTFB time.
1464 EXPECT_EQ(load_timing_info.receive_headers_start,
1465 load_timing_info.connect_timing.connect_end);
1466 // Ensure that the mock clock advanced at all.
1467 EXPECT_EQ(base::TimeTicks::Now() - load_timing_info.receive_headers_start,
1468 kDelayAfterFirstByte);
Andrew Comminos1f2ff1cc2018-12-14 05:22:381469
1470 std::string response_data;
1471 rv = ReadTransaction(&trans, &response_data);
1472 EXPECT_THAT(rv, IsOk());
1473 EXPECT_EQ("hello world", response_data);
1474}
1475
1476// Tests that the time-to-first-byte reported in a transaction's load timing
1477// info uses the first response, even if 1XX/informational.
1478void HttpNetworkTransactionTest::Check100ResponseTiming(bool use_spdy) {
Andrew Comminos517a92c2019-01-14 17:49:561479 static const base::TimeDelta kDelayAfter100Response =
Andrew Comminos1f2ff1cc2018-12-14 05:22:381480 base::TimeDelta::FromMilliseconds(10);
1481
1482 HttpRequestInfo request;
1483 request.method = "GET";
1484 request.url = GURL("https://www.foo.com/");
1485 request.traffic_annotation =
1486 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1487
1488 SSLSocketDataProvider ssl(ASYNC, OK);
1489 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
1490
1491 std::vector<MockWrite> data_writes;
1492 std::vector<MockRead> data_reads;
1493
1494 spdy::SpdySerializedFrame spdy_req(
1495 spdy_util_.ConstructSpdyGet(request.url.spec().c_str(), 1, LOWEST));
1496
1497 spdy::SpdyHeaderBlock spdy_resp1_headers;
1498 spdy_resp1_headers[spdy::kHttp2StatusHeader] = "100";
1499 spdy::SpdySerializedFrame spdy_resp1(
1500 spdy_util_.ConstructSpdyReply(1, spdy_resp1_headers.Clone()));
1501 spdy::SpdySerializedFrame spdy_resp2(
1502 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
1503 spdy::SpdySerializedFrame spdy_data(
1504 spdy_util_.ConstructSpdyDataFrame(1, "hello world", true));
1505
1506 if (use_spdy) {
1507 ssl.next_proto = kProtoHTTP2;
1508
1509 data_writes = {CreateMockWrite(spdy_req, 0)};
1510
1511 data_reads = {
1512 CreateMockRead(spdy_resp1, 1), MockRead(ASYNC, ERR_IO_PENDING, 2),
1513 CreateMockRead(spdy_resp2, 3), CreateMockRead(spdy_data, 4),
1514 MockRead(SYNCHRONOUS, OK, 5),
1515 };
1516 } else {
1517 data_writes = {
1518 MockWrite(ASYNC, 0,
1519 "GET / HTTP/1.1\r\n"
1520 "Host: www.foo.com\r\n"
1521 "Connection: keep-alive\r\n\r\n"),
1522 };
1523
1524 data_reads = {
1525 MockRead(ASYNC, 1, "HTTP/1.1 100 Continue\r\n\r\n"),
1526 MockRead(ASYNC, ERR_IO_PENDING, 2),
1527
1528 MockRead(ASYNC, 3, "HTTP/1.1 200 OK\r\n\r\n"),
1529 MockRead(ASYNC, 4, "hello world"),
1530 MockRead(SYNCHRONOUS, OK, 5),
1531 };
1532 }
1533
1534 SequencedSocketData data(data_reads, data_writes);
1535 session_deps_.socket_factory->AddSocketDataProvider(&data);
1536
1537 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1538
1539 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1540
1541 TestCompletionCallback callback;
1542
1543 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1544 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1545
1546 data.RunUntilPaused();
1547 // We should now have parsed the 100 response and hit ERR_IO_PENDING. Insert
1548 // the delay before parsing the 200 response.
1549 ASSERT_TRUE(data.IsPaused());
Andrew Comminos517a92c2019-01-14 17:49:561550 FastForwardBy(kDelayAfter100Response);
Andrew Comminos1f2ff1cc2018-12-14 05:22:381551 data.Resume();
1552
1553 rv = callback.WaitForResult();
1554 EXPECT_THAT(rv, IsOk());
1555
1556 const HttpResponseInfo* response = trans.GetResponseInfo();
1557 ASSERT_TRUE(response);
1558
1559 LoadTimingInfo load_timing_info;
1560 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
1561 EXPECT_FALSE(load_timing_info.receive_headers_start.is_null());
1562 EXPECT_FALSE(load_timing_info.connect_timing.connect_end.is_null());
Andrew Comminos517a92c2019-01-14 17:49:561563 // Ensure we didn't include the delay in the TTFB time.
1564 EXPECT_EQ(load_timing_info.receive_headers_start,
1565 load_timing_info.connect_timing.connect_end);
1566 // Ensure that the mock clock advanced at all.
1567 EXPECT_EQ(base::TimeTicks::Now() - load_timing_info.receive_headers_start,
1568 kDelayAfter100Response);
Andrew Comminos1f2ff1cc2018-12-14 05:22:381569
1570 std::string response_data;
1571 rv = ReadTransaction(&trans, &response_data);
1572 EXPECT_THAT(rv, IsOk());
1573 EXPECT_EQ("hello world", response_data);
1574}
1575
Andrew Comminos517a92c2019-01-14 17:49:561576TEST_F(HttpNetworkTransactionTest, MeasuresTimeToFirst100ResponseForHttp) {
Andrew Comminos1f2ff1cc2018-12-14 05:22:381577 Check100ResponseTiming(false /* use_spdy */);
1578}
1579
Andrew Comminos517a92c2019-01-14 17:49:561580TEST_F(HttpNetworkTransactionTest, MeasuresTimeToFirst100ResponseForSpdy) {
Andrew Comminos1f2ff1cc2018-12-14 05:22:381581 Check100ResponseTiming(true /* use_spdy */);
1582}
1583
bncd16676a2016-07-20 16:23:011584TEST_F(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
zmo9528c9f42015-08-04 22:12:081585 HttpRequestInfo request;
1586 request.method = "POST";
1587 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101588 request.traffic_annotation =
1589 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
zmo9528c9f42015-08-04 22:12:081590
danakj1fd259a02016-04-16 03:17:091591 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161592 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zmo9528c9f42015-08-04 22:12:081593
1594 MockRead data_reads[] = {
1595 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1596 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381597 };
Ryan Sleevib8d7ea02018-05-07 20:01:011598 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
zmo9528c9f42015-08-04 22:12:081599 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381600
zmo9528c9f42015-08-04 22:12:081601 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381602
tfarina42834112016-09-22 13:38:201603 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011604 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381605
zmo9528c9f42015-08-04 22:12:081606 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011607 EXPECT_THAT(rv, IsOk());
[email protected]ee9410e72010-01-07 01:42:381608
zmo9528c9f42015-08-04 22:12:081609 std::string response_data;
bnc691fda62016-08-12 00:43:161610 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011611 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:081612 EXPECT_EQ("", response_data);
[email protected]ee9410e72010-01-07 01:42:381613}
1614
bncd16676a2016-07-20 16:23:011615TEST_F(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381616 HttpRequestInfo request;
1617 request.method = "POST";
1618 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101619 request.traffic_annotation =
1620 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ee9410e72010-01-07 01:42:381621
danakj1fd259a02016-04-16 03:17:091622 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161623 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271624
[email protected]ee9410e72010-01-07 01:42:381625 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061626 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381627 };
Ryan Sleevib8d7ea02018-05-07 20:01:011628 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071629 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381630
[email protected]49639fa2011-12-20 23:22:411631 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381632
tfarina42834112016-09-22 13:38:201633 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011634 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381635
1636 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011637 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]ee9410e72010-01-07 01:42:381638}
1639
[email protected]23e482282013-06-14 16:08:021640void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511641 const MockWrite* write_failure,
1642 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421643 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521644 request.method = "GET";
1645 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101646 request.traffic_annotation =
1647 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:521648
vishal.b62985ca92015-04-17 08:45:511649 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071650 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091651 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271652
[email protected]202965992011-12-07 23:04:511653 // Written data for successfully sending both requests.
1654 MockWrite data1_writes[] = {
1655 MockWrite("GET / HTTP/1.1\r\n"
1656 "Host: www.foo.com\r\n"
1657 "Connection: keep-alive\r\n\r\n"),
1658 MockWrite("GET / HTTP/1.1\r\n"
1659 "Host: www.foo.com\r\n"
1660 "Connection: keep-alive\r\n\r\n")
1661 };
1662
1663 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521664 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351665 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1666 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061667 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521668 };
[email protected]202965992011-12-07 23:04:511669
1670 if (write_failure) {
[email protected]a34f61ee2014-03-18 20:59:491671 ASSERT_FALSE(read_failure);
[email protected]202965992011-12-07 23:04:511672 data1_writes[1] = *write_failure;
1673 } else {
1674 ASSERT_TRUE(read_failure);
1675 data1_reads[2] = *read_failure;
1676 }
1677
Ryan Sleevib8d7ea02018-05-07 20:01:011678 StaticSocketDataProvider data1(data1_reads, data1_writes);
[email protected]bb88e1d32013-05-03 23:11:071679 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521680
1681 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351682 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1683 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061684 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521685 };
Ryan Sleevib8d7ea02018-05-07 20:01:011686 StaticSocketDataProvider data2(data2_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071687 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521688
thestig9d3bb0c2015-01-24 00:49:511689 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521690 "hello", "world"
1691 };
1692
mikecironef22f9812016-10-04 03:40:191693 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521694 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411695 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521696
bnc691fda62016-08-12 00:43:161697 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
initial.commit586acc5fe2008-07-26 22:42:521698
tfarina42834112016-09-22 13:38:201699 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011700 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521701
1702 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011703 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521704
[email protected]58e32bb2013-01-21 18:23:251705 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161706 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:251707 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1708 if (i == 0) {
1709 first_socket_log_id = load_timing_info.socket_log_id;
1710 } else {
1711 // The second request should be using a new socket.
1712 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1713 }
1714
bnc691fda62016-08-12 00:43:161715 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521716 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521717
wezca1070932016-05-26 20:30:521718 EXPECT_TRUE(response->headers);
tbansal2ecbbc72016-10-06 17:15:471719 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]3d2a59b2008-09-26 19:44:251720 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521721
1722 std::string response_data;
bnc691fda62016-08-12 00:43:161723 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011724 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251725 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521726 }
1727}
[email protected]3d2a59b2008-09-26 19:44:251728
[email protected]a34f61ee2014-03-18 20:59:491729void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1730 const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:101731 const MockRead* read_failure,
1732 bool use_spdy) {
[email protected]a34f61ee2014-03-18 20:59:491733 HttpRequestInfo request;
1734 request.method = "GET";
[email protected]09356c652014-03-25 15:36:101735 request.url = GURL("https://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101736 request.traffic_annotation =
1737 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]a34f61ee2014-03-18 20:59:491738
vishal.b62985ca92015-04-17 08:45:511739 TestNetLog net_log;
[email protected]a34f61ee2014-03-18 20:59:491740 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091741 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a34f61ee2014-03-18 20:59:491742
[email protected]09356c652014-03-25 15:36:101743 SSLSocketDataProvider ssl1(ASYNC, OK);
1744 SSLSocketDataProvider ssl2(ASYNC, OK);
1745 if (use_spdy) {
bnc3cf2a592016-08-11 14:48:361746 ssl1.next_proto = kProtoHTTP2;
1747 ssl2.next_proto = kProtoHTTP2;
[email protected]09356c652014-03-25 15:36:101748 }
1749 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1750 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]a34f61ee2014-03-18 20:59:491751
[email protected]09356c652014-03-25 15:36:101752 // SPDY versions of the request and response.
Ryan Hamilton0239aac2018-05-19 00:03:131753 spdy::SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
bnc38dcd392016-02-09 23:19:491754 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
Ryan Hamilton0239aac2018-05-19 00:03:131755 spdy::SpdySerializedFrame spdy_response(
bnc42331402016-07-25 13:36:151756 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:131757 spdy::SpdySerializedFrame spdy_data(
Bence Békyd74f4382018-02-20 18:26:191758 spdy_util_.ConstructSpdyDataFrame(1, "hello", true));
[email protected]a34f61ee2014-03-18 20:59:491759
[email protected]09356c652014-03-25 15:36:101760 // HTTP/1.1 versions of the request and response.
1761 const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1762 "Host: www.foo.com\r\n"
1763 "Connection: keep-alive\r\n\r\n";
1764 const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1765 const char kHttpData[] = "hello";
1766
1767 std::vector<MockRead> data1_reads;
1768 std::vector<MockWrite> data1_writes;
[email protected]a34f61ee2014-03-18 20:59:491769 if (write_failure) {
1770 ASSERT_FALSE(read_failure);
[email protected]09356c652014-03-25 15:36:101771 data1_writes.push_back(*write_failure);
1772 data1_reads.push_back(MockRead(ASYNC, OK));
[email protected]a34f61ee2014-03-18 20:59:491773 } else {
1774 ASSERT_TRUE(read_failure);
[email protected]09356c652014-03-25 15:36:101775 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411776 data1_writes.push_back(CreateMockWrite(spdy_request));
[email protected]09356c652014-03-25 15:36:101777 } else {
1778 data1_writes.push_back(MockWrite(kHttpRequest));
1779 }
1780 data1_reads.push_back(*read_failure);
[email protected]a34f61ee2014-03-18 20:59:491781 }
1782
Ryan Sleevib8d7ea02018-05-07 20:01:011783 StaticSocketDataProvider data1(data1_reads, data1_writes);
[email protected]a34f61ee2014-03-18 20:59:491784 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1785
[email protected]09356c652014-03-25 15:36:101786 std::vector<MockRead> data2_reads;
1787 std::vector<MockWrite> data2_writes;
1788
1789 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411790 data2_writes.push_back(CreateMockWrite(spdy_request, 0, ASYNC));
[email protected]09356c652014-03-25 15:36:101791
bncdf80d44fd2016-07-15 20:27:411792 data2_reads.push_back(CreateMockRead(spdy_response, 1, ASYNC));
1793 data2_reads.push_back(CreateMockRead(spdy_data, 2, ASYNC));
[email protected]09356c652014-03-25 15:36:101794 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1795 } else {
1796 data2_writes.push_back(
1797 MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1798
1799 data2_reads.push_back(
1800 MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1801 data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1802 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1803 }
Ryan Sleevib8d7ea02018-05-07 20:01:011804 SequencedSocketData data2(data2_reads, data2_writes);
[email protected]a34f61ee2014-03-18 20:59:491805 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1806
1807 // Preconnect a socket.
nharper8cdb0fb2016-04-22 21:34:591808 session->http_stream_factory()->PreconnectStreams(1, request);
[email protected]a34f61ee2014-03-18 20:59:491809 // Wait for the preconnect to complete.
1810 // TODO(davidben): Some way to wait for an idle socket count might be handy.
1811 base::RunLoop().RunUntilIdle();
Matt Menke9d5e2c92019-02-05 01:42:231812 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]a34f61ee2014-03-18 20:59:491813
1814 // Make the request.
1815 TestCompletionCallback callback;
1816
bnc691fda62016-08-12 00:43:161817 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a34f61ee2014-03-18 20:59:491818
tfarina42834112016-09-22 13:38:201819 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011820 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a34f61ee2014-03-18 20:59:491821
1822 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011823 EXPECT_THAT(rv, IsOk());
[email protected]a34f61ee2014-03-18 20:59:491824
1825 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161826 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]09356c652014-03-25 15:36:101827 TestLoadTimingNotReused(
1828 load_timing_info,
1829 CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]a34f61ee2014-03-18 20:59:491830
bnc691fda62016-08-12 00:43:161831 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521832 ASSERT_TRUE(response);
[email protected]a34f61ee2014-03-18 20:59:491833
wezca1070932016-05-26 20:30:521834 EXPECT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:021835 if (response->was_fetched_via_spdy) {
1836 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
1837 } else {
1838 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1839 }
[email protected]a34f61ee2014-03-18 20:59:491840
1841 std::string response_data;
bnc691fda62016-08-12 00:43:161842 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011843 EXPECT_THAT(rv, IsOk());
[email protected]09356c652014-03-25 15:36:101844 EXPECT_EQ(kHttpData, response_data);
[email protected]a34f61ee2014-03-18 20:59:491845}
1846
Biljith Jayan45a41722017-08-16 18:43:141847// Test that we do not retry indefinitely when a server sends an error like
1848// ERR_SPDY_PING_FAILED, ERR_SPDY_SERVER_REFUSED_STREAM,
1849// ERR_QUIC_HANDSHAKE_FAILED or ERR_QUIC_PROTOCOL_ERROR.
1850TEST_F(HttpNetworkTransactionTest, FiniteRetriesOnIOError) {
1851 HttpRequestInfo request;
1852 request.method = "GET";
1853 request.url = GURL("https://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101854 request.traffic_annotation =
1855 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Biljith Jayan45a41722017-08-16 18:43:141856
1857 // Check whether we give up after the third try.
1858
1859 // Construct an HTTP2 request and a "Go away" response.
Ryan Hamilton0239aac2018-05-19 00:03:131860 spdy::SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
Biljith Jayan45a41722017-08-16 18:43:141861 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
Ryan Hamilton0239aac2018-05-19 00:03:131862 spdy::SpdySerializedFrame spdy_response_go_away(
1863 spdy_util_.ConstructSpdyGoAway(0));
Ryan Sleevib8d7ea02018-05-07 20:01:011864 MockRead data_read1[] = {CreateMockRead(spdy_response_go_away)};
1865 MockWrite data_write[] = {CreateMockWrite(spdy_request, 0)};
Biljith Jayan45a41722017-08-16 18:43:141866
1867 // Three go away responses.
Ryan Sleevib8d7ea02018-05-07 20:01:011868 StaticSocketDataProvider data1(data_read1, data_write);
1869 StaticSocketDataProvider data2(data_read1, data_write);
1870 StaticSocketDataProvider data3(data_read1, data_write);
Biljith Jayan45a41722017-08-16 18:43:141871
1872 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1873 AddSSLSocketData();
1874 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1875 AddSSLSocketData();
1876 session_deps_.socket_factory->AddSocketDataProvider(&data3);
1877 AddSSLSocketData();
1878
1879 TestCompletionCallback callback;
1880 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1881 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1882
1883 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1884 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1885
1886 rv = callback.WaitForResult();
1887 EXPECT_THAT(rv, IsError(ERR_SPDY_SERVER_REFUSED_STREAM));
1888}
1889
1890TEST_F(HttpNetworkTransactionTest, RetryTwiceOnIOError) {
1891 HttpRequestInfo request;
1892 request.method = "GET";
1893 request.url = GURL("https://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101894 request.traffic_annotation =
1895 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Biljith Jayan45a41722017-08-16 18:43:141896
1897 // Check whether we try atleast thrice before giving up.
1898
1899 // Construct an HTTP2 request and a "Go away" response.
Ryan Hamilton0239aac2018-05-19 00:03:131900 spdy::SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
Biljith Jayan45a41722017-08-16 18:43:141901 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
Ryan Hamilton0239aac2018-05-19 00:03:131902 spdy::SpdySerializedFrame spdy_response_go_away(
1903 spdy_util_.ConstructSpdyGoAway(0));
Ryan Sleevib8d7ea02018-05-07 20:01:011904 MockRead data_read1[] = {CreateMockRead(spdy_response_go_away)};
1905 MockWrite data_write[] = {CreateMockWrite(spdy_request, 0)};
Biljith Jayan45a41722017-08-16 18:43:141906
1907 // Construct a non error HTTP2 response.
Ryan Hamilton0239aac2018-05-19 00:03:131908 spdy::SpdySerializedFrame spdy_response_no_error(
Biljith Jayan45a41722017-08-16 18:43:141909 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:131910 spdy::SpdySerializedFrame spdy_data(
1911 spdy_util_.ConstructSpdyDataFrame(1, true));
Biljith Jayan45a41722017-08-16 18:43:141912 MockRead data_read2[] = {CreateMockRead(spdy_response_no_error, 1),
1913 CreateMockRead(spdy_data, 2)};
1914
1915 // Two error responses.
Ryan Sleevib8d7ea02018-05-07 20:01:011916 StaticSocketDataProvider data1(data_read1, data_write);
1917 StaticSocketDataProvider data2(data_read1, data_write);
Biljith Jayan45a41722017-08-16 18:43:141918 // Followed by a success response.
Ryan Sleevib8d7ea02018-05-07 20:01:011919 SequencedSocketData data3(data_read2, data_write);
Biljith Jayan45a41722017-08-16 18:43:141920
1921 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1922 AddSSLSocketData();
1923 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1924 AddSSLSocketData();
1925 session_deps_.socket_factory->AddSocketDataProvider(&data3);
1926 AddSSLSocketData();
1927
1928 TestCompletionCallback callback;
1929 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1930 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1931
1932 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1933 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1934
1935 rv = callback.WaitForResult();
1936 EXPECT_THAT(rv, IsOk());
1937}
1938
bncd16676a2016-07-20 16:23:011939TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061940 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]202965992011-12-07 23:04:511941 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1942}
1943
bncd16676a2016-07-20 16:23:011944TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061945 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]202965992011-12-07 23:04:511946 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251947}
1948
bncd16676a2016-07-20 16:23:011949TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061950 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]202965992011-12-07 23:04:511951 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251952}
1953
[email protected]d58ceea82014-06-04 10:55:541954// Make sure that on a 408 response (Request Timeout), the request is retried,
1955// if the socket was a reused keep alive socket.
bncd16676a2016-07-20 16:23:011956TEST_F(HttpNetworkTransactionTest, KeepAlive408) {
[email protected]d58ceea82014-06-04 10:55:541957 MockRead read_failure(SYNCHRONOUS,
1958 "HTTP/1.1 408 Request Timeout\r\n"
1959 "Connection: Keep-Alive\r\n"
1960 "Content-Length: 6\r\n\r\n"
1961 "Pickle");
1962 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1963}
1964
bncd16676a2016-07-20 16:23:011965TEST_F(HttpNetworkTransactionTest, PreconnectErrorNotConnectedOnWrite) {
[email protected]a34f61ee2014-03-18 20:59:491966 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]09356c652014-03-25 15:36:101967 PreconnectErrorResendRequestTest(&write_failure, NULL, false);
[email protected]a34f61ee2014-03-18 20:59:491968}
1969
bncd16676a2016-07-20 16:23:011970TEST_F(HttpNetworkTransactionTest, PreconnectErrorReset) {
[email protected]a34f61ee2014-03-18 20:59:491971 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]09356c652014-03-25 15:36:101972 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
[email protected]a34f61ee2014-03-18 20:59:491973}
1974
bncd16676a2016-07-20 16:23:011975TEST_F(HttpNetworkTransactionTest, PreconnectErrorEOF) {
[email protected]a34f61ee2014-03-18 20:59:491976 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]09356c652014-03-25 15:36:101977 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1978}
1979
bncd16676a2016-07-20 16:23:011980TEST_F(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:101981 MockRead read_failure(ASYNC, OK); // EOF
1982 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1983}
1984
[email protected]d58ceea82014-06-04 10:55:541985// Make sure that on a 408 response (Request Timeout), the request is retried,
1986// if the socket was a preconnected (UNUSED_IDLE) socket.
bncd16676a2016-07-20 16:23:011987TEST_F(HttpNetworkTransactionTest, RetryOnIdle408) {
[email protected]d58ceea82014-06-04 10:55:541988 MockRead read_failure(SYNCHRONOUS,
1989 "HTTP/1.1 408 Request Timeout\r\n"
1990 "Connection: Keep-Alive\r\n"
1991 "Content-Length: 6\r\n\r\n"
1992 "Pickle");
1993 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1994 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1995}
1996
bncd16676a2016-07-20 16:23:011997TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorNotConnectedOnWrite) {
[email protected]09356c652014-03-25 15:36:101998 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1999 PreconnectErrorResendRequestTest(&write_failure, NULL, true);
2000}
2001
bncd16676a2016-07-20 16:23:012002TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
[email protected]09356c652014-03-25 15:36:102003 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
2004 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
2005}
2006
bncd16676a2016-07-20 16:23:012007TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
[email protected]09356c652014-03-25 15:36:102008 MockRead read_failure(SYNCHRONOUS, OK); // EOF
2009 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
2010}
2011
bncd16676a2016-07-20 16:23:012012TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:102013 MockRead read_failure(ASYNC, OK); // EOF
2014 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
[email protected]a34f61ee2014-03-18 20:59:492015}
2016
bncd16676a2016-07-20 16:23:012017TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:422018 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:252019 request.method = "GET";
bncce36dca22015-04-21 22:11:232020 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:102021 request.traffic_annotation =
2022 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3d2a59b2008-09-26 19:44:252023
danakj1fd259a02016-04-16 03:17:092024 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162025 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272026
[email protected]3d2a59b2008-09-26 19:44:252027 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:062028 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:352029 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
2030 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:062031 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:252032 };
Ryan Sleevib8d7ea02018-05-07 20:01:012033 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:072034 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:252035
[email protected]49639fa2011-12-20 23:22:412036 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:252037
tfarina42834112016-09-22 13:38:202038 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012039 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3d2a59b2008-09-26 19:44:252040
2041 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:012042 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:592043
2044 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:162045 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592046 EXPECT_LT(0u, endpoint.address().size());
[email protected]3d2a59b2008-09-26 19:44:252047}
2048
2049// What do various browsers do when the server closes a non-keepalive
2050// connection without sending any response header or body?
2051//
2052// IE7: error page
2053// Safari 3.1.2 (Windows): error page
2054// Firefox 3.0.1: blank page
2055// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:422056// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
2057// Us: error page (EMPTY_RESPONSE)
bncd16676a2016-07-20 16:23:012058TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:252059 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:062060 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:352061 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
2062 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:062063 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:252064 };
Ryan Sleevib8d7ea02018-05-07 20:01:012065 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:012066 EXPECT_THAT(out.rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]3d2a59b2008-09-26 19:44:252067}
[email protected]1826a402014-01-08 15:40:482068
[email protected]7a5378b2012-11-04 03:25:172069// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
2070// tests. There was a bug causing HttpNetworkTransaction to hang in the
2071// destructor in such situations.
2072// See http://crbug.com/154712 and http://crbug.com/156609.
bncd16676a2016-07-20 16:23:012073TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:172074 HttpRequestInfo request;
2075 request.method = "GET";
bncce36dca22015-04-21 22:11:232076 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:102077 request.traffic_annotation =
2078 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7a5378b2012-11-04 03:25:172079
danakj1fd259a02016-04-16 03:17:092080 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:582081 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:192082 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:172083
2084 MockRead data_reads[] = {
2085 MockRead("HTTP/1.0 200 OK\r\n"),
2086 MockRead("Connection: keep-alive\r\n"),
2087 MockRead("Content-Length: 100\r\n\r\n"),
2088 MockRead("hello"),
2089 MockRead(SYNCHRONOUS, 0),
2090 };
Ryan Sleevib8d7ea02018-05-07 20:01:012091 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:072092 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:172093
2094 TestCompletionCallback callback;
2095
tfarina42834112016-09-22 13:38:202096 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012097 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:172098
2099 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:012100 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:172101
Victor Costan9c7302b2018-08-27 16:39:442102 scoped_refptr<IOBufferWithSize> io_buf =
2103 base::MakeRefCounted<IOBufferWithSize>(100);
[email protected]90499482013-06-01 00:39:502104 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:172105 if (rv == ERR_IO_PENDING)
2106 rv = callback.WaitForResult();
2107 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:502108 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
robpercival214763f2016-07-01 23:27:012109 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:172110
2111 trans.reset();
fdoray92e35a72016-06-10 15:54:552112 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:172113 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2114}
2115
bncd16676a2016-07-20 16:23:012116TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:172117 HttpRequestInfo request;
2118 request.method = "GET";
bncce36dca22015-04-21 22:11:232119 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:102120 request.traffic_annotation =
2121 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7a5378b2012-11-04 03:25:172122
danakj1fd259a02016-04-16 03:17:092123 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:582124 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:192125 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:172126
2127 MockRead data_reads[] = {
2128 MockRead("HTTP/1.0 200 OK\r\n"),
2129 MockRead("Connection: keep-alive\r\n"),
2130 MockRead("Content-Length: 100\r\n\r\n"),
2131 MockRead(SYNCHRONOUS, 0),
2132 };
Ryan Sleevib8d7ea02018-05-07 20:01:012133 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:072134 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:172135
2136 TestCompletionCallback callback;
2137
tfarina42834112016-09-22 13:38:202138 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012139 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:172140
2141 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:012142 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:172143
Victor Costan9c7302b2018-08-27 16:39:442144 scoped_refptr<IOBufferWithSize> io_buf(
2145 base::MakeRefCounted<IOBufferWithSize>(100));
[email protected]90499482013-06-01 00:39:502146 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:172147 if (rv == ERR_IO_PENDING)
2148 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:012149 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:172150
2151 trans.reset();
fdoray92e35a72016-06-10 15:54:552152 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:172153 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2154}
2155
[email protected]0b0bf032010-09-21 18:08:502156// Test that we correctly reuse a keep-alive connection after not explicitly
2157// reading the body.
bncd16676a2016-07-20 16:23:012158TEST_F(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:132159 HttpRequestInfo request;
2160 request.method = "GET";
2161 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:102162 request.traffic_annotation =
2163 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]fc31d6a42010-06-24 18:05:132164
vishal.b62985ca92015-04-17 08:45:512165 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:072166 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:092167 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272168
mmenkecc2298e2015-12-07 18:20:182169 const char* request_data =
2170 "GET / HTTP/1.1\r\n"
2171 "Host: www.foo.com\r\n"
2172 "Connection: keep-alive\r\n\r\n";
2173 MockWrite data_writes[] = {
2174 MockWrite(ASYNC, 0, request_data), MockWrite(ASYNC, 2, request_data),
2175 MockWrite(ASYNC, 4, request_data), MockWrite(ASYNC, 6, request_data),
2176 MockWrite(ASYNC, 8, request_data), MockWrite(ASYNC, 10, request_data),
2177 MockWrite(ASYNC, 12, request_data), MockWrite(ASYNC, 14, request_data),
2178 MockWrite(ASYNC, 17, request_data), MockWrite(ASYNC, 20, request_data),
2179 };
2180
[email protected]0b0bf032010-09-21 18:08:502181 // Note that because all these reads happen in the same
2182 // StaticSocketDataProvider, it shows that the same socket is being reused for
2183 // all transactions.
mmenkecc2298e2015-12-07 18:20:182184 MockRead data_reads[] = {
2185 MockRead(ASYNC, 1, "HTTP/1.1 204 No Content\r\n\r\n"),
2186 MockRead(ASYNC, 3, "HTTP/1.1 205 Reset Content\r\n\r\n"),
2187 MockRead(ASYNC, 5, "HTTP/1.1 304 Not Modified\r\n\r\n"),
2188 MockRead(ASYNC, 7,
2189 "HTTP/1.1 302 Found\r\n"
2190 "Content-Length: 0\r\n\r\n"),
2191 MockRead(ASYNC, 9,
2192 "HTTP/1.1 302 Found\r\n"
2193 "Content-Length: 5\r\n\r\n"
2194 "hello"),
2195 MockRead(ASYNC, 11,
2196 "HTTP/1.1 301 Moved Permanently\r\n"
2197 "Content-Length: 0\r\n\r\n"),
2198 MockRead(ASYNC, 13,
2199 "HTTP/1.1 301 Moved Permanently\r\n"
2200 "Content-Length: 5\r\n\r\n"
2201 "hello"),
[email protected]fc31d6a42010-06-24 18:05:132202
mmenkecc2298e2015-12-07 18:20:182203 // In the next two rounds, IsConnectedAndIdle returns false, due to
2204 // the set_busy_before_sync_reads(true) call, while the
2205 // HttpNetworkTransaction is being shut down, but the socket is still
2206 // reuseable. See http://crbug.com/544255.
2207 MockRead(ASYNC, 15,
2208 "HTTP/1.1 200 Hunky-Dory\r\n"
2209 "Content-Length: 5\r\n\r\n"),
2210 MockRead(SYNCHRONOUS, 16, "hello"),
[email protected]fc31d6a42010-06-24 18:05:132211
mmenkecc2298e2015-12-07 18:20:182212 MockRead(ASYNC, 18,
2213 "HTTP/1.1 200 Hunky-Dory\r\n"
2214 "Content-Length: 5\r\n\r\n"
2215 "he"),
2216 MockRead(SYNCHRONOUS, 19, "llo"),
2217
2218 // The body of the final request is actually read.
2219 MockRead(ASYNC, 21, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
2220 MockRead(ASYNC, 22, "hello"),
2221 };
Ryan Sleevib8d7ea02018-05-07 20:01:012222 SequencedSocketData data(data_reads, data_writes);
mmenkecc2298e2015-12-07 18:20:182223 data.set_busy_before_sync_reads(true);
2224 session_deps_.socket_factory->AddSocketDataProvider(&data);
2225
Avi Drissman4365a4782018-12-28 19:26:242226 const int kNumUnreadBodies = base::size(data_writes) - 1;
[email protected]0b0bf032010-09-21 18:08:502227 std::string response_lines[kNumUnreadBodies];
2228
mikecironef22f9812016-10-04 03:40:192229 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
mmenkecc2298e2015-12-07 18:20:182230 for (size_t i = 0; i < kNumUnreadBodies; ++i) {
[email protected]49639fa2011-12-20 23:22:412231 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:132232
Jeremy Roman0579ed62017-08-29 15:56:192233 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
bnc87dcefc2017-05-25 12:47:582234 session.get());
[email protected]fc31d6a42010-06-24 18:05:132235
tfarina42834112016-09-22 13:38:202236 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012237 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]fc31d6a42010-06-24 18:05:132238
[email protected]58e32bb2013-01-21 18:23:252239 LoadTimingInfo load_timing_info;
2240 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2241 if (i == 0) {
2242 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
2243 first_socket_log_id = load_timing_info.socket_log_id;
2244 } else {
2245 TestLoadTimingReused(load_timing_info);
2246 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
2247 }
2248
[email protected]fc31d6a42010-06-24 18:05:132249 const HttpResponseInfo* response = trans->GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182250 ASSERT_TRUE(response);
[email protected]fc31d6a42010-06-24 18:05:132251
mmenkecc2298e2015-12-07 18:20:182252 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502253 response_lines[i] = response->headers->GetStatusLine();
2254
mmenkecc2298e2015-12-07 18:20:182255 // Delete the transaction without reading the response bodies. Then spin
2256 // the message loop, so the response bodies are drained.
2257 trans.reset();
2258 base::RunLoop().RunUntilIdle();
[email protected]fc31d6a42010-06-24 18:05:132259 }
[email protected]0b0bf032010-09-21 18:08:502260
2261 const char* const kStatusLines[] = {
mmenkecc2298e2015-12-07 18:20:182262 "HTTP/1.1 204 No Content",
2263 "HTTP/1.1 205 Reset Content",
2264 "HTTP/1.1 304 Not Modified",
2265 "HTTP/1.1 302 Found",
2266 "HTTP/1.1 302 Found",
2267 "HTTP/1.1 301 Moved Permanently",
2268 "HTTP/1.1 301 Moved Permanently",
2269 "HTTP/1.1 200 Hunky-Dory",
2270 "HTTP/1.1 200 Hunky-Dory",
[email protected]0b0bf032010-09-21 18:08:502271 };
2272
Avi Drissman4365a4782018-12-28 19:26:242273 static_assert(kNumUnreadBodies == base::size(kStatusLines),
mostynb91e0da982015-01-20 19:17:272274 "forgot to update kStatusLines");
[email protected]0b0bf032010-09-21 18:08:502275
2276 for (int i = 0; i < kNumUnreadBodies; ++i)
2277 EXPECT_EQ(kStatusLines[i], response_lines[i]);
2278
[email protected]49639fa2011-12-20 23:22:412279 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:162280 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202281 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012282 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:162283 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182284 ASSERT_TRUE(response);
2285 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502286 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2287 std::string response_data;
bnc691fda62016-08-12 00:43:162288 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:012289 EXPECT_THAT(rv, IsOk());
[email protected]0b0bf032010-09-21 18:08:502290 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:132291}
2292
mmenke5f94fda2016-06-02 20:54:132293// Sockets that receive extra data after a response is complete should not be
2294// reused.
bncd16676a2016-07-20 16:23:012295TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData1) {
mmenke5f94fda2016-06-02 20:54:132296 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2297 MockWrite data_writes1[] = {
2298 MockWrite("HEAD / HTTP/1.1\r\n"
2299 "Host: www.borked.com\r\n"
2300 "Connection: keep-alive\r\n\r\n"),
2301 };
2302
2303 MockRead data_reads1[] = {
2304 MockRead("HTTP/1.1 200 OK\r\n"
2305 "Connection: keep-alive\r\n"
2306 "Content-Length: 22\r\n\r\n"
2307 "This server is borked."),
2308 };
2309
2310 MockWrite data_writes2[] = {
2311 MockWrite("GET /foo HTTP/1.1\r\n"
2312 "Host: www.borked.com\r\n"
2313 "Connection: keep-alive\r\n\r\n"),
2314 };
2315
2316 MockRead data_reads2[] = {
2317 MockRead("HTTP/1.1 200 OK\r\n"
2318 "Content-Length: 3\r\n\r\n"
2319 "foo"),
2320 };
Ryan Sleevib8d7ea02018-05-07 20:01:012321 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke5f94fda2016-06-02 20:54:132322 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:012323 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke5f94fda2016-06-02 20:54:132324 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2325
2326 TestCompletionCallback callback;
2327 HttpRequestInfo request1;
2328 request1.method = "HEAD";
2329 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e62018-02-07 07:41:102330 request1.traffic_annotation =
2331 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132332
bnc87dcefc2017-05-25 12:47:582333 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192334 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202335 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012336 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132337
2338 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2339 ASSERT_TRUE(response1);
2340 ASSERT_TRUE(response1->headers);
2341 EXPECT_EQ(200, response1->headers->response_code());
2342 EXPECT_TRUE(response1->headers->IsKeepAlive());
2343
2344 std::string response_data1;
robpercival214763f2016-07-01 23:27:012345 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132346 EXPECT_EQ("", response_data1);
2347 // Deleting the transaction attempts to release the socket back into the
2348 // socket pool.
2349 trans1.reset();
2350
2351 HttpRequestInfo request2;
2352 request2.method = "GET";
2353 request2.url = GURL("http://www.borked.com/foo");
Ramin Halavatib5e433e62018-02-07 07:41:102354 request2.traffic_annotation =
2355 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132356
bnc87dcefc2017-05-25 12:47:582357 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192358 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202359 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012360 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132361
2362 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2363 ASSERT_TRUE(response2);
2364 ASSERT_TRUE(response2->headers);
2365 EXPECT_EQ(200, response2->headers->response_code());
2366
2367 std::string response_data2;
robpercival214763f2016-07-01 23:27:012368 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132369 EXPECT_EQ("foo", response_data2);
2370}
2371
bncd16676a2016-07-20 16:23:012372TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData2) {
mmenke5f94fda2016-06-02 20:54:132373 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2374 MockWrite data_writes1[] = {
2375 MockWrite("GET / HTTP/1.1\r\n"
2376 "Host: www.borked.com\r\n"
2377 "Connection: keep-alive\r\n\r\n"),
2378 };
2379
2380 MockRead data_reads1[] = {
2381 MockRead("HTTP/1.1 200 OK\r\n"
2382 "Connection: keep-alive\r\n"
2383 "Content-Length: 22\r\n\r\n"
2384 "This server is borked."
2385 "Bonus data!"),
2386 };
2387
2388 MockWrite data_writes2[] = {
2389 MockWrite("GET /foo HTTP/1.1\r\n"
2390 "Host: www.borked.com\r\n"
2391 "Connection: keep-alive\r\n\r\n"),
2392 };
2393
2394 MockRead data_reads2[] = {
2395 MockRead("HTTP/1.1 200 OK\r\n"
2396 "Content-Length: 3\r\n\r\n"
2397 "foo"),
2398 };
Ryan Sleevib8d7ea02018-05-07 20:01:012399 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke5f94fda2016-06-02 20:54:132400 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:012401 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke5f94fda2016-06-02 20:54:132402 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2403
2404 TestCompletionCallback callback;
2405 HttpRequestInfo request1;
2406 request1.method = "GET";
2407 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e62018-02-07 07:41:102408 request1.traffic_annotation =
2409 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132410
bnc87dcefc2017-05-25 12:47:582411 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192412 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202413 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012414 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132415
2416 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2417 ASSERT_TRUE(response1);
2418 ASSERT_TRUE(response1->headers);
2419 EXPECT_EQ(200, response1->headers->response_code());
2420 EXPECT_TRUE(response1->headers->IsKeepAlive());
2421
2422 std::string response_data1;
robpercival214763f2016-07-01 23:27:012423 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132424 EXPECT_EQ("This server is borked.", response_data1);
2425 // Deleting the transaction attempts to release the socket back into the
2426 // socket pool.
2427 trans1.reset();
2428
2429 HttpRequestInfo request2;
2430 request2.method = "GET";
2431 request2.url = GURL("http://www.borked.com/foo");
Ramin Halavatib5e433e62018-02-07 07:41:102432 request2.traffic_annotation =
2433 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132434
bnc87dcefc2017-05-25 12:47:582435 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192436 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202437 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012438 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132439
2440 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2441 ASSERT_TRUE(response2);
2442 ASSERT_TRUE(response2->headers);
2443 EXPECT_EQ(200, response2->headers->response_code());
2444
2445 std::string response_data2;
robpercival214763f2016-07-01 23:27:012446 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132447 EXPECT_EQ("foo", response_data2);
2448}
2449
bncd16676a2016-07-20 16:23:012450TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData3) {
mmenke5f94fda2016-06-02 20:54:132451 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2452 MockWrite data_writes1[] = {
2453 MockWrite("GET / HTTP/1.1\r\n"
2454 "Host: www.borked.com\r\n"
2455 "Connection: keep-alive\r\n\r\n"),
2456 };
2457
2458 MockRead data_reads1[] = {
2459 MockRead("HTTP/1.1 200 OK\r\n"
2460 "Connection: keep-alive\r\n"
2461 "Transfer-Encoding: chunked\r\n\r\n"),
2462 MockRead("16\r\nThis server is borked.\r\n"),
2463 MockRead("0\r\n\r\nBonus data!"),
2464 };
2465
2466 MockWrite data_writes2[] = {
2467 MockWrite("GET /foo HTTP/1.1\r\n"
2468 "Host: www.borked.com\r\n"
2469 "Connection: keep-alive\r\n\r\n"),
2470 };
2471
2472 MockRead data_reads2[] = {
2473 MockRead("HTTP/1.1 200 OK\r\n"
2474 "Content-Length: 3\r\n\r\n"
2475 "foo"),
2476 };
Ryan Sleevib8d7ea02018-05-07 20:01:012477 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke5f94fda2016-06-02 20:54:132478 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:012479 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke5f94fda2016-06-02 20:54:132480 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2481
2482 TestCompletionCallback callback;
2483 HttpRequestInfo request1;
2484 request1.method = "GET";
2485 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e62018-02-07 07:41:102486 request1.traffic_annotation =
2487 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132488
bnc87dcefc2017-05-25 12:47:582489 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192490 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202491 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012492 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132493
2494 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2495 ASSERT_TRUE(response1);
2496 ASSERT_TRUE(response1->headers);
2497 EXPECT_EQ(200, response1->headers->response_code());
2498 EXPECT_TRUE(response1->headers->IsKeepAlive());
2499
2500 std::string response_data1;
robpercival214763f2016-07-01 23:27:012501 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132502 EXPECT_EQ("This server is borked.", response_data1);
2503 // Deleting the transaction attempts to release the socket back into the
2504 // socket pool.
2505 trans1.reset();
2506
2507 HttpRequestInfo request2;
2508 request2.method = "GET";
2509 request2.url = GURL("http://www.borked.com/foo");
Ramin Halavatib5e433e62018-02-07 07:41:102510 request2.traffic_annotation =
2511 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132512
bnc87dcefc2017-05-25 12:47:582513 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192514 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202515 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012516 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132517
2518 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2519 ASSERT_TRUE(response2);
2520 ASSERT_TRUE(response2->headers);
2521 EXPECT_EQ(200, response2->headers->response_code());
2522
2523 std::string response_data2;
robpercival214763f2016-07-01 23:27:012524 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132525 EXPECT_EQ("foo", response_data2);
2526}
2527
2528// This is a little different from the others - it tests the case that the
2529// HttpStreamParser doesn't know if there's extra data on a socket or not when
2530// the HttpNetworkTransaction is torn down, because the response body hasn't
2531// been read from yet, but the request goes through the HttpResponseBodyDrainer.
bncd16676a2016-07-20 16:23:012532TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData4) {
mmenke5f94fda2016-06-02 20:54:132533 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2534 MockWrite data_writes1[] = {
2535 MockWrite("GET / HTTP/1.1\r\n"
2536 "Host: www.borked.com\r\n"
2537 "Connection: keep-alive\r\n\r\n"),
2538 };
2539
2540 MockRead data_reads1[] = {
2541 MockRead("HTTP/1.1 200 OK\r\n"
2542 "Connection: keep-alive\r\n"
2543 "Transfer-Encoding: chunked\r\n\r\n"),
2544 MockRead("16\r\nThis server is borked.\r\n"),
2545 MockRead("0\r\n\r\nBonus data!"),
2546 };
Ryan Sleevib8d7ea02018-05-07 20:01:012547 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke5f94fda2016-06-02 20:54:132548 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2549
2550 TestCompletionCallback callback;
2551 HttpRequestInfo request1;
2552 request1.method = "GET";
2553 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e62018-02-07 07:41:102554 request1.traffic_annotation =
2555 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132556
bnc87dcefc2017-05-25 12:47:582557 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:192558 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
bnc87dcefc2017-05-25 12:47:582559 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012560 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132561
bnc87dcefc2017-05-25 12:47:582562 const HttpResponseInfo* response1 = trans->GetResponseInfo();
mmenke5f94fda2016-06-02 20:54:132563 ASSERT_TRUE(response1);
2564 ASSERT_TRUE(response1->headers);
2565 EXPECT_EQ(200, response1->headers->response_code());
2566 EXPECT_TRUE(response1->headers->IsKeepAlive());
2567
2568 // Deleting the transaction creates an HttpResponseBodyDrainer to read the
2569 // response body.
bnc87dcefc2017-05-25 12:47:582570 trans.reset();
mmenke5f94fda2016-06-02 20:54:132571
2572 // Let the HttpResponseBodyDrainer drain the socket. It should determine the
2573 // socket can't be reused, rather than returning it to the socket pool.
2574 base::RunLoop().RunUntilIdle();
2575
2576 // There should be no idle sockets in the pool.
2577 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2578}
2579
[email protected]038e9a32008-10-08 22:40:162580// Test the request-challenge-retry sequence for basic auth.
2581// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012582TEST_F(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:422583 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:162584 request.method = "GET";
bncce36dca22015-04-21 22:11:232585 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:102586 request.traffic_annotation =
2587 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]038e9a32008-10-08 22:40:162588
vishal.b62985ca92015-04-17 08:45:512589 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072590 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092591 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162592 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272593
[email protected]f9ee6b52008-11-08 06:46:232594 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232595 MockWrite(
2596 "GET / HTTP/1.1\r\n"
2597 "Host: www.example.org\r\n"
2598 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:232599 };
2600
[email protected]038e9a32008-10-08 22:40:162601 MockRead data_reads1[] = {
2602 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2603 // Give a couple authenticate options (only the middle one is actually
2604 // supported).
[email protected]22927ad2009-09-21 19:56:192605 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:162606 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2607 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2608 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2609 // Large content-length -- won't matter, as connection will be reset.
2610 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062611 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:162612 };
2613
2614 // After calling trans->RestartWithAuth(), this is the request we should
2615 // be issuing -- the final header line contains the credentials.
2616 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232617 MockWrite(
2618 "GET / HTTP/1.1\r\n"
2619 "Host: www.example.org\r\n"
2620 "Connection: keep-alive\r\n"
2621 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:162622 };
2623
2624 // Lastly, the server responds with the actual content.
2625 MockRead data_reads2[] = {
2626 MockRead("HTTP/1.0 200 OK\r\n"),
2627 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2628 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062629 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:162630 };
2631
Ryan Sleevib8d7ea02018-05-07 20:01:012632 StaticSocketDataProvider data1(data_reads1, data_writes1);
2633 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:072634 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2635 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:162636
[email protected]49639fa2011-12-20 23:22:412637 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:162638
tfarina42834112016-09-22 13:38:202639 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012640 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162641
2642 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012643 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162644
[email protected]58e32bb2013-01-21 18:23:252645 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162646 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
[email protected]58e32bb2013-01-21 18:23:252647 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2648
Ryan Sleevib8d7ea02018-05-07 20:01:012649 int64_t writes_size1 = CountWriteBytes(data_writes1);
bnc691fda62016-08-12 00:43:162650 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012651 int64_t reads_size1 = CountReadBytes(data_reads1);
bnc691fda62016-08-12 00:43:162652 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192653
bnc691fda62016-08-12 00:43:162654 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522655 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042656 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:162657
[email protected]49639fa2011-12-20 23:22:412658 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:162659
bnc691fda62016-08-12 00:43:162660 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012661 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162662
2663 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012664 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162665
[email protected]58e32bb2013-01-21 18:23:252666 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162667 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
[email protected]58e32bb2013-01-21 18:23:252668 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2669 // The load timing after restart should have a new socket ID, and times after
2670 // those of the first load timing.
2671 EXPECT_LE(load_timing_info1.receive_headers_end,
2672 load_timing_info2.connect_timing.connect_start);
2673 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2674
Ryan Sleevib8d7ea02018-05-07 20:01:012675 int64_t writes_size2 = CountWriteBytes(data_writes2);
bnc691fda62016-08-12 00:43:162676 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012677 int64_t reads_size2 = CountReadBytes(data_reads2);
bnc691fda62016-08-12 00:43:162678 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192679
bnc691fda62016-08-12 00:43:162680 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522681 ASSERT_TRUE(response);
2682 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:162683 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:162684}
2685
ttuttled9dbc652015-09-29 20:00:592686// Test the request-challenge-retry sequence for basic auth.
2687// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012688TEST_F(HttpNetworkTransactionTest, BasicAuthWithAddressChange) {
ttuttled9dbc652015-09-29 20:00:592689 HttpRequestInfo request;
2690 request.method = "GET";
2691 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:102692 request.traffic_annotation =
2693 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttled9dbc652015-09-29 20:00:592694
2695 TestNetLog log;
2696 MockHostResolver* resolver = new MockHostResolver();
2697 session_deps_.net_log = &log;
2698 session_deps_.host_resolver.reset(resolver);
danakj1fd259a02016-04-16 03:17:092699 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
bnc691fda62016-08-12 00:43:162700 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttled9dbc652015-09-29 20:00:592701
2702 resolver->rules()->ClearRules();
2703 resolver->rules()->AddRule("www.example.org", "127.0.0.1");
2704
2705 MockWrite data_writes1[] = {
2706 MockWrite("GET / HTTP/1.1\r\n"
2707 "Host: www.example.org\r\n"
2708 "Connection: keep-alive\r\n\r\n"),
2709 };
2710
2711 MockRead data_reads1[] = {
2712 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2713 // Give a couple authenticate options (only the middle one is actually
2714 // supported).
2715 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
2716 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2717 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2718 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2719 // Large content-length -- won't matter, as connection will be reset.
2720 MockRead("Content-Length: 10000\r\n\r\n"),
2721 MockRead(SYNCHRONOUS, ERR_FAILED),
2722 };
2723
2724 // After calling trans->RestartWithAuth(), this is the request we should
2725 // be issuing -- the final header line contains the credentials.
2726 MockWrite data_writes2[] = {
2727 MockWrite("GET / HTTP/1.1\r\n"
2728 "Host: www.example.org\r\n"
2729 "Connection: keep-alive\r\n"
2730 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2731 };
2732
2733 // Lastly, the server responds with the actual content.
2734 MockRead data_reads2[] = {
2735 MockRead("HTTP/1.0 200 OK\r\n"),
2736 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2737 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, OK),
2738 };
2739
Ryan Sleevib8d7ea02018-05-07 20:01:012740 StaticSocketDataProvider data1(data_reads1, data_writes1);
2741 StaticSocketDataProvider data2(data_reads2, data_writes2);
ttuttled9dbc652015-09-29 20:00:592742 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2743 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2744
2745 TestCompletionCallback callback1;
2746
bnc691fda62016-08-12 00:43:162747 EXPECT_EQ(OK, callback1.GetResult(trans.Start(&request, callback1.callback(),
tfarina42834112016-09-22 13:38:202748 NetLogWithSource())));
ttuttled9dbc652015-09-29 20:00:592749
2750 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162751 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
ttuttled9dbc652015-09-29 20:00:592752 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2753
Ryan Sleevib8d7ea02018-05-07 20:01:012754 int64_t writes_size1 = CountWriteBytes(data_writes1);
bnc691fda62016-08-12 00:43:162755 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012756 int64_t reads_size1 = CountReadBytes(data_reads1);
bnc691fda62016-08-12 00:43:162757 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592758
bnc691fda62016-08-12 00:43:162759 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592760 ASSERT_TRUE(response);
2761 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2762
2763 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:162764 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592765 ASSERT_FALSE(endpoint.address().empty());
2766 EXPECT_EQ("127.0.0.1:80", endpoint.ToString());
2767
2768 resolver->rules()->ClearRules();
2769 resolver->rules()->AddRule("www.example.org", "127.0.0.2");
2770
2771 TestCompletionCallback callback2;
2772
bnc691fda62016-08-12 00:43:162773 EXPECT_EQ(OK, callback2.GetResult(trans.RestartWithAuth(
ttuttled9dbc652015-09-29 20:00:592774 AuthCredentials(kFoo, kBar), callback2.callback())));
2775
2776 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162777 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
ttuttled9dbc652015-09-29 20:00:592778 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2779 // The load timing after restart should have a new socket ID, and times after
2780 // those of the first load timing.
2781 EXPECT_LE(load_timing_info1.receive_headers_end,
2782 load_timing_info2.connect_timing.connect_start);
2783 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2784
Ryan Sleevib8d7ea02018-05-07 20:01:012785 int64_t writes_size2 = CountWriteBytes(data_writes2);
bnc691fda62016-08-12 00:43:162786 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012787 int64_t reads_size2 = CountReadBytes(data_reads2);
bnc691fda62016-08-12 00:43:162788 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592789
bnc691fda62016-08-12 00:43:162790 response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592791 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:522792 EXPECT_FALSE(response->auth_challenge);
ttuttled9dbc652015-09-29 20:00:592793 EXPECT_EQ(100, response->headers->GetContentLength());
2794
bnc691fda62016-08-12 00:43:162795 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592796 ASSERT_FALSE(endpoint.address().empty());
2797 EXPECT_EQ("127.0.0.2:80", endpoint.ToString());
2798}
2799
David Benjamin83ddfb32018-03-30 01:07:522800// Test that, if the server requests auth indefinitely, HttpNetworkTransaction
2801// will eventually give up.
2802TEST_F(HttpNetworkTransactionTest, BasicAuthForever) {
2803 HttpRequestInfo request;
2804 request.method = "GET";
2805 request.url = GURL("http://www.example.org/");
2806 request.traffic_annotation =
2807 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2808
2809 TestNetLog log;
2810 session_deps_.net_log = &log;
2811 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2812 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
2813
2814 MockWrite data_writes[] = {
2815 MockWrite("GET / HTTP/1.1\r\n"
2816 "Host: www.example.org\r\n"
2817 "Connection: keep-alive\r\n\r\n"),
2818 };
2819
2820 MockRead data_reads[] = {
2821 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2822 // Give a couple authenticate options (only the middle one is actually
2823 // supported).
2824 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
2825 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2826 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2827 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2828 // Large content-length -- won't matter, as connection will be reset.
2829 MockRead("Content-Length: 10000\r\n\r\n"),
2830 MockRead(SYNCHRONOUS, ERR_FAILED),
2831 };
2832
2833 // After calling trans->RestartWithAuth(), this is the request we should
2834 // be issuing -- the final header line contains the credentials.
2835 MockWrite data_writes_restart[] = {
2836 MockWrite("GET / HTTP/1.1\r\n"
2837 "Host: www.example.org\r\n"
2838 "Connection: keep-alive\r\n"
2839 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2840 };
2841
Ryan Sleevib8d7ea02018-05-07 20:01:012842 StaticSocketDataProvider data(data_reads, data_writes);
David Benjamin83ddfb32018-03-30 01:07:522843 session_deps_.socket_factory->AddSocketDataProvider(&data);
2844
2845 TestCompletionCallback callback;
2846 int rv = callback.GetResult(
2847 trans.Start(&request, callback.callback(), NetLogWithSource()));
2848
2849 std::vector<std::unique_ptr<StaticSocketDataProvider>> data_restarts;
2850 for (int i = 0; i < 32; i++) {
2851 // Check the previous response was a 401.
2852 EXPECT_THAT(rv, IsOk());
2853 const HttpResponseInfo* response = trans.GetResponseInfo();
2854 ASSERT_TRUE(response);
2855 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2856
2857 data_restarts.push_back(std::make_unique<StaticSocketDataProvider>(
Ryan Sleevib8d7ea02018-05-07 20:01:012858 data_reads, data_writes_restart));
David Benjamin83ddfb32018-03-30 01:07:522859 session_deps_.socket_factory->AddSocketDataProvider(
2860 data_restarts.back().get());
2861 rv = callback.GetResult(trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
2862 callback.callback()));
2863 }
2864
2865 // After too many tries, the transaction should have given up.
2866 EXPECT_THAT(rv, IsError(ERR_TOO_MANY_RETRIES));
2867}
2868
bncd16676a2016-07-20 16:23:012869TEST_F(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:462870 HttpRequestInfo request;
2871 request.method = "GET";
bncce36dca22015-04-21 22:11:232872 request.url = GURL("http://www.example.org/");
ttuttle859dc7a2015-04-23 19:42:292873 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:102874 request.traffic_annotation =
2875 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]861fcd52009-08-26 02:33:462876
danakj1fd259a02016-04-16 03:17:092877 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162878 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272879
[email protected]861fcd52009-08-26 02:33:462880 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:232881 MockWrite(
2882 "GET / HTTP/1.1\r\n"
2883 "Host: www.example.org\r\n"
2884 "Connection: keep-alive\r\n\r\n"),
[email protected]861fcd52009-08-26 02:33:462885 };
2886
2887 MockRead data_reads[] = {
2888 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2889 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2890 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2891 // Large content-length -- won't matter, as connection will be reset.
2892 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062893 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:462894 };
2895
Ryan Sleevib8d7ea02018-05-07 20:01:012896 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:072897 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:412898 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:462899
tfarina42834112016-09-22 13:38:202900 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012901 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]861fcd52009-08-26 02:33:462902
2903 rv = callback.WaitForResult();
2904 EXPECT_EQ(0, rv);
2905
Ryan Sleevib8d7ea02018-05-07 20:01:012906 int64_t writes_size = CountWriteBytes(data_writes);
bnc691fda62016-08-12 00:43:162907 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012908 int64_t reads_size = CountReadBytes(data_reads);
bnc691fda62016-08-12 00:43:162909 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192910
bnc691fda62016-08-12 00:43:162911 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522912 ASSERT_TRUE(response);
2913 EXPECT_FALSE(response->auth_challenge);
[email protected]861fcd52009-08-26 02:33:462914}
2915
[email protected]2d2697f92009-02-18 21:00:322916// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2917// connection.
bncd16676a2016-07-20 16:23:012918TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
mmenkecc2298e2015-12-07 18:20:182919 // On the second pass, the body read of the auth challenge is synchronous, so
2920 // IsConnectedAndIdle returns false. The socket should still be drained and
2921 // reused. See http://crbug.com/544255.
2922 for (int i = 0; i < 2; ++i) {
2923 HttpRequestInfo request;
2924 request.method = "GET";
2925 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:102926 request.traffic_annotation =
2927 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:322928
mmenkecc2298e2015-12-07 18:20:182929 TestNetLog log;
2930 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092931 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272932
mmenkecc2298e2015-12-07 18:20:182933 MockWrite data_writes[] = {
2934 MockWrite(ASYNC, 0,
2935 "GET / HTTP/1.1\r\n"
2936 "Host: www.example.org\r\n"
2937 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322938
bnc691fda62016-08-12 00:43:162939 // After calling trans.RestartWithAuth(), this is the request we should
mmenkecc2298e2015-12-07 18:20:182940 // be issuing -- the final header line contains the credentials.
2941 MockWrite(ASYNC, 6,
2942 "GET / HTTP/1.1\r\n"
2943 "Host: www.example.org\r\n"
2944 "Connection: keep-alive\r\n"
2945 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2946 };
[email protected]2d2697f92009-02-18 21:00:322947
mmenkecc2298e2015-12-07 18:20:182948 MockRead data_reads[] = {
2949 MockRead(ASYNC, 1, "HTTP/1.1 401 Unauthorized\r\n"),
2950 MockRead(ASYNC, 2, "WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2951 MockRead(ASYNC, 3, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2952 MockRead(ASYNC, 4, "Content-Length: 14\r\n\r\n"),
2953 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 5, "Unauthorized\r\n"),
[email protected]2d2697f92009-02-18 21:00:322954
mmenkecc2298e2015-12-07 18:20:182955 // Lastly, the server responds with the actual content.
2956 MockRead(ASYNC, 7, "HTTP/1.1 200 OK\r\n"),
2957 MockRead(ASYNC, 8, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2958 MockRead(ASYNC, 9, "Content-Length: 5\r\n\r\n"),
2959 MockRead(ASYNC, 10, "Hello"),
2960 };
[email protected]2d2697f92009-02-18 21:00:322961
Ryan Sleevib8d7ea02018-05-07 20:01:012962 SequencedSocketData data(data_reads, data_writes);
mmenkecc2298e2015-12-07 18:20:182963 data.set_busy_before_sync_reads(true);
2964 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]2d0a4f92011-05-05 16:38:462965
mmenkecc2298e2015-12-07 18:20:182966 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322967
bnc691fda62016-08-12 00:43:162968 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202969 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012970 ASSERT_THAT(callback1.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322971
mmenkecc2298e2015-12-07 18:20:182972 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162973 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
mmenkecc2298e2015-12-07 18:20:182974 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
[email protected]2d2697f92009-02-18 21:00:322975
bnc691fda62016-08-12 00:43:162976 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182977 ASSERT_TRUE(response);
2978 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322979
mmenkecc2298e2015-12-07 18:20:182980 TestCompletionCallback callback2;
[email protected]58e32bb2013-01-21 18:23:252981
bnc691fda62016-08-12 00:43:162982 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
2983 callback2.callback());
robpercival214763f2016-07-01 23:27:012984 ASSERT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322985
mmenkecc2298e2015-12-07 18:20:182986 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162987 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
mmenkecc2298e2015-12-07 18:20:182988 TestLoadTimingReused(load_timing_info2);
2989 // The load timing after restart should have the same socket ID, and times
2990 // those of the first load timing.
2991 EXPECT_LE(load_timing_info1.receive_headers_end,
2992 load_timing_info2.send_start);
2993 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]2d2697f92009-02-18 21:00:322994
bnc691fda62016-08-12 00:43:162995 response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182996 ASSERT_TRUE(response);
2997 EXPECT_FALSE(response->auth_challenge);
2998 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322999
mmenkecc2298e2015-12-07 18:20:183000 std::string response_data;
bnc691fda62016-08-12 00:43:163001 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]2d2697f92009-02-18 21:00:323002
Ryan Sleevib8d7ea02018-05-07 20:01:013003 int64_t writes_size = CountWriteBytes(data_writes);
bnc691fda62016-08-12 00:43:163004 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:013005 int64_t reads_size = CountReadBytes(data_reads);
bnc691fda62016-08-12 00:43:163006 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
mmenkecc2298e2015-12-07 18:20:183007 }
[email protected]2d2697f92009-02-18 21:00:323008}
3009
3010// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3011// connection and with no response body to drain.
bncd16676a2016-07-20 16:23:013012TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:423013 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:323014 request.method = "GET";
bncce36dca22015-04-21 22:11:233015 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:103016 request.traffic_annotation =
3017 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:323018
danakj1fd259a02016-04-16 03:17:093019 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273020
[email protected]2d2697f92009-02-18 21:00:323021 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:163022 MockWrite("GET / HTTP/1.1\r\n"
3023 "Host: www.example.org\r\n"
3024 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323025
bnc691fda62016-08-12 00:43:163026 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:233027 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:163028 MockWrite("GET / HTTP/1.1\r\n"
3029 "Host: www.example.org\r\n"
3030 "Connection: keep-alive\r\n"
3031 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323032 };
3033
[email protected]2d2697f92009-02-18 21:00:323034 MockRead data_reads1[] = {
3035 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
3036 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:313037 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:323038
3039 // Lastly, the server responds with the actual content.
3040 MockRead("HTTP/1.1 200 OK\r\n"),
3041 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:503042 MockRead("Content-Length: 5\r\n\r\n"),
3043 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:323044 };
3045
[email protected]2d0a4f92011-05-05 16:38:463046 // An incorrect reconnect would cause this to be read.
3047 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:063048 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:463049 };
3050
Ryan Sleevib8d7ea02018-05-07 20:01:013051 StaticSocketDataProvider data1(data_reads1, data_writes1);
3052 StaticSocketDataProvider data2(data_reads2, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:073053 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3054 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:323055
[email protected]49639fa2011-12-20 23:22:413056 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323057
bnc691fda62016-08-12 00:43:163058 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:203059 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013060 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:323061
3062 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013063 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:323064
bnc691fda62016-08-12 00:43:163065 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523066 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:043067 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:323068
[email protected]49639fa2011-12-20 23:22:413069 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323070
bnc691fda62016-08-12 00:43:163071 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013072 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:323073
3074 rv = callback2.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 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523078 ASSERT_TRUE(response);
3079 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503080 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:323081}
3082
3083// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3084// connection and with a large response body to drain.
bncd16676a2016-07-20 16:23:013085TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:423086 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:323087 request.method = "GET";
bncce36dca22015-04-21 22:11:233088 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:103089 request.traffic_annotation =
3090 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:323091
danakj1fd259a02016-04-16 03:17:093092 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273093
[email protected]2d2697f92009-02-18 21:00:323094 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:163095 MockWrite("GET / HTTP/1.1\r\n"
3096 "Host: www.example.org\r\n"
3097 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323098
bnc691fda62016-08-12 00:43:163099 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:233100 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:163101 MockWrite("GET / HTTP/1.1\r\n"
3102 "Host: www.example.org\r\n"
3103 "Connection: keep-alive\r\n"
3104 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323105 };
3106
3107 // Respond with 5 kb of response body.
3108 std::string large_body_string("Unauthorized");
3109 large_body_string.append(5 * 1024, ' ');
3110 large_body_string.append("\r\n");
3111
3112 MockRead data_reads1[] = {
3113 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
3114 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3115 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3116 // 5134 = 12 + 5 * 1024 + 2
3117 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063118 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:323119
3120 // Lastly, the server responds with the actual content.
3121 MockRead("HTTP/1.1 200 OK\r\n"),
3122 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:503123 MockRead("Content-Length: 5\r\n\r\n"),
3124 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:323125 };
3126
[email protected]2d0a4f92011-05-05 16:38:463127 // An incorrect reconnect would cause this to be read.
3128 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:063129 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:463130 };
3131
Ryan Sleevib8d7ea02018-05-07 20:01:013132 StaticSocketDataProvider data1(data_reads1, data_writes1);
3133 StaticSocketDataProvider data2(data_reads2, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:073134 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3135 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:323136
[email protected]49639fa2011-12-20 23:22:413137 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323138
bnc691fda62016-08-12 00:43:163139 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:203140 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013141 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:323142
3143 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013144 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:323145
bnc691fda62016-08-12 00:43:163146 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523147 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:043148 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:323149
[email protected]49639fa2011-12-20 23:22:413150 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323151
bnc691fda62016-08-12 00:43:163152 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013153 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:323154
3155 rv = callback2.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 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523159 ASSERT_TRUE(response);
3160 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503161 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:323162}
3163
3164// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:313165// connection, but the server gets impatient and closes the connection.
bncd16676a2016-07-20 16:23:013166TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:313167 HttpRequestInfo request;
3168 request.method = "GET";
bncce36dca22015-04-21 22:11:233169 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:103170 request.traffic_annotation =
3171 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]11203f012009-11-12 23:02:313172
danakj1fd259a02016-04-16 03:17:093173 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273174
[email protected]11203f012009-11-12 23:02:313175 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233176 MockWrite(
3177 "GET / HTTP/1.1\r\n"
3178 "Host: www.example.org\r\n"
3179 "Connection: keep-alive\r\n\r\n"),
3180 // This simulates the seemingly successful write to a closed connection
3181 // if the bug is not fixed.
3182 MockWrite(
3183 "GET / HTTP/1.1\r\n"
3184 "Host: www.example.org\r\n"
3185 "Connection: keep-alive\r\n"
3186 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:313187 };
3188
3189 MockRead data_reads1[] = {
3190 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
3191 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3192 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3193 MockRead("Content-Length: 14\r\n\r\n"),
3194 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:063195 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:313196 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:063197 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:313198 };
3199
bnc691fda62016-08-12 00:43:163200 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]11203f012009-11-12 23:02:313201 // be issuing -- the final header line contains the credentials.
3202 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:233203 MockWrite(
3204 "GET / HTTP/1.1\r\n"
3205 "Host: www.example.org\r\n"
3206 "Connection: keep-alive\r\n"
3207 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:313208 };
3209
3210 // Lastly, the server responds with the actual content.
3211 MockRead data_reads2[] = {
3212 MockRead("HTTP/1.1 200 OK\r\n"),
3213 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:503214 MockRead("Content-Length: 5\r\n\r\n"),
3215 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:313216 };
3217
Ryan Sleevib8d7ea02018-05-07 20:01:013218 StaticSocketDataProvider data1(data_reads1, data_writes1);
3219 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:073220 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3221 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:313222
[email protected]49639fa2011-12-20 23:22:413223 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:313224
bnc691fda62016-08-12 00:43:163225 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:203226 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013227 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:313228
3229 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013230 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:313231
bnc691fda62016-08-12 00:43:163232 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523233 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:043234 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:313235
[email protected]49639fa2011-12-20 23:22:413236 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:313237
bnc691fda62016-08-12 00:43:163238 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013239 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:313240
3241 rv = callback2.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 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523245 ASSERT_TRUE(response);
3246 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503247 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:313248}
3249
[email protected]394816e92010-08-03 07:38:593250// Test the request-challenge-retry sequence for basic auth, over a connection
3251// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013252TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
ttuttle34f63b52015-03-05 04:33:013253 HttpRequestInfo request;
3254 request.method = "GET";
bncce36dca22015-04-21 22:11:233255 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:013256 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293257 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:103258 request.traffic_annotation =
3259 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle34f63b52015-03-05 04:33:013260
3261 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593262 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493263 ProxyResolutionService::CreateFixedFromPacResult(
3264 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513265 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:013266 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093267 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013268
3269 // Since we have proxy, should try to establish tunnel.
3270 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543271 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173272 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543273 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013274 };
3275
mmenkee71e15332015-10-07 16:39:543276 // The proxy responds to the connect with a 407, using a non-persistent
ttuttle34f63b52015-03-05 04:33:013277 // connection.
3278 MockRead data_reads1[] = {
3279 // No credentials.
3280 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
3281 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
mmenkee71e15332015-10-07 16:39:543282 };
ttuttle34f63b52015-03-05 04:33:013283
mmenkee71e15332015-10-07 16:39:543284 // Since the first connection couldn't be reused, need to establish another
3285 // once given credentials.
3286 MockWrite data_writes2[] = {
3287 // After calling trans->RestartWithAuth(), this is the request we should
3288 // be issuing -- the final header line contains the credentials.
3289 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173290 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543291 "Proxy-Connection: keep-alive\r\n"
3292 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3293
3294 MockWrite("GET / HTTP/1.1\r\n"
3295 "Host: www.example.org\r\n"
3296 "Connection: keep-alive\r\n\r\n"),
3297 };
3298
3299 MockRead data_reads2[] = {
ttuttle34f63b52015-03-05 04:33:013300 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3301
3302 MockRead("HTTP/1.1 200 OK\r\n"),
3303 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3304 MockRead("Content-Length: 5\r\n\r\n"),
3305 MockRead(SYNCHRONOUS, "hello"),
3306 };
3307
Ryan Sleevib8d7ea02018-05-07 20:01:013308 StaticSocketDataProvider data1(data_reads1, data_writes1);
ttuttle34f63b52015-03-05 04:33:013309 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:013310 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenkee71e15332015-10-07 16:39:543311 session_deps_.socket_factory->AddSocketDataProvider(&data2);
ttuttle34f63b52015-03-05 04:33:013312 SSLSocketDataProvider ssl(ASYNC, OK);
3313 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3314
3315 TestCompletionCallback callback1;
3316
bnc87dcefc2017-05-25 12:47:583317 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193318 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013319
3320 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013321 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:013322
3323 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013324 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463325 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:013326 log.GetEntries(&entries);
3327 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003328 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3329 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013330 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003331 entries, pos,
3332 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3333 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013334
3335 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523336 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013337 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523338 ASSERT_TRUE(response->headers);
ttuttle34f63b52015-03-05 04:33:013339 EXPECT_EQ(407, response->headers->response_code());
3340 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3341 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3342
3343 LoadTimingInfo load_timing_info;
3344 // CONNECT requests and responses are handled at the connect job level, so
3345 // the transaction does not yet have a connection.
3346 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3347
3348 TestCompletionCallback callback2;
3349
3350 rv =
3351 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013352 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:013353
3354 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013355 EXPECT_THAT(rv, IsOk());
ttuttle34f63b52015-03-05 04:33:013356
3357 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523358 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013359
3360 EXPECT_TRUE(response->headers->IsKeepAlive());
3361 EXPECT_EQ(200, response->headers->response_code());
3362 EXPECT_EQ(5, response->headers->GetContentLength());
3363 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3364
3365 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523366 EXPECT_FALSE(response->auth_challenge);
ttuttle34f63b52015-03-05 04:33:013367
3368 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3369 TestLoadTimingNotReusedWithPac(load_timing_info,
3370 CONNECT_TIMING_HAS_SSL_TIMES);
3371
3372 trans.reset();
3373 session->CloseAllConnections();
3374}
3375
3376// Test the request-challenge-retry sequence for basic auth, over a connection
3377// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013378TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) {
[email protected]394816e92010-08-03 07:38:593379 HttpRequestInfo request;
3380 request.method = "GET";
bncce36dca22015-04-21 22:11:233381 request.url = GURL("https://www.example.org/");
[email protected]394816e92010-08-03 07:38:593382 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293383 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:103384 request.traffic_annotation =
3385 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]394816e92010-08-03 07:38:593386
[email protected]cb9bf6ca2011-01-28 13:15:273387 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593388 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493389 ProxyResolutionService::CreateFixedFromPacResult(
3390 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513391 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073392 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093393 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273394
[email protected]394816e92010-08-03 07:38:593395 // Since we have proxy, should try to establish tunnel.
3396 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543397 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173398 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543399 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenkee0b5c882015-08-26 20:29:113400 };
3401
mmenkee71e15332015-10-07 16:39:543402 // The proxy responds to the connect with a 407, using a non-persistent
mmenke0fd148d2015-09-30 23:00:083403 // connection.
3404 MockRead data_reads1[] = {
mmenkee71e15332015-10-07 16:39:543405 // No credentials.
3406 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3407 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3408 MockRead("Proxy-Connection: close\r\n\r\n"),
3409 };
mmenkee0b5c882015-08-26 20:29:113410
mmenkee71e15332015-10-07 16:39:543411 MockWrite data_writes2[] = {
3412 // After calling trans->RestartWithAuth(), this is the request we should
3413 // be issuing -- the final header line contains the credentials.
3414 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173415 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543416 "Proxy-Connection: keep-alive\r\n"
3417 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
mmenke0fd148d2015-09-30 23:00:083418
mmenkee71e15332015-10-07 16:39:543419 MockWrite("GET / HTTP/1.1\r\n"
3420 "Host: www.example.org\r\n"
3421 "Connection: keep-alive\r\n\r\n"),
3422 };
3423
3424 MockRead data_reads2[] = {
3425 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3426
3427 MockRead("HTTP/1.1 200 OK\r\n"),
3428 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3429 MockRead("Content-Length: 5\r\n\r\n"),
3430 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:593431 };
3432
Ryan Sleevib8d7ea02018-05-07 20:01:013433 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:073434 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:013435 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenkee71e15332015-10-07 16:39:543436 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8ddf8322012-02-23 18:08:063437 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073438 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:593439
[email protected]49639fa2011-12-20 23:22:413440 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:593441
bnc87dcefc2017-05-25 12:47:583442 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193443 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:503444
[email protected]49639fa2011-12-20 23:22:413445 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013446 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593447
3448 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013449 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463450 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403451 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:593452 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003453 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3454 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593455 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403456 entries, pos,
mikecirone8b85c432016-09-08 19:11:003457 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3458 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593459
3460 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523461 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013462 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523463 ASSERT_TRUE(response->headers);
[email protected]394816e92010-08-03 07:38:593464 EXPECT_EQ(407, response->headers->response_code());
3465 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043466 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:593467
[email protected]029c83b62013-01-24 05:28:203468 LoadTimingInfo load_timing_info;
3469 // CONNECT requests and responses are handled at the connect job level, so
3470 // the transaction does not yet have a connection.
3471 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3472
[email protected]49639fa2011-12-20 23:22:413473 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:593474
[email protected]49639fa2011-12-20 23:22:413475 rv = trans->RestartWithAuth(
3476 AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013477 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593478
3479 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013480 EXPECT_THAT(rv, IsOk());
[email protected]394816e92010-08-03 07:38:593481
3482 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523483 ASSERT_TRUE(response);
[email protected]394816e92010-08-03 07:38:593484
3485 EXPECT_TRUE(response->headers->IsKeepAlive());
3486 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:503487 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:593488 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3489
3490 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523491 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503492
[email protected]029c83b62013-01-24 05:28:203493 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3494 TestLoadTimingNotReusedWithPac(load_timing_info,
3495 CONNECT_TIMING_HAS_SSL_TIMES);
3496
[email protected]0b0bf032010-09-21 18:08:503497 trans.reset();
[email protected]102e27c2011-02-23 01:01:313498 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:593499}
3500
[email protected]11203f012009-11-12 23:02:313501// Test the request-challenge-retry sequence for basic auth, over a keep-alive
ttuttle34f63b52015-03-05 04:33:013502// proxy connection with HTTP/1.0 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013503TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
mmenked39192ee2015-12-09 00:57:233504 // On the second pass, the body read of the auth challenge is synchronous, so
3505 // IsConnectedAndIdle returns false. The socket should still be drained and
3506 // reused. See http://crbug.com/544255.
3507 for (int i = 0; i < 2; ++i) {
3508 HttpRequestInfo request;
3509 request.method = "GET";
3510 request.url = GURL("https://www.example.org/");
3511 // Ensure that proxy authentication is attempted even
3512 // when the no authentication data flag is set.
3513 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:103514 request.traffic_annotation =
3515 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle34f63b52015-03-05 04:33:013516
mmenked39192ee2015-12-09 00:57:233517 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593518 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493519 ProxyResolutionService::CreateFixed("myproxy:70",
3520 TRAFFIC_ANNOTATION_FOR_TESTS);
mmenked39192ee2015-12-09 00:57:233521 BoundTestNetLog log;
3522 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093523 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013524
bnc691fda62016-08-12 00:43:163525 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013526
mmenked39192ee2015-12-09 00:57:233527 // Since we have proxy, should try to establish tunnel.
3528 MockWrite data_writes1[] = {
3529 MockWrite(ASYNC, 0,
3530 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3531 "Host: www.example.org:443\r\n"
3532 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013533
bnc691fda62016-08-12 00:43:163534 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233535 // be issuing -- the final header line contains the credentials.
3536 MockWrite(ASYNC, 3,
3537 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3538 "Host: www.example.org:443\r\n"
3539 "Proxy-Connection: keep-alive\r\n"
3540 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3541 };
ttuttle34f63b52015-03-05 04:33:013542
mmenked39192ee2015-12-09 00:57:233543 // The proxy responds to the connect with a 407, using a persistent
3544 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3545 MockRead data_reads1[] = {
3546 // No credentials.
3547 MockRead(ASYNC, 1,
3548 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3549 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3550 "Proxy-Connection: keep-alive\r\n"
3551 "Content-Length: 10\r\n\r\n"),
3552 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
ttuttle34f63b52015-03-05 04:33:013553
mmenked39192ee2015-12-09 00:57:233554 // Wrong credentials (wrong password).
3555 MockRead(ASYNC, 4,
3556 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3557 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3558 "Proxy-Connection: keep-alive\r\n"
3559 "Content-Length: 10\r\n\r\n"),
3560 // No response body because the test stops reading here.
3561 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3562 };
ttuttle34f63b52015-03-05 04:33:013563
Ryan Sleevib8d7ea02018-05-07 20:01:013564 SequencedSocketData data1(data_reads1, data_writes1);
mmenked39192ee2015-12-09 00:57:233565 data1.set_busy_before_sync_reads(true);
3566 session_deps_.socket_factory->AddSocketDataProvider(&data1);
ttuttle34f63b52015-03-05 04:33:013567
mmenked39192ee2015-12-09 00:57:233568 TestCompletionCallback callback1;
ttuttle34f63b52015-03-05 04:33:013569
bnc691fda62016-08-12 00:43:163570 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013571 EXPECT_THAT(callback1.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013572
mmenked39192ee2015-12-09 00:57:233573 TestNetLogEntry::List entries;
3574 log.GetEntries(&entries);
3575 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003576 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3577 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233578 ExpectLogContainsSomewhere(
3579 entries, pos,
mikecirone8b85c432016-09-08 19:11:003580 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3581 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013582
bnc691fda62016-08-12 00:43:163583 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233584 ASSERT_TRUE(response);
3585 ASSERT_TRUE(response->headers);
3586 EXPECT_TRUE(response->headers->IsKeepAlive());
3587 EXPECT_EQ(407, response->headers->response_code());
3588 EXPECT_EQ(10, response->headers->GetContentLength());
3589 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3590 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013591
mmenked39192ee2015-12-09 00:57:233592 TestCompletionCallback callback2;
ttuttle34f63b52015-03-05 04:33:013593
mmenked39192ee2015-12-09 00:57:233594 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163595 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3596 callback2.callback());
robpercival214763f2016-07-01 23:27:013597 EXPECT_THAT(callback2.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013598
bnc691fda62016-08-12 00:43:163599 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233600 ASSERT_TRUE(response);
3601 ASSERT_TRUE(response->headers);
3602 EXPECT_TRUE(response->headers->IsKeepAlive());
3603 EXPECT_EQ(407, response->headers->response_code());
3604 EXPECT_EQ(10, response->headers->GetContentLength());
3605 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3606 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013607
mmenked39192ee2015-12-09 00:57:233608 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3609 // out of scope.
3610 session->CloseAllConnections();
3611 }
ttuttle34f63b52015-03-05 04:33:013612}
3613
3614// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3615// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013616TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
mmenked39192ee2015-12-09 00:57:233617 // On the second pass, the body read of the auth challenge is synchronous, so
3618 // IsConnectedAndIdle returns false. The socket should still be drained and
3619 // reused. See http://crbug.com/544255.
3620 for (int i = 0; i < 2; ++i) {
3621 HttpRequestInfo request;
3622 request.method = "GET";
3623 request.url = GURL("https://www.example.org/");
3624 // Ensure that proxy authentication is attempted even
3625 // when the no authentication data flag is set.
3626 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:103627 request.traffic_annotation =
3628 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenked39192ee2015-12-09 00:57:233629
3630 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593631 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493632 ProxyResolutionService::CreateFixed("myproxy:70",
3633 TRAFFIC_ANNOTATION_FOR_TESTS);
mmenked39192ee2015-12-09 00:57:233634 BoundTestNetLog log;
3635 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093636 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenked39192ee2015-12-09 00:57:233637
bnc691fda62016-08-12 00:43:163638 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenked39192ee2015-12-09 00:57:233639
3640 // Since we have proxy, should try to establish tunnel.
3641 MockWrite data_writes1[] = {
3642 MockWrite(ASYNC, 0,
3643 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3644 "Host: www.example.org:443\r\n"
3645 "Proxy-Connection: keep-alive\r\n\r\n"),
3646
bnc691fda62016-08-12 00:43:163647 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233648 // be issuing -- the final header line contains the credentials.
3649 MockWrite(ASYNC, 3,
3650 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3651 "Host: www.example.org:443\r\n"
3652 "Proxy-Connection: keep-alive\r\n"
3653 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3654 };
3655
3656 // The proxy responds to the connect with a 407, using a persistent
3657 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3658 MockRead data_reads1[] = {
3659 // No credentials.
3660 MockRead(ASYNC, 1,
3661 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3662 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3663 "Content-Length: 10\r\n\r\n"),
3664 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
3665
3666 // Wrong credentials (wrong password).
3667 MockRead(ASYNC, 4,
3668 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3669 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3670 "Content-Length: 10\r\n\r\n"),
3671 // No response body because the test stops reading here.
3672 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3673 };
3674
Ryan Sleevib8d7ea02018-05-07 20:01:013675 SequencedSocketData data1(data_reads1, data_writes1);
mmenked39192ee2015-12-09 00:57:233676 data1.set_busy_before_sync_reads(true);
3677 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3678
3679 TestCompletionCallback callback1;
3680
bnc691fda62016-08-12 00:43:163681 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013682 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233683
3684 TestNetLogEntry::List entries;
3685 log.GetEntries(&entries);
3686 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003687 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3688 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233689 ExpectLogContainsSomewhere(
3690 entries, pos,
mikecirone8b85c432016-09-08 19:11:003691 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3692 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233693
bnc691fda62016-08-12 00:43:163694 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233695 ASSERT_TRUE(response);
3696 ASSERT_TRUE(response->headers);
3697 EXPECT_TRUE(response->headers->IsKeepAlive());
3698 EXPECT_EQ(407, response->headers->response_code());
3699 EXPECT_EQ(10, response->headers->GetContentLength());
3700 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3701 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3702
3703 TestCompletionCallback callback2;
3704
3705 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163706 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3707 callback2.callback());
robpercival214763f2016-07-01 23:27:013708 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233709
bnc691fda62016-08-12 00:43:163710 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233711 ASSERT_TRUE(response);
3712 ASSERT_TRUE(response->headers);
3713 EXPECT_TRUE(response->headers->IsKeepAlive());
3714 EXPECT_EQ(407, response->headers->response_code());
3715 EXPECT_EQ(10, response->headers->GetContentLength());
3716 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3717 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3718
3719 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3720 // out of scope.
3721 session->CloseAllConnections();
3722 }
3723}
3724
3725// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3726// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel, in
3727// the case the server sends extra data on the original socket, so it can't be
3728// reused.
bncd16676a2016-07-20 16:23:013729TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveExtraData) {
[email protected]cb9bf6ca2011-01-28 13:15:273730 HttpRequestInfo request;
3731 request.method = "GET";
bncce36dca22015-04-21 22:11:233732 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273733 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293734 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:103735 request.traffic_annotation =
3736 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:273737
[email protected]2d2697f92009-02-18 21:00:323738 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593739 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493740 ProxyResolutionService::CreateFixedFromPacResult(
3741 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513742 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073743 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093744 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:323745
[email protected]2d2697f92009-02-18 21:00:323746 // Since we have proxy, should try to establish tunnel.
3747 MockWrite data_writes1[] = {
mmenked39192ee2015-12-09 00:57:233748 MockWrite(ASYNC, 0,
3749 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173750 "Host: www.example.org:443\r\n"
3751 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233752 };
[email protected]2d2697f92009-02-18 21:00:323753
mmenked39192ee2015-12-09 00:57:233754 // The proxy responds to the connect with a 407, using a persistent, but sends
3755 // extra data, so the socket cannot be reused.
3756 MockRead data_reads1[] = {
3757 // No credentials.
3758 MockRead(ASYNC, 1,
3759 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3760 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3761 "Content-Length: 10\r\n\r\n"),
3762 MockRead(SYNCHRONOUS, 2, "0123456789"),
3763 MockRead(SYNCHRONOUS, 3, "I'm broken!"),
3764 };
3765
3766 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:233767 // After calling trans->RestartWithAuth(), this is the request we should
3768 // be issuing -- the final header line contains the credentials.
mmenked39192ee2015-12-09 00:57:233769 MockWrite(ASYNC, 0,
3770 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173771 "Host: www.example.org:443\r\n"
3772 "Proxy-Connection: keep-alive\r\n"
mmenked39192ee2015-12-09 00:57:233773 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3774
3775 MockWrite(ASYNC, 2,
3776 "GET / HTTP/1.1\r\n"
3777 "Host: www.example.org\r\n"
3778 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323779 };
3780
mmenked39192ee2015-12-09 00:57:233781 MockRead data_reads2[] = {
3782 MockRead(ASYNC, 1, "HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323783
mmenked39192ee2015-12-09 00:57:233784 MockRead(ASYNC, 3,
3785 "HTTP/1.1 200 OK\r\n"
3786 "Content-Type: text/html; charset=iso-8859-1\r\n"
3787 "Content-Length: 5\r\n\r\n"),
3788 // No response body because the test stops reading here.
3789 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 4),
[email protected]2d2697f92009-02-18 21:00:323790 };
3791
Ryan Sleevib8d7ea02018-05-07 20:01:013792 SequencedSocketData data1(data_reads1, data_writes1);
mmenked39192ee2015-12-09 00:57:233793 data1.set_busy_before_sync_reads(true);
[email protected]bb88e1d32013-05-03 23:11:073794 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:013795 SequencedSocketData data2(data_reads2, data_writes2);
mmenked39192ee2015-12-09 00:57:233796 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3797 SSLSocketDataProvider ssl(ASYNC, OK);
3798 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d2697f92009-02-18 21:00:323799
[email protected]49639fa2011-12-20 23:22:413800 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323801
bnc87dcefc2017-05-25 12:47:583802 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193803 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d2697f92009-02-18 21:00:323804
mmenked39192ee2015-12-09 00:57:233805 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013806 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233807
mmenke43758e62015-05-04 21:09:463808 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403809 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:393810 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003811 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3812 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:393813 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403814 entries, pos,
mikecirone8b85c432016-09-08 19:11:003815 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3816 NetLogEventPhase::NONE);
[email protected]2d2697f92009-02-18 21:00:323817
[email protected]1c773ea12009-04-28 19:58:423818 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243819 ASSERT_TRUE(response);
3820 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:323821 EXPECT_TRUE(response->headers->IsKeepAlive());
3822 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423823 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043824 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:323825
mmenked39192ee2015-12-09 00:57:233826 LoadTimingInfo load_timing_info;
3827 // CONNECT requests and responses are handled at the connect job level, so
3828 // the transaction does not yet have a connection.
3829 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3830
[email protected]49639fa2011-12-20 23:22:413831 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323832
mmenked39192ee2015-12-09 00:57:233833 rv =
3834 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013835 EXPECT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:323836
[email protected]2d2697f92009-02-18 21:00:323837 EXPECT_TRUE(response->headers->IsKeepAlive());
mmenked39192ee2015-12-09 00:57:233838 EXPECT_EQ(200, response->headers->response_code());
3839 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:423840 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]e772db3f2010-07-12 18:11:133841
mmenked39192ee2015-12-09 00:57:233842 // The password prompt info should not be set.
3843 EXPECT_FALSE(response->auth_challenge);
3844
3845 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3846 TestLoadTimingNotReusedWithPac(load_timing_info,
3847 CONNECT_TIMING_HAS_SSL_TIMES);
3848
3849 trans.reset();
[email protected]102e27c2011-02-23 01:01:313850 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:323851}
3852
mmenkee71e15332015-10-07 16:39:543853// Test the case a proxy closes a socket while the challenge body is being
3854// drained.
bncd16676a2016-07-20 16:23:013855TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHangupDuringBody) {
mmenkee71e15332015-10-07 16:39:543856 HttpRequestInfo request;
3857 request.method = "GET";
3858 request.url = GURL("https://www.example.org/");
3859 // Ensure that proxy authentication is attempted even
3860 // when the no authentication data flag is set.
3861 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:103862 request.traffic_annotation =
3863 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenkee71e15332015-10-07 16:39:543864
3865 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:493866 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
3867 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:093868 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenkee71e15332015-10-07 16:39:543869
bnc691fda62016-08-12 00:43:163870 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkee71e15332015-10-07 16:39:543871
3872 // Since we have proxy, should try to establish tunnel.
3873 MockWrite data_writes1[] = {
3874 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173875 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543876 "Proxy-Connection: keep-alive\r\n\r\n"),
3877 };
3878
3879 // The proxy responds to the connect with a 407, using a persistent
3880 // connection.
3881 MockRead data_reads1[] = {
3882 // No credentials.
3883 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3884 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3885 MockRead("Content-Length: 10\r\n\r\n"), MockRead("spam!"),
3886 // Server hands up in the middle of the body.
3887 MockRead(ASYNC, ERR_CONNECTION_CLOSED),
3888 };
3889
3890 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:163891 // After calling trans.RestartWithAuth(), this is the request we should
mmenkee71e15332015-10-07 16:39:543892 // be issuing -- the final header line contains the credentials.
3893 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173894 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543895 "Proxy-Connection: keep-alive\r\n"
3896 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3897
3898 MockWrite("GET / HTTP/1.1\r\n"
3899 "Host: www.example.org\r\n"
3900 "Connection: keep-alive\r\n\r\n"),
3901 };
3902
3903 MockRead data_reads2[] = {
3904 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3905
3906 MockRead("HTTP/1.1 200 OK\r\n"),
3907 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3908 MockRead("Content-Length: 5\r\n\r\n"),
3909 MockRead(SYNCHRONOUS, "hello"),
3910 };
3911
Ryan Sleevib8d7ea02018-05-07 20:01:013912 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenkee71e15332015-10-07 16:39:543913 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:013914 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenkee71e15332015-10-07 16:39:543915 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3916 SSLSocketDataProvider ssl(ASYNC, OK);
3917 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3918
3919 TestCompletionCallback callback;
3920
tfarina42834112016-09-22 13:38:203921 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013922 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543923
bnc691fda62016-08-12 00:43:163924 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543925 ASSERT_TRUE(response);
3926 ASSERT_TRUE(response->headers);
3927 EXPECT_TRUE(response->headers->IsKeepAlive());
3928 EXPECT_EQ(407, response->headers->response_code());
3929 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3930
bnc691fda62016-08-12 00:43:163931 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
robpercival214763f2016-07-01 23:27:013932 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543933
bnc691fda62016-08-12 00:43:163934 response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543935 ASSERT_TRUE(response);
3936 ASSERT_TRUE(response->headers);
3937 EXPECT_TRUE(response->headers->IsKeepAlive());
3938 EXPECT_EQ(200, response->headers->response_code());
3939 std::string body;
bnc691fda62016-08-12 00:43:163940 EXPECT_THAT(ReadTransaction(&trans, &body), IsOk());
mmenkee71e15332015-10-07 16:39:543941 EXPECT_EQ("hello", body);
3942}
3943
[email protected]a8e9b162009-03-12 00:06:443944// Test that we don't read the response body when we fail to establish a tunnel,
3945// even if the user cancels the proxy's auth attempt.
bncd16676a2016-07-20 16:23:013946TEST_F(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:273947 HttpRequestInfo request;
3948 request.method = "GET";
bncce36dca22015-04-21 22:11:233949 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:103950 request.traffic_annotation =
3951 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:273952
[email protected]a8e9b162009-03-12 00:06:443953 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:493954 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
3955 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]a8e9b162009-03-12 00:06:443956
danakj1fd259a02016-04-16 03:17:093957 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:443958
bnc691fda62016-08-12 00:43:163959 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a8e9b162009-03-12 00:06:443960
[email protected]a8e9b162009-03-12 00:06:443961 // Since we have proxy, should try to establish tunnel.
3962 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173963 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3964 "Host: www.example.org:443\r\n"
3965 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:443966 };
3967
3968 // The proxy responds to the connect with a 407.
3969 MockRead data_reads[] = {
ttuttle7933c112015-01-06 00:55:243970 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3971 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3972 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233973 MockRead("0123456789"),
ttuttle7933c112015-01-06 00:55:243974 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]a8e9b162009-03-12 00:06:443975 };
3976
Ryan Sleevib8d7ea02018-05-07 20:01:013977 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:073978 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:443979
[email protected]49639fa2011-12-20 23:22:413980 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:443981
tfarina42834112016-09-22 13:38:203982 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013983 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a8e9b162009-03-12 00:06:443984
3985 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013986 EXPECT_THAT(rv, IsOk());
[email protected]a8e9b162009-03-12 00:06:443987
bnc691fda62016-08-12 00:43:163988 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243989 ASSERT_TRUE(response);
3990 ASSERT_TRUE(response->headers);
[email protected]a8e9b162009-03-12 00:06:443991 EXPECT_TRUE(response->headers->IsKeepAlive());
3992 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423993 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:443994
3995 std::string response_data;
bnc691fda62016-08-12 00:43:163996 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:013997 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]e60e47a2010-07-14 03:37:183998
3999 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:314000 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:444001}
4002
ttuttle7933c112015-01-06 00:55:244003// Test that we don't pass extraneous headers from the proxy's response to the
4004// caller when the proxy responds to CONNECT with 407.
bncd16676a2016-07-20 16:23:014005TEST_F(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
ttuttle7933c112015-01-06 00:55:244006 HttpRequestInfo request;
4007 request.method = "GET";
bncce36dca22015-04-21 22:11:234008 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104009 request.traffic_annotation =
4010 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle7933c112015-01-06 00:55:244011
4012 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:494013 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
4014 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle7933c112015-01-06 00:55:244015
danakj1fd259a02016-04-16 03:17:094016 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle7933c112015-01-06 00:55:244017
bnc691fda62016-08-12 00:43:164018 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle7933c112015-01-06 00:55:244019
4020 // Since we have proxy, should try to establish tunnel.
4021 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:174022 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4023 "Host: www.example.org:443\r\n"
4024 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle7933c112015-01-06 00:55:244025 };
4026
4027 // The proxy responds to the connect with a 407.
4028 MockRead data_reads[] = {
4029 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4030 MockRead("X-Foo: bar\r\n"),
4031 MockRead("Set-Cookie: foo=bar\r\n"),
4032 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4033 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:234034 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
ttuttle7933c112015-01-06 00:55:244035 };
4036
Ryan Sleevib8d7ea02018-05-07 20:01:014037 StaticSocketDataProvider data(data_reads, data_writes);
ttuttle7933c112015-01-06 00:55:244038 session_deps_.socket_factory->AddSocketDataProvider(&data);
4039
4040 TestCompletionCallback callback;
4041
tfarina42834112016-09-22 13:38:204042 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014043 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle7933c112015-01-06 00:55:244044
4045 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:014046 EXPECT_THAT(rv, IsOk());
ttuttle7933c112015-01-06 00:55:244047
bnc691fda62016-08-12 00:43:164048 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:244049 ASSERT_TRUE(response);
4050 ASSERT_TRUE(response->headers);
4051 EXPECT_TRUE(response->headers->IsKeepAlive());
4052 EXPECT_EQ(407, response->headers->response_code());
4053 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4054 EXPECT_FALSE(response->headers->HasHeader("X-Foo"));
4055 EXPECT_FALSE(response->headers->HasHeader("Set-Cookie"));
4056
4057 std::string response_data;
bnc691fda62016-08-12 00:43:164058 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:014059 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
ttuttle7933c112015-01-06 00:55:244060
4061 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
4062 session->CloseAllConnections();
4063}
4064
[email protected]8fdbcd22010-05-05 02:54:524065// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
4066// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
bncd16676a2016-07-20 16:23:014067TEST_F(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:524068 HttpRequestInfo request;
4069 request.method = "GET";
bncce36dca22015-04-21 22:11:234070 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104071 request.traffic_annotation =
4072 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8fdbcd22010-05-05 02:54:524073
[email protected]cb9bf6ca2011-01-28 13:15:274074 // We are using a DIRECT connection (i.e. no proxy) for this session.
danakj1fd259a02016-04-16 03:17:094075 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:164076 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:274077
[email protected]8fdbcd22010-05-05 02:54:524078 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:234079 MockWrite(
4080 "GET / HTTP/1.1\r\n"
4081 "Host: www.example.org\r\n"
4082 "Connection: keep-alive\r\n\r\n"),
[email protected]8fdbcd22010-05-05 02:54:524083 };
4084
4085 MockRead data_reads1[] = {
4086 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
4087 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4088 // Large content-length -- won't matter, as connection will be reset.
4089 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064090 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:524091 };
4092
Ryan Sleevib8d7ea02018-05-07 20:01:014093 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:074094 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:524095
[email protected]49639fa2011-12-20 23:22:414096 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:524097
tfarina42834112016-09-22 13:38:204098 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014099 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8fdbcd22010-05-05 02:54:524100
4101 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:014102 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
[email protected]8fdbcd22010-05-05 02:54:524103}
4104
[email protected]7a67a8152010-11-05 18:31:104105// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
4106// through a non-authenticating proxy. The request should fail with
4107// ERR_UNEXPECTED_PROXY_AUTH.
4108// Note that it is impossible to detect if an HTTP server returns a 407 through
4109// a non-authenticating proxy - there is nothing to indicate whether the
4110// response came from the proxy or the server, so it is treated as if the proxy
4111// issued the challenge.
bncd16676a2016-07-20 16:23:014112TEST_F(HttpNetworkTransactionTest, HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:274113 HttpRequestInfo request;
4114 request.method = "GET";
bncce36dca22015-04-21 22:11:234115 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104116 request.traffic_annotation =
4117 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:274118
Ramin Halavatica8d5252018-03-12 05:33:494119 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
4120 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:514121 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074122 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094123 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:104124
[email protected]7a67a8152010-11-05 18:31:104125 // Since we have proxy, should try to establish tunnel.
4126 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174127 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4128 "Host: www.example.org:443\r\n"
4129 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:104130
rsleevidb16bb02015-11-12 23:47:174131 MockWrite("GET / HTTP/1.1\r\n"
4132 "Host: www.example.org\r\n"
4133 "Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:104134 };
4135
4136 MockRead data_reads1[] = {
4137 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4138
4139 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
4140 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4141 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:064142 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:104143 };
4144
Ryan Sleevib8d7ea02018-05-07 20:01:014145 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:074146 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:064147 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074148 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:104149
[email protected]49639fa2011-12-20 23:22:414150 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:104151
bnc691fda62016-08-12 00:43:164152 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]7a67a8152010-11-05 18:31:104153
bnc691fda62016-08-12 00:43:164154 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014155 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a67a8152010-11-05 18:31:104156
4157 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014158 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
mmenke43758e62015-05-04 21:09:464159 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:404160 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:104161 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:004162 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
4163 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:104164 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:404165 entries, pos,
mikecirone8b85c432016-09-08 19:11:004166 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
4167 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:104168}
[email protected]2df19bb2010-08-25 20:13:464169
mmenke2a1781d2015-10-07 19:25:334170// Test a proxy auth scheme that allows default credentials and a proxy server
4171// that uses non-persistent connections.
bncd16676a2016-07-20 16:23:014172TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334173 AuthAllowsDefaultCredentialsTunnelConnectionClose) {
4174 HttpRequestInfo request;
4175 request.method = "GET";
4176 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104177 request.traffic_annotation =
4178 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334179
4180 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594181 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494182 ProxyResolutionService::CreateFixedFromPacResult(
4183 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334184
Jeremy Roman0579ed62017-08-29 15:56:194185 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334186 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194187 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334188 mock_handler->set_allows_default_credentials(true);
4189 auth_handler_factory->AddMockHandler(mock_handler.release(),
4190 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484191 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334192
4193 // Add NetLog just so can verify load timing information gets a NetLog ID.
4194 NetLog net_log;
4195 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094196 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334197
4198 // Since we have proxy, should try to establish tunnel.
4199 MockWrite data_writes1[] = {
4200 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174201 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334202 "Proxy-Connection: keep-alive\r\n\r\n"),
4203 };
4204
4205 // The proxy responds to the connect with a 407, using a non-persistent
4206 // connection.
4207 MockRead data_reads1[] = {
4208 // No credentials.
4209 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4210 MockRead("Proxy-Authenticate: Mock\r\n"),
4211 MockRead("Proxy-Connection: close\r\n\r\n"),
4212 };
4213
4214 // Since the first connection couldn't be reused, need to establish another
4215 // once given credentials.
4216 MockWrite data_writes2[] = {
4217 // After calling trans->RestartWithAuth(), this is the request we should
4218 // be issuing -- the final header line contains the credentials.
4219 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174220 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334221 "Proxy-Connection: keep-alive\r\n"
4222 "Proxy-Authorization: auth_token\r\n\r\n"),
4223
4224 MockWrite("GET / HTTP/1.1\r\n"
4225 "Host: www.example.org\r\n"
4226 "Connection: keep-alive\r\n\r\n"),
4227 };
4228
4229 MockRead data_reads2[] = {
4230 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
4231
4232 MockRead("HTTP/1.1 200 OK\r\n"),
4233 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4234 MockRead("Content-Length: 5\r\n\r\n"),
4235 MockRead(SYNCHRONOUS, "hello"),
4236 };
4237
Ryan Sleevib8d7ea02018-05-07 20:01:014238 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke2a1781d2015-10-07 19:25:334239 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:014240 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke2a1781d2015-10-07 19:25:334241 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4242 SSLSocketDataProvider ssl(ASYNC, OK);
4243 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4244
bnc87dcefc2017-05-25 12:47:584245 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194246 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334247
4248 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204249 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014250 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334251
4252 const HttpResponseInfo* response = trans->GetResponseInfo();
4253 ASSERT_TRUE(response);
4254 ASSERT_TRUE(response->headers);
4255 EXPECT_FALSE(response->headers->IsKeepAlive());
4256 EXPECT_EQ(407, response->headers->response_code());
4257 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4258 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
wezca1070932016-05-26 20:30:524259 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:334260
4261 LoadTimingInfo load_timing_info;
4262 // CONNECT requests and responses are handled at the connect job level, so
4263 // the transaction does not yet have a connection.
4264 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4265
4266 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014267 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334268 response = trans->GetResponseInfo();
4269 ASSERT_TRUE(response);
4270 ASSERT_TRUE(response->headers);
4271 EXPECT_TRUE(response->headers->IsKeepAlive());
4272 EXPECT_EQ(200, response->headers->response_code());
4273 EXPECT_EQ(5, response->headers->GetContentLength());
4274 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4275
4276 // The password prompt info should not be set.
4277 EXPECT_FALSE(response->auth_challenge);
4278
4279 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4280 TestLoadTimingNotReusedWithPac(load_timing_info,
4281 CONNECT_TIMING_HAS_SSL_TIMES);
4282
4283 trans.reset();
4284 session->CloseAllConnections();
4285}
4286
4287// Test a proxy auth scheme that allows default credentials and a proxy server
4288// that hangs up when credentials are initially sent.
bncd16676a2016-07-20 16:23:014289TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334290 AuthAllowsDefaultCredentialsTunnelServerClosesConnection) {
4291 HttpRequestInfo request;
4292 request.method = "GET";
4293 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104294 request.traffic_annotation =
4295 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334296
4297 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594298 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494299 ProxyResolutionService::CreateFixedFromPacResult(
4300 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334301
Jeremy Roman0579ed62017-08-29 15:56:194302 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334303 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194304 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334305 mock_handler->set_allows_default_credentials(true);
4306 auth_handler_factory->AddMockHandler(mock_handler.release(),
4307 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484308 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334309
4310 // Add NetLog just so can verify load timing information gets a NetLog ID.
4311 NetLog net_log;
4312 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094313 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334314
4315 // Should try to establish tunnel.
4316 MockWrite data_writes1[] = {
4317 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174318 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334319 "Proxy-Connection: keep-alive\r\n\r\n"),
4320
4321 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174322 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334323 "Proxy-Connection: keep-alive\r\n"
4324 "Proxy-Authorization: auth_token\r\n\r\n"),
4325 };
4326
4327 // The proxy responds to the connect with a 407, using a non-persistent
4328 // connection.
4329 MockRead data_reads1[] = {
4330 // No credentials.
4331 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4332 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4333 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4334 };
4335
4336 // Since the first connection was closed, need to establish another once given
4337 // credentials.
4338 MockWrite data_writes2[] = {
4339 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174340 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334341 "Proxy-Connection: keep-alive\r\n"
4342 "Proxy-Authorization: auth_token\r\n\r\n"),
4343
4344 MockWrite("GET / HTTP/1.1\r\n"
4345 "Host: www.example.org\r\n"
4346 "Connection: keep-alive\r\n\r\n"),
4347 };
4348
4349 MockRead data_reads2[] = {
4350 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
4351
4352 MockRead("HTTP/1.1 200 OK\r\n"),
4353 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4354 MockRead("Content-Length: 5\r\n\r\n"),
4355 MockRead(SYNCHRONOUS, "hello"),
4356 };
4357
Ryan Sleevib8d7ea02018-05-07 20:01:014358 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke2a1781d2015-10-07 19:25:334359 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:014360 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke2a1781d2015-10-07 19:25:334361 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4362 SSLSocketDataProvider ssl(ASYNC, OK);
4363 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4364
bnc87dcefc2017-05-25 12:47:584365 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194366 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334367
4368 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204369 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014370 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334371
4372 const HttpResponseInfo* response = trans->GetResponseInfo();
4373 ASSERT_TRUE(response);
4374 ASSERT_TRUE(response->headers);
4375 EXPECT_TRUE(response->headers->IsKeepAlive());
4376 EXPECT_EQ(407, response->headers->response_code());
4377 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4378 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4379 EXPECT_FALSE(response->auth_challenge);
4380
4381 LoadTimingInfo load_timing_info;
4382 // CONNECT requests and responses are handled at the connect job level, so
4383 // the transaction does not yet have a connection.
4384 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4385
4386 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014387 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334388
4389 response = trans->GetResponseInfo();
4390 ASSERT_TRUE(response);
4391 ASSERT_TRUE(response->headers);
4392 EXPECT_TRUE(response->headers->IsKeepAlive());
4393 EXPECT_EQ(200, response->headers->response_code());
4394 EXPECT_EQ(5, response->headers->GetContentLength());
4395 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4396
4397 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524398 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:334399
4400 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4401 TestLoadTimingNotReusedWithPac(load_timing_info,
4402 CONNECT_TIMING_HAS_SSL_TIMES);
4403
4404 trans.reset();
4405 session->CloseAllConnections();
4406}
4407
4408// Test a proxy auth scheme that allows default credentials and a proxy server
4409// that hangs up when credentials are initially sent, and hangs up again when
4410// they are retried.
bncd16676a2016-07-20 16:23:014411TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334412 AuthAllowsDefaultCredentialsTunnelServerClosesConnectionTwice) {
4413 HttpRequestInfo request;
4414 request.method = "GET";
4415 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104416 request.traffic_annotation =
4417 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334418
4419 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594420 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494421 ProxyResolutionService::CreateFixedFromPacResult(
4422 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334423
Jeremy Roman0579ed62017-08-29 15:56:194424 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334425 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194426 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334427 mock_handler->set_allows_default_credentials(true);
4428 auth_handler_factory->AddMockHandler(mock_handler.release(),
4429 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484430 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334431
4432 // Add NetLog just so can verify load timing information gets a NetLog ID.
4433 NetLog net_log;
4434 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094435 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334436
4437 // Should try to establish tunnel.
4438 MockWrite data_writes1[] = {
4439 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174440 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334441 "Proxy-Connection: keep-alive\r\n\r\n"),
4442
4443 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174444 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334445 "Proxy-Connection: keep-alive\r\n"
4446 "Proxy-Authorization: auth_token\r\n\r\n"),
4447 };
4448
4449 // The proxy responds to the connect with a 407, and then hangs up after the
4450 // second request is sent.
4451 MockRead data_reads1[] = {
4452 // No credentials.
4453 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4454 MockRead("Content-Length: 0\r\n"),
4455 MockRead("Proxy-Connection: keep-alive\r\n"),
4456 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4457 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4458 };
4459
4460 // HttpNetworkTransaction sees a reused connection that was closed with
4461 // ERR_CONNECTION_CLOSED, realized it might have been a race, so retries the
4462 // request.
4463 MockWrite data_writes2[] = {
4464 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174465 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334466 "Proxy-Connection: keep-alive\r\n\r\n"),
4467 };
4468
4469 // The proxy, having had more than enough of us, just hangs up.
4470 MockRead data_reads2[] = {
4471 // No credentials.
4472 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4473 };
4474
Ryan Sleevib8d7ea02018-05-07 20:01:014475 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke2a1781d2015-10-07 19:25:334476 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:014477 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke2a1781d2015-10-07 19:25:334478 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4479
bnc87dcefc2017-05-25 12:47:584480 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194481 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334482
4483 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204484 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014485 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334486
4487 const HttpResponseInfo* response = trans->GetResponseInfo();
4488 ASSERT_TRUE(response);
4489 ASSERT_TRUE(response->headers);
4490 EXPECT_TRUE(response->headers->IsKeepAlive());
4491 EXPECT_EQ(407, response->headers->response_code());
4492 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4493 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4494 EXPECT_FALSE(response->auth_challenge);
4495
4496 LoadTimingInfo load_timing_info;
4497 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4498
4499 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014500 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_EMPTY_RESPONSE));
mmenke2a1781d2015-10-07 19:25:334501
4502 trans.reset();
4503 session->CloseAllConnections();
4504}
4505
Asanka Herathbc3f8f62018-11-16 23:08:304506// This test exercises an odd edge case where the proxy closes the connection
4507// after the authentication handshake is complete. Presumably this technique is
4508// used in lieu of returning a 403 or 5xx status code when the authentication
4509// succeeds, but the user is not authorized to connect to the destination
4510// server. There's no standard for what a proxy should do to indicate a blocked
4511// site.
4512TEST_F(HttpNetworkTransactionTest,
4513 AuthAllowsDefaultCredentialsTunnelConnectionClosesBeforeBody) {
4514 HttpRequestInfo request;
4515 request.method = "GET";
4516 request.url = GURL("https://www.example.org/");
4517 request.traffic_annotation =
4518 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4519
4520 // Configure against proxy server "myproxy:70".
4521 session_deps_.proxy_resolution_service =
4522 ProxyResolutionService::CreateFixedFromPacResult(
4523 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
4524
Steven Valdez0ef94d02018-11-19 23:28:134525 // When TLS 1.3 is enabled, spurious connections are made as part of the SSL
4526 // version interference probes.
4527 // TODO(crbug.com/906668): Correctly handle version interference probes to
4528 // test TLS 1.3.
4529 SSLConfig config;
4530 config.version_max = SSL_PROTOCOL_VERSION_TLS1_2;
4531 session_deps_.ssl_config_service =
4532 std::make_unique<TestSSLConfigService>(config);
4533
Asanka Herathbc3f8f62018-11-16 23:08:304534 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
4535 auth_handler_factory->set_do_init_from_challenge(true);
4536
4537 // Create two mock AuthHandlers. This is because the transaction gets retried
4538 // after the first ERR_CONNECTION_CLOSED since it's ambiguous whether there
4539 // was a real network error.
4540 //
4541 // The handlers support both default and explicit credentials. The retry
4542 // mentioned above should be able to reuse the default identity. Thus there
4543 // should never be a need to prompt for explicit credentials.
4544 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
4545 mock_handler->set_allows_default_credentials(true);
4546 mock_handler->set_allows_explicit_credentials(true);
4547 mock_handler->set_connection_based(true);
4548 auth_handler_factory->AddMockHandler(mock_handler.release(),
4549 HttpAuth::AUTH_PROXY);
4550 mock_handler = std::make_unique<HttpAuthHandlerMock>();
4551 mock_handler->set_allows_default_credentials(true);
4552 mock_handler->set_allows_explicit_credentials(true);
4553 mock_handler->set_connection_based(true);
4554 auth_handler_factory->AddMockHandler(mock_handler.release(),
4555 HttpAuth::AUTH_PROXY);
4556 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
4557
4558 NetLog net_log;
4559 session_deps_.net_log = &net_log;
4560 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4561
4562 // Data for both sockets.
4563 //
4564 // Writes are for the tunnel establishment attempts and the
4565 // authentication handshake.
4566 MockWrite data_writes1[] = {
4567 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4568 "Host: www.example.org:443\r\n"
4569 "Proxy-Connection: keep-alive\r\n\r\n"),
4570
4571 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4572 "Host: www.example.org:443\r\n"
4573 "Proxy-Connection: keep-alive\r\n"
4574 "Proxy-Authorization: auth_token\r\n\r\n"),
4575
4576 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4577 "Host: www.example.org:443\r\n"
4578 "Proxy-Connection: keep-alive\r\n"
4579 "Proxy-Authorization: auth_token\r\n\r\n"),
4580 };
4581
4582 // The server side of the authentication handshake. Note that the response to
4583 // the final CONNECT request is ERR_CONNECTION_CLOSED.
4584 MockRead data_reads1[] = {
4585 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4586 MockRead("Content-Length: 0\r\n"),
4587 MockRead("Proxy-Connection: keep-alive\r\n"),
4588 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4589
4590 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4591 MockRead("Content-Length: 0\r\n"),
4592 MockRead("Proxy-Connection: keep-alive\r\n"),
4593 MockRead("Proxy-Authenticate: Mock foo\r\n\r\n"),
4594
4595 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4596 };
4597
4598 StaticSocketDataProvider data1(data_reads1, data_writes1);
4599 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4600
4601 // The second socket is for the reconnection attempt. Data is identical to the
4602 // first attempt.
4603 StaticSocketDataProvider data2(data_reads1, data_writes1);
4604 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4605
4606 auto trans =
4607 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
4608
4609 TestCompletionCallback callback;
4610 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4611
4612 // Two rounds per handshake. After one retry, the error is propagated up the
4613 // stack.
4614 for (int i = 0; i < 4; ++i) {
4615 EXPECT_THAT(callback.GetResult(rv), IsOk());
4616
4617 const HttpResponseInfo* response = trans->GetResponseInfo();
4618 ASSERT_TRUE(response);
4619 ASSERT_TRUE(response->headers);
4620 EXPECT_EQ(407, response->headers->response_code());
4621 ASSERT_TRUE(trans->IsReadyToRestartForAuth());
4622
4623 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4624 }
4625
4626 // One shall be the number thou shalt retry, and the number of the retrying
4627 // shall be one. Two shalt thou not retry, neither retry thou zero, excepting
4628 // that thou then proceed to one. Three is right out. Once the number one,
4629 // being the first number, be reached, then lobbest thou thy
4630 // ERR_CONNECTION_CLOSED towards they network transaction, who shall snuff it.
4631 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.GetResult(rv));
4632
4633 trans.reset();
4634 session->CloseAllConnections();
4635}
4636
mmenke2a1781d2015-10-07 19:25:334637// Test a proxy auth scheme that allows default credentials and a proxy server
4638// that hangs up when credentials are initially sent, and sends a challenge
4639// again they are retried.
bncd16676a2016-07-20 16:23:014640TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334641 AuthAllowsDefaultCredentialsTunnelServerChallengesTwice) {
4642 HttpRequestInfo request;
4643 request.method = "GET";
4644 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104645 request.traffic_annotation =
4646 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334647
4648 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594649 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494650 ProxyResolutionService::CreateFixedFromPacResult(
4651 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334652
Jeremy Roman0579ed62017-08-29 15:56:194653 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334654 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194655 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334656 mock_handler->set_allows_default_credentials(true);
4657 auth_handler_factory->AddMockHandler(mock_handler.release(),
4658 HttpAuth::AUTH_PROXY);
4659 // Add another handler for the second challenge. It supports default
4660 // credentials, but they shouldn't be used, since they were already tried.
Jeremy Roman0579ed62017-08-29 15:56:194661 mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334662 mock_handler->set_allows_default_credentials(true);
4663 auth_handler_factory->AddMockHandler(mock_handler.release(),
4664 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484665 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334666
4667 // Add NetLog just so can verify load timing information gets a NetLog ID.
4668 NetLog net_log;
4669 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094670 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334671
4672 // Should try to establish tunnel.
4673 MockWrite data_writes1[] = {
4674 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174675 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334676 "Proxy-Connection: keep-alive\r\n\r\n"),
4677 };
4678
4679 // The proxy responds to the connect with a 407, using a non-persistent
4680 // connection.
4681 MockRead data_reads1[] = {
4682 // No credentials.
4683 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4684 MockRead("Proxy-Authenticate: Mock\r\n"),
4685 MockRead("Proxy-Connection: close\r\n\r\n"),
4686 };
4687
4688 // Since the first connection was closed, need to establish another once given
4689 // credentials.
4690 MockWrite data_writes2[] = {
4691 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174692 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334693 "Proxy-Connection: keep-alive\r\n"
4694 "Proxy-Authorization: auth_token\r\n\r\n"),
4695 };
4696
4697 MockRead data_reads2[] = {
4698 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4699 MockRead("Proxy-Authenticate: Mock\r\n"),
4700 MockRead("Proxy-Connection: close\r\n\r\n"),
4701 };
4702
Ryan Sleevib8d7ea02018-05-07 20:01:014703 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke2a1781d2015-10-07 19:25:334704 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:014705 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke2a1781d2015-10-07 19:25:334706 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4707 SSLSocketDataProvider ssl(ASYNC, OK);
4708 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4709
bnc87dcefc2017-05-25 12:47:584710 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194711 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334712
4713 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204714 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014715 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334716
4717 const HttpResponseInfo* response = trans->GetResponseInfo();
4718 ASSERT_TRUE(response);
4719 ASSERT_TRUE(response->headers);
4720 EXPECT_EQ(407, response->headers->response_code());
4721 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4722 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4723 EXPECT_FALSE(response->auth_challenge);
4724
4725 LoadTimingInfo load_timing_info;
4726 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4727
4728 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014729 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334730 response = trans->GetResponseInfo();
4731 ASSERT_TRUE(response);
4732 ASSERT_TRUE(response->headers);
4733 EXPECT_EQ(407, response->headers->response_code());
4734 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4735 EXPECT_TRUE(response->auth_challenge);
4736
4737 trans.reset();
4738 session->CloseAllConnections();
4739}
4740
asankae2257db2016-10-11 22:03:164741// A more nuanced test than GenerateAuthToken test which asserts that
4742// ERR_INVALID_AUTH_CREDENTIALS does not cause the auth scheme to be
4743// unnecessarily invalidated, and that if the server co-operates, the
4744// authentication handshake can continue with the same scheme but with a
4745// different identity.
4746TEST_F(HttpNetworkTransactionTest, NonPermanentGenerateAuthTokenError) {
4747 HttpRequestInfo request;
4748 request.method = "GET";
4749 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104750 request.traffic_annotation =
4751 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
asankae2257db2016-10-11 22:03:164752
Jeremy Roman0579ed62017-08-29 15:56:194753 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
asankae2257db2016-10-11 22:03:164754 auth_handler_factory->set_do_init_from_challenge(true);
4755
4756 // First handler. Uses default credentials, but barfs at generate auth token.
Jeremy Roman0579ed62017-08-29 15:56:194757 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164758 mock_handler->set_allows_default_credentials(true);
4759 mock_handler->set_allows_explicit_credentials(true);
4760 mock_handler->set_connection_based(true);
4761 mock_handler->SetGenerateExpectation(true, ERR_INVALID_AUTH_CREDENTIALS);
4762 auth_handler_factory->AddMockHandler(mock_handler.release(),
4763 HttpAuth::AUTH_SERVER);
4764
4765 // Add another handler for the second challenge. It supports default
4766 // credentials, but they shouldn't be used, since they were already tried.
Jeremy Roman0579ed62017-08-29 15:56:194767 mock_handler = std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164768 mock_handler->set_allows_default_credentials(true);
4769 mock_handler->set_allows_explicit_credentials(true);
4770 mock_handler->set_connection_based(true);
4771 auth_handler_factory->AddMockHandler(mock_handler.release(),
4772 HttpAuth::AUTH_SERVER);
4773 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
4774
4775 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4776
4777 MockWrite data_writes1[] = {
4778 MockWrite("GET / HTTP/1.1\r\n"
4779 "Host: www.example.org\r\n"
4780 "Connection: keep-alive\r\n\r\n"),
4781 };
4782
4783 MockRead data_reads1[] = {
4784 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4785 "WWW-Authenticate: Mock\r\n"
4786 "Connection: keep-alive\r\n\r\n"),
4787 };
4788
4789 // Identical to data_writes1[]. The AuthHandler encounters a
4790 // ERR_INVALID_AUTH_CREDENTIALS during the GenerateAuthToken stage, so the
4791 // transaction procceds without an authorization header.
4792 MockWrite data_writes2[] = {
4793 MockWrite("GET / HTTP/1.1\r\n"
4794 "Host: www.example.org\r\n"
4795 "Connection: keep-alive\r\n\r\n"),
4796 };
4797
4798 MockRead data_reads2[] = {
4799 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4800 "WWW-Authenticate: Mock\r\n"
4801 "Connection: keep-alive\r\n\r\n"),
4802 };
4803
4804 MockWrite data_writes3[] = {
4805 MockWrite("GET / HTTP/1.1\r\n"
4806 "Host: www.example.org\r\n"
4807 "Connection: keep-alive\r\n"
4808 "Authorization: auth_token\r\n\r\n"),
4809 };
4810
4811 MockRead data_reads3[] = {
4812 MockRead("HTTP/1.1 200 OK\r\n"
4813 "Content-Length: 5\r\n"
4814 "Content-Type: text/plain\r\n"
4815 "Connection: keep-alive\r\n\r\n"
4816 "Hello"),
4817 };
4818
Ryan Sleevib8d7ea02018-05-07 20:01:014819 StaticSocketDataProvider data1(data_reads1, data_writes1);
asankae2257db2016-10-11 22:03:164820 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4821
Ryan Sleevib8d7ea02018-05-07 20:01:014822 StaticSocketDataProvider data2(data_reads2, data_writes2);
asankae2257db2016-10-11 22:03:164823 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4824
Ryan Sleevib8d7ea02018-05-07 20:01:014825 StaticSocketDataProvider data3(data_reads3, data_writes3);
asankae2257db2016-10-11 22:03:164826 session_deps_.socket_factory->AddSocketDataProvider(&data3);
4827
bnc87dcefc2017-05-25 12:47:584828 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194829 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
asankae2257db2016-10-11 22:03:164830
4831 TestCompletionCallback callback;
4832 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4833 EXPECT_THAT(callback.GetResult(rv), IsOk());
4834
4835 const HttpResponseInfo* response = trans->GetResponseInfo();
4836 ASSERT_TRUE(response);
4837 ASSERT_TRUE(response->headers);
4838 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4839
4840 // The following three tests assert that an authentication challenge was
4841 // received and that the stack is ready to respond to the challenge using
4842 // ambient credentials.
4843 EXPECT_EQ(401, response->headers->response_code());
4844 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4845 EXPECT_FALSE(response->auth_challenge);
4846
4847 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4848 EXPECT_THAT(callback.GetResult(rv), IsOk());
4849 response = trans->GetResponseInfo();
4850 ASSERT_TRUE(response);
4851 ASSERT_TRUE(response->headers);
4852
4853 // The following three tests assert that an authentication challenge was
4854 // received and that the stack needs explicit credentials before it is ready
4855 // to respond to the challenge.
4856 EXPECT_EQ(401, response->headers->response_code());
4857 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4858 EXPECT_TRUE(response->auth_challenge);
4859
4860 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4861 EXPECT_THAT(callback.GetResult(rv), IsOk());
4862 response = trans->GetResponseInfo();
4863 ASSERT_TRUE(response);
4864 ASSERT_TRUE(response->headers);
4865 EXPECT_EQ(200, response->headers->response_code());
4866
4867 trans.reset();
4868 session->CloseAllConnections();
4869}
4870
Matt Menked1eb6d42018-01-17 04:54:064871// Proxy resolver that returns a proxy with the same host and port for different
4872// schemes, based on the path of the URL being requests.
4873class SameProxyWithDifferentSchemesProxyResolver : public ProxyResolver {
4874 public:
4875 SameProxyWithDifferentSchemesProxyResolver() {}
4876 ~SameProxyWithDifferentSchemesProxyResolver() override {}
4877
4878 static std::string ProxyHostPortPairAsString() { return "proxy.test:10000"; }
4879
4880 static HostPortPair ProxyHostPortPair() {
4881 return HostPortPair::FromString(ProxyHostPortPairAsString());
4882 }
4883
4884 // ProxyResolver implementation.
4885 int GetProxyForURL(const GURL& url,
4886 ProxyInfo* results,
Bence Békycc5b88a2018-05-25 20:24:174887 CompletionOnceCallback callback,
Matt Menked1eb6d42018-01-17 04:54:064888 std::unique_ptr<Request>* request,
4889 const NetLogWithSource& /*net_log*/) override {
4890 *results = ProxyInfo();
Ramin Halavati921731ea2018-03-16 08:24:574891 results->set_traffic_annotation(
4892 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
Matt Menked1eb6d42018-01-17 04:54:064893 if (url.path() == "/socks4") {
4894 results->UsePacString("SOCKS " + ProxyHostPortPairAsString());
4895 return OK;
4896 }
4897 if (url.path() == "/socks5") {
4898 results->UsePacString("SOCKS5 " + ProxyHostPortPairAsString());
4899 return OK;
4900 }
4901 if (url.path() == "/http") {
4902 results->UsePacString("PROXY " + ProxyHostPortPairAsString());
4903 return OK;
4904 }
4905 if (url.path() == "/https") {
4906 results->UsePacString("HTTPS " + ProxyHostPortPairAsString());
4907 return OK;
4908 }
Matt Menkee8648fa2019-01-17 16:47:074909 if (url.path() == "/https_trusted") {
4910 results->UseProxyServer(ProxyServer(ProxyServer::SCHEME_HTTPS,
4911 ProxyHostPortPair(),
4912 true /* is_trusted_proxy */));
4913 return OK;
4914 }
Matt Menked1eb6d42018-01-17 04:54:064915 NOTREACHED();
4916 return ERR_NOT_IMPLEMENTED;
4917 }
4918
4919 private:
4920 DISALLOW_COPY_AND_ASSIGN(SameProxyWithDifferentSchemesProxyResolver);
4921};
4922
4923class SameProxyWithDifferentSchemesProxyResolverFactory
4924 : public ProxyResolverFactory {
4925 public:
4926 SameProxyWithDifferentSchemesProxyResolverFactory()
4927 : ProxyResolverFactory(false) {}
4928
Lily Houghton99597862018-03-07 16:40:424929 int CreateProxyResolver(const scoped_refptr<PacFileData>& pac_script,
4930 std::unique_ptr<ProxyResolver>* resolver,
Bence Békycc5b88a2018-05-25 20:24:174931 CompletionOnceCallback callback,
Lily Houghton99597862018-03-07 16:40:424932 std::unique_ptr<Request>* request) override {
Matt Menked1eb6d42018-01-17 04:54:064933 *resolver = std::make_unique<SameProxyWithDifferentSchemesProxyResolver>();
4934 return OK;
4935 }
4936
4937 private:
4938 DISALLOW_COPY_AND_ASSIGN(SameProxyWithDifferentSchemesProxyResolverFactory);
4939};
4940
4941// Check that when different proxy schemes are all applied to a proxy at the
Matt Menkee8648fa2019-01-17 16:47:074942// same address, the connections are not grouped together. i.e., a request to
Matt Menked1eb6d42018-01-17 04:54:064943// foo.com using proxy.com as an HTTPS proxy won't use the same socket as a
4944// request to foo.com using proxy.com as an HTTP proxy.
4945TEST_F(HttpNetworkTransactionTest, SameDestinationForDifferentProxyTypes) {
Ramin Halavatica8d5252018-03-12 05:33:494946 session_deps_.proxy_resolution_service =
4947 std::make_unique<ProxyResolutionService>(
4948 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
4949 ProxyConfig::CreateAutoDetect(), TRAFFIC_ANNOTATION_FOR_TESTS)),
4950 std::make_unique<SameProxyWithDifferentSchemesProxyResolverFactory>(),
4951 nullptr);
Matt Menked1eb6d42018-01-17 04:54:064952
4953 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4954
4955 MockWrite socks_writes[] = {
4956 MockWrite(SYNCHRONOUS, kSOCKS4OkRequestLocalHostPort80,
4957 kSOCKS4OkRequestLocalHostPort80Length),
4958 MockWrite(SYNCHRONOUS,
4959 "GET /socks4 HTTP/1.1\r\n"
4960 "Host: test\r\n"
4961 "Connection: keep-alive\r\n\r\n"),
4962 };
4963 MockRead socks_reads[] = {
4964 MockRead(SYNCHRONOUS, kSOCKS4OkReply, kSOCKS4OkReplyLength),
4965 MockRead("HTTP/1.0 200 OK\r\n"
4966 "Connection: keep-alive\r\n"
4967 "Content-Length: 15\r\n\r\n"
4968 "SOCKS4 Response"),
4969 };
Ryan Sleevib8d7ea02018-05-07 20:01:014970 StaticSocketDataProvider socks_data(socks_reads, socks_writes);
Matt Menked1eb6d42018-01-17 04:54:064971 session_deps_.socket_factory->AddSocketDataProvider(&socks_data);
4972
4973 const char kSOCKS5Request[] = {
4974 0x05, // Version
4975 0x01, // Command (CONNECT)
4976 0x00, // Reserved
4977 0x03, // Address type (DOMAINNAME)
4978 0x04, // Length of domain (4)
4979 't', 'e', 's', 't', // Domain string
4980 0x00, 0x50, // 16-bit port (80)
4981 };
4982 MockWrite socks5_writes[] = {
4983 MockWrite(ASYNC, kSOCKS5GreetRequest, kSOCKS5GreetRequestLength),
Avi Drissman4365a4782018-12-28 19:26:244984 MockWrite(ASYNC, kSOCKS5Request, base::size(kSOCKS5Request)),
Matt Menked1eb6d42018-01-17 04:54:064985 MockWrite(SYNCHRONOUS,
4986 "GET /socks5 HTTP/1.1\r\n"
4987 "Host: test\r\n"
4988 "Connection: keep-alive\r\n\r\n"),
4989 };
4990 MockRead socks5_reads[] = {
4991 MockRead(ASYNC, kSOCKS5GreetResponse, kSOCKS5GreetResponseLength),
4992 MockRead(ASYNC, kSOCKS5OkResponse, kSOCKS5OkResponseLength),
4993 MockRead("HTTP/1.0 200 OK\r\n"
4994 "Connection: keep-alive\r\n"
4995 "Content-Length: 15\r\n\r\n"
4996 "SOCKS5 Response"),
4997 };
Ryan Sleevib8d7ea02018-05-07 20:01:014998 StaticSocketDataProvider socks5_data(socks5_reads, socks5_writes);
Matt Menked1eb6d42018-01-17 04:54:064999 session_deps_.socket_factory->AddSocketDataProvider(&socks5_data);
5000
5001 MockWrite http_writes[] = {
5002 MockWrite(SYNCHRONOUS,
5003 "GET http://test/http HTTP/1.1\r\n"
5004 "Host: test\r\n"
5005 "Proxy-Connection: keep-alive\r\n\r\n"),
5006 };
5007 MockRead http_reads[] = {
5008 MockRead("HTTP/1.1 200 OK\r\n"
5009 "Proxy-Connection: keep-alive\r\n"
5010 "Content-Length: 13\r\n\r\n"
5011 "HTTP Response"),
5012 };
Ryan Sleevib8d7ea02018-05-07 20:01:015013 StaticSocketDataProvider http_data(http_reads, http_writes);
Matt Menked1eb6d42018-01-17 04:54:065014 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
5015
5016 MockWrite https_writes[] = {
5017 MockWrite(SYNCHRONOUS,
5018 "GET http://test/https HTTP/1.1\r\n"
5019 "Host: test\r\n"
5020 "Proxy-Connection: keep-alive\r\n\r\n"),
5021 };
5022 MockRead https_reads[] = {
5023 MockRead("HTTP/1.1 200 OK\r\n"
5024 "Proxy-Connection: keep-alive\r\n"
5025 "Content-Length: 14\r\n\r\n"
5026 "HTTPS Response"),
5027 };
Ryan Sleevib8d7ea02018-05-07 20:01:015028 StaticSocketDataProvider https_data(https_reads, https_writes);
Matt Menked1eb6d42018-01-17 04:54:065029 session_deps_.socket_factory->AddSocketDataProvider(&https_data);
5030 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
5031 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5032
Matt Menkee8648fa2019-01-17 16:47:075033 MockWrite https_trusted_writes[] = {
5034 MockWrite(SYNCHRONOUS,
5035 "GET http://test/https_trusted HTTP/1.1\r\n"
5036 "Host: test\r\n"
5037 "Proxy-Connection: keep-alive\r\n\r\n"),
5038 };
5039 MockRead https_trusted_reads[] = {
5040 MockRead("HTTP/1.1 200 OK\r\n"
5041 "Proxy-Connection: keep-alive\r\n"
5042 "Content-Length: 22\r\n\r\n"
5043 "HTTPS Trusted Response"),
5044 };
5045 StaticSocketDataProvider trusted_https_data(https_trusted_reads,
5046 https_trusted_writes);
5047 session_deps_.socket_factory->AddSocketDataProvider(&trusted_https_data);
5048 SSLSocketDataProvider ssl2(SYNCHRONOUS, OK);
5049 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
5050
Matt Menked1eb6d42018-01-17 04:54:065051 struct TestCase {
5052 GURL url;
5053 std::string expected_response;
Matt Menkee8648fa2019-01-17 16:47:075054 // How many idle sockets there should be in the SOCKS 4/5 proxy socket pools
Matt Menked1eb6d42018-01-17 04:54:065055 // after the test.
Matt Menkee8648fa2019-01-17 16:47:075056 int expected_idle_socks4_sockets;
5057 int expected_idle_socks5_sockets;
5058 // How many idle sockets there should be in the HTTP/HTTPS proxy socket
5059 // pools after the test.
Matt Menked1eb6d42018-01-17 04:54:065060 int expected_idle_http_sockets;
Matt Menkee8648fa2019-01-17 16:47:075061 int expected_idle_https_sockets;
5062 // How many idle sockets there should be in the HTTPS proxy socket pool with
5063 // the ProxyServer's |is_trusted_proxy| bit set after the test.
5064 int expected_idle_trusted_https_sockets;
Matt Menked1eb6d42018-01-17 04:54:065065 } const kTestCases[] = {
Matt Menkee8648fa2019-01-17 16:47:075066 {GURL("http://test/socks4"), "SOCKS4 Response", 1, 0, 0, 0, 0},
5067 {GURL("http://test/socks5"), "SOCKS5 Response", 1, 1, 0, 0, 0},
5068 {GURL("http://test/http"), "HTTP Response", 1, 1, 1, 0, 0},
5069 {GURL("http://test/https"), "HTTPS Response", 1, 1, 1, 1, 0},
5070 {GURL("http://test/https_trusted"), "HTTPS Trusted Response", 1, 1, 1, 1,
5071 1},
Matt Menked1eb6d42018-01-17 04:54:065072 };
5073
5074 for (const auto& test_case : kTestCases) {
5075 HttpRequestInfo request;
5076 request.method = "GET";
5077 request.url = test_case.url;
Ramin Halavatib5e433e62018-02-07 07:41:105078 request.traffic_annotation =
5079 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Matt Menked1eb6d42018-01-17 04:54:065080 std::unique_ptr<HttpNetworkTransaction> trans =
5081 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
5082 session.get());
5083 TestCompletionCallback callback;
5084 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
5085 EXPECT_THAT(callback.GetResult(rv), IsOk());
5086
5087 const HttpResponseInfo* response = trans->GetResponseInfo();
5088 ASSERT_TRUE(response);
5089 ASSERT_TRUE(response->headers);
5090 EXPECT_EQ(200, response->headers->response_code());
5091 std::string response_data;
5092 EXPECT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
5093 EXPECT_EQ(test_case.expected_response, response_data);
5094
5095 // Return the socket to the socket pool, so can make sure it's not used for
5096 // the next requests.
5097 trans.reset();
5098 base::RunLoop().RunUntilIdle();
5099
5100 // Check the number of idle sockets in the pool, to make sure that used
5101 // sockets are indeed being returned to the socket pool. If each request
5102 // doesn't return an idle socket to the pool, the test would incorrectly
5103 // pass.
Matt Menkee8648fa2019-01-17 16:47:075104 EXPECT_EQ(test_case.expected_idle_socks4_sockets,
5105 session
5106 ->GetSocketPoolForSOCKSProxy(
5107 HttpNetworkSession::NORMAL_SOCKET_POOL,
5108 ProxyServer(ProxyServer::SCHEME_SOCKS4,
5109 SameProxyWithDifferentSchemesProxyResolver::
5110 ProxyHostPortPair()))
5111 ->IdleSocketCount());
5112 EXPECT_EQ(test_case.expected_idle_socks5_sockets,
5113 session
5114 ->GetSocketPoolForSOCKSProxy(
5115 HttpNetworkSession::NORMAL_SOCKET_POOL,
5116 ProxyServer(ProxyServer::SCHEME_SOCKS5,
5117 SameProxyWithDifferentSchemesProxyResolver::
5118 ProxyHostPortPair()))
5119 ->IdleSocketCount());
5120 EXPECT_EQ(test_case.expected_idle_http_sockets,
5121 session
5122 ->GetSocketPoolForHTTPLikeProxy(
5123 HttpNetworkSession::NORMAL_SOCKET_POOL,
5124 ProxyServer(ProxyServer::SCHEME_HTTP,
5125 SameProxyWithDifferentSchemesProxyResolver::
5126 ProxyHostPortPair()))
5127 ->IdleSocketCount());
5128 EXPECT_EQ(test_case.expected_idle_https_sockets,
5129 session
5130 ->GetSocketPoolForHTTPLikeProxy(
5131 HttpNetworkSession::NORMAL_SOCKET_POOL,
5132 ProxyServer(ProxyServer::SCHEME_HTTPS,
5133 SameProxyWithDifferentSchemesProxyResolver::
5134 ProxyHostPortPair()))
5135 ->IdleSocketCount());
5136 EXPECT_EQ(test_case.expected_idle_trusted_https_sockets,
5137 session
5138 ->GetSocketPoolForHTTPLikeProxy(
5139 HttpNetworkSession::NORMAL_SOCKET_POOL,
5140 ProxyServer(ProxyServer::SCHEME_HTTPS,
5141 SameProxyWithDifferentSchemesProxyResolver::
5142 ProxyHostPortPair(),
5143 true /* is_trusted_proxy */))
5144 ->IdleSocketCount());
Matt Menked1eb6d42018-01-17 04:54:065145 }
5146}
5147
[email protected]029c83b62013-01-24 05:28:205148// Test the load timing for HTTPS requests with an HTTP proxy.
bncd16676a2016-07-20 16:23:015149TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:205150 HttpRequestInfo request1;
5151 request1.method = "GET";
bncce36dca22015-04-21 22:11:235152 request1.url = GURL("https://www.example.org/1");
Ramin Halavatib5e433e62018-02-07 07:41:105153 request1.traffic_annotation =
5154 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:205155
5156 HttpRequestInfo request2;
5157 request2.method = "GET";
bncce36dca22015-04-21 22:11:235158 request2.url = GURL("https://www.example.org/2");
Ramin Halavatib5e433e62018-02-07 07:41:105159 request2.traffic_annotation =
5160 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:205161
5162 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495163 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5164 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515165 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075166 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095167 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:205168
5169 // Since we have proxy, should try to establish tunnel.
5170 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:175171 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5172 "Host: www.example.org:443\r\n"
5173 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205174
rsleevidb16bb02015-11-12 23:47:175175 MockWrite("GET /1 HTTP/1.1\r\n"
5176 "Host: www.example.org\r\n"
5177 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205178
rsleevidb16bb02015-11-12 23:47:175179 MockWrite("GET /2 HTTP/1.1\r\n"
5180 "Host: www.example.org\r\n"
5181 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205182 };
5183
5184 // The proxy responds to the connect with a 407, using a persistent
5185 // connection.
5186 MockRead data_reads1[] = {
5187 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
5188
5189 MockRead("HTTP/1.1 200 OK\r\n"),
5190 MockRead("Content-Length: 1\r\n\r\n"),
5191 MockRead(SYNCHRONOUS, "1"),
5192
5193 MockRead("HTTP/1.1 200 OK\r\n"),
5194 MockRead("Content-Length: 2\r\n\r\n"),
5195 MockRead(SYNCHRONOUS, "22"),
5196 };
5197
Ryan Sleevib8d7ea02018-05-07 20:01:015198 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:075199 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:205200 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075201 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:205202
5203 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:585204 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:195205 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:205206
5207 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015208 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:205209
5210 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015211 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:205212
5213 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:525214 ASSERT_TRUE(response1);
tbansal2ecbbc72016-10-06 17:15:475215 EXPECT_TRUE(response1->proxy_server.is_http());
wezca1070932016-05-26 20:30:525216 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:205217 EXPECT_EQ(1, response1->headers->GetContentLength());
5218
5219 LoadTimingInfo load_timing_info1;
5220 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
5221 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
5222
5223 trans1.reset();
5224
5225 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:585226 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:195227 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:205228
5229 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015230 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:205231
5232 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015233 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:205234
5235 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:525236 ASSERT_TRUE(response2);
tbansal2ecbbc72016-10-06 17:15:475237 EXPECT_TRUE(response2->proxy_server.is_http());
wezca1070932016-05-26 20:30:525238 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:205239 EXPECT_EQ(2, response2->headers->GetContentLength());
5240
5241 LoadTimingInfo load_timing_info2;
5242 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5243 TestLoadTimingReused(load_timing_info2);
5244
5245 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
5246
5247 trans2.reset();
5248 session->CloseAllConnections();
5249}
5250
5251// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
bncd16676a2016-07-20 16:23:015252TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:205253 HttpRequestInfo request1;
5254 request1.method = "GET";
bncce36dca22015-04-21 22:11:235255 request1.url = GURL("https://www.example.org/1");
Ramin Halavatib5e433e62018-02-07 07:41:105256 request1.traffic_annotation =
5257 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:205258
5259 HttpRequestInfo request2;
5260 request2.method = "GET";
bncce36dca22015-04-21 22:11:235261 request2.url = GURL("https://www.example.org/2");
Ramin Halavatib5e433e62018-02-07 07:41:105262 request2.traffic_annotation =
5263 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:205264
5265 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595266 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:495267 ProxyResolutionService::CreateFixedFromPacResult(
5268 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515269 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075270 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095271 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:205272
5273 // Since we have proxy, should try to establish tunnel.
5274 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:175275 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5276 "Host: www.example.org:443\r\n"
5277 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205278
rsleevidb16bb02015-11-12 23:47:175279 MockWrite("GET /1 HTTP/1.1\r\n"
5280 "Host: www.example.org\r\n"
5281 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205282
rsleevidb16bb02015-11-12 23:47:175283 MockWrite("GET /2 HTTP/1.1\r\n"
5284 "Host: www.example.org\r\n"
5285 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205286 };
5287
5288 // The proxy responds to the connect with a 407, using a persistent
5289 // connection.
5290 MockRead data_reads1[] = {
5291 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
5292
5293 MockRead("HTTP/1.1 200 OK\r\n"),
5294 MockRead("Content-Length: 1\r\n\r\n"),
5295 MockRead(SYNCHRONOUS, "1"),
5296
5297 MockRead("HTTP/1.1 200 OK\r\n"),
5298 MockRead("Content-Length: 2\r\n\r\n"),
5299 MockRead(SYNCHRONOUS, "22"),
5300 };
5301
Ryan Sleevib8d7ea02018-05-07 20:01:015302 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:075303 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:205304 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075305 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:205306
5307 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:585308 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:195309 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:205310
5311 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015312 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:205313
5314 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015315 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:205316
5317 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:525318 ASSERT_TRUE(response1);
5319 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:205320 EXPECT_EQ(1, response1->headers->GetContentLength());
5321
5322 LoadTimingInfo load_timing_info1;
5323 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
5324 TestLoadTimingNotReusedWithPac(load_timing_info1,
5325 CONNECT_TIMING_HAS_SSL_TIMES);
5326
5327 trans1.reset();
5328
5329 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:585330 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:195331 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:205332
5333 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015334 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:205335
5336 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015337 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:205338
5339 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:525340 ASSERT_TRUE(response2);
5341 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:205342 EXPECT_EQ(2, response2->headers->GetContentLength());
5343
5344 LoadTimingInfo load_timing_info2;
5345 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5346 TestLoadTimingReusedWithPac(load_timing_info2);
5347
5348 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
5349
5350 trans2.reset();
5351 session->CloseAllConnections();
5352}
5353
[email protected]2df19bb2010-08-25 20:13:465354// Test a simple get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015355TEST_F(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:275356 HttpRequestInfo request;
5357 request.method = "GET";
bncce36dca22015-04-21 22:11:235358 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105359 request.traffic_annotation =
5360 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275361
[email protected]2df19bb2010-08-25 20:13:465362 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495363 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5364 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515365 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075366 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095367 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:465368
[email protected]2df19bb2010-08-25 20:13:465369 // Since we have proxy, should use full url
5370 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235371 MockWrite(
5372 "GET http://www.example.org/ HTTP/1.1\r\n"
5373 "Host: www.example.org\r\n"
5374 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465375 };
5376
5377 MockRead data_reads1[] = {
5378 MockRead("HTTP/1.1 200 OK\r\n"),
5379 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5380 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065381 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:465382 };
5383
Ryan Sleevib8d7ea02018-05-07 20:01:015384 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:075385 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:065386 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075387 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:465388
[email protected]49639fa2011-12-20 23:22:415389 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:465390
bnc691fda62016-08-12 00:43:165391 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505392
bnc691fda62016-08-12 00:43:165393 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015394 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465395
5396 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015397 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465398
[email protected]58e32bb2013-01-21 18:23:255399 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165400 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255401 TestLoadTimingNotReused(load_timing_info,
5402 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5403
bnc691fda62016-08-12 00:43:165404 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525405 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:465406
tbansal2ecbbc72016-10-06 17:15:475407 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:465408 EXPECT_TRUE(response->headers->IsKeepAlive());
5409 EXPECT_EQ(200, response->headers->response_code());
5410 EXPECT_EQ(100, response->headers->GetContentLength());
5411 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5412
5413 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525414 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:465415}
5416
[email protected]7642b5ae2010-09-01 20:55:175417// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015418TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:275419 HttpRequestInfo request;
5420 request.method = "GET";
bncce36dca22015-04-21 22:11:235421 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105422 request.traffic_annotation =
5423 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275424
[email protected]7642b5ae2010-09-01 20:55:175425 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495426 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5427 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515428 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075429 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095430 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:175431
bncce36dca22015-04-21 22:11:235432 // fetch http://www.example.org/ via SPDY
Ryan Hamilton0239aac2018-05-19 00:03:135433 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:455434 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415435 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]7642b5ae2010-09-01 20:55:175436
Ryan Hamilton0239aac2018-05-19 00:03:135437 spdy::SpdySerializedFrame resp(
5438 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
5439 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:175440 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415441 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]7642b5ae2010-09-01 20:55:175442 };
5443
Ryan Sleevib8d7ea02018-05-07 20:01:015444 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075445 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:175446
[email protected]8ddf8322012-02-23 18:08:065447 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365448 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075449 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:175450
[email protected]49639fa2011-12-20 23:22:415451 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:175452
bnc691fda62016-08-12 00:43:165453 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505454
bnc691fda62016-08-12 00:43:165455 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015456 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7642b5ae2010-09-01 20:55:175457
5458 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015459 EXPECT_THAT(rv, IsOk());
[email protected]7642b5ae2010-09-01 20:55:175460
[email protected]58e32bb2013-01-21 18:23:255461 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165462 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255463 TestLoadTimingNotReused(load_timing_info,
5464 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5465
bnc691fda62016-08-12 00:43:165466 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525467 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:475468 EXPECT_TRUE(response->proxy_server.is_https());
wezca1070932016-05-26 20:30:525469 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025470 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]7642b5ae2010-09-01 20:55:175471
5472 std::string response_data;
bnc691fda62016-08-12 00:43:165473 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235474 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:175475}
5476
[email protected]1c173852014-06-19 12:51:505477// Verifies that a session which races and wins against the owning transaction
5478// (completing prior to host resolution), doesn't fail the transaction.
5479// Regression test for crbug.com/334413.
bncd16676a2016-07-20 16:23:015480TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
[email protected]1c173852014-06-19 12:51:505481 HttpRequestInfo request;
5482 request.method = "GET";
bncce36dca22015-04-21 22:11:235483 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105484 request.traffic_annotation =
5485 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c173852014-06-19 12:51:505486
5487 // Configure SPDY proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495488 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5489 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515490 BoundTestNetLog log;
[email protected]1c173852014-06-19 12:51:505491 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095492 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1c173852014-06-19 12:51:505493
bncce36dca22015-04-21 22:11:235494 // Fetch http://www.example.org/ through the SPDY proxy.
Ryan Hamilton0239aac2018-05-19 00:03:135495 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:455496 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415497 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]1c173852014-06-19 12:51:505498
Ryan Hamilton0239aac2018-05-19 00:03:135499 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
5500 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]1c173852014-06-19 12:51:505501 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415502 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]1c173852014-06-19 12:51:505503 };
5504
Ryan Sleevib8d7ea02018-05-07 20:01:015505 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]1c173852014-06-19 12:51:505506 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
5507
5508 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365509 ssl.next_proto = kProtoHTTP2;
[email protected]1c173852014-06-19 12:51:505510 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5511
5512 TestCompletionCallback callback1;
5513
bnc691fda62016-08-12 00:43:165514 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1c173852014-06-19 12:51:505515
5516 // Stall the hostname resolution begun by the transaction.
[email protected]1c173852014-06-19 12:51:505517 session_deps_.host_resolver->set_ondemand_mode(true);
5518
bnc691fda62016-08-12 00:43:165519 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015520 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c173852014-06-19 12:51:505521
5522 // Race a session to the proxy, which completes first.
5523 session_deps_.host_resolver->set_ondemand_mode(false);
Paul Jensena457017a2018-01-19 23:52:045524 SpdySessionKey key(HostPortPair("proxy", 70), ProxyServer::Direct(),
Matt Menke2436b2f2018-12-11 18:07:115525 PRIVACY_MODE_DISABLED,
5526 SpdySessionKey::IsProxySession::kTrue, SocketTag());
[email protected]1c173852014-06-19 12:51:505527 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:525528 CreateSpdySession(session.get(), key, log.bound());
[email protected]1c173852014-06-19 12:51:505529
5530 // Unstall the resolution begun by the transaction.
5531 session_deps_.host_resolver->set_ondemand_mode(true);
5532 session_deps_.host_resolver->ResolveAllPending();
5533
5534 EXPECT_FALSE(callback1.have_result());
5535 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015536 EXPECT_THAT(rv, IsOk());
[email protected]1c173852014-06-19 12:51:505537
bnc691fda62016-08-12 00:43:165538 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525539 ASSERT_TRUE(response);
5540 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025541 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]1c173852014-06-19 12:51:505542
5543 std::string response_data;
bnc691fda62016-08-12 00:43:165544 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]1c173852014-06-19 12:51:505545 EXPECT_EQ(kUploadData, response_data);
5546}
5547
[email protected]dc7bd1c52010-11-12 00:01:135548// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015549TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:275550 HttpRequestInfo request;
5551 request.method = "GET";
bncce36dca22015-04-21 22:11:235552 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105553 request.traffic_annotation =
5554 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275555
[email protected]79cb5c12011-09-12 13:12:045556 // Configure against https proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495557 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5558 "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515559 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075560 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095561 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:135562
[email protected]dc7bd1c52010-11-12 00:01:135563 // The first request will be a bare GET, the second request will be a
5564 // GET with a Proxy-Authorization header.
bncb26024382016-06-29 02:39:455565 spdy_util_.set_default_url(request.url);
Ryan Hamilton0239aac2018-05-19 00:03:135566 spdy::SpdySerializedFrame req_get(
Bence Béky27ad0a12018-02-08 00:35:485567 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:385568 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]dc7bd1c52010-11-12 00:01:135569 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:465570 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:135571 };
Ryan Hamilton0239aac2018-05-19 00:03:135572 spdy::SpdySerializedFrame req_get_authorization(spdy_util_.ConstructSpdyGet(
Avi Drissman4365a4782018-12-28 19:26:245573 kExtraAuthorizationHeaders, base::size(kExtraAuthorizationHeaders) / 2, 3,
Bence Béky27ad0a12018-02-08 00:35:485574 LOWEST));
[email protected]dc7bd1c52010-11-12 00:01:135575 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415576 CreateMockWrite(req_get, 0), CreateMockWrite(req_get_authorization, 3),
[email protected]dc7bd1c52010-11-12 00:01:135577 };
5578
5579 // The first response is a 407 proxy authentication challenge, and the second
5580 // response will be a 200 response since the second request includes a valid
5581 // Authorization header.
5582 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:465583 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:135584 };
Ryan Hamilton0239aac2018-05-19 00:03:135585 spdy::SpdySerializedFrame resp_authentication(
5586 spdy_util_.ConstructSpdyReplyError(
5587 "407", kExtraAuthenticationHeaders,
Avi Drissman4365a4782018-12-28 19:26:245588 base::size(kExtraAuthenticationHeaders) / 2, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135589 spdy::SpdySerializedFrame body_authentication(
bncdf80d44fd2016-07-15 20:27:415590 spdy_util_.ConstructSpdyDataFrame(1, true));
Ryan Hamilton0239aac2018-05-19 00:03:135591 spdy::SpdySerializedFrame resp_data(
5592 spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
5593 spdy::SpdySerializedFrame body_data(
5594 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:135595 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415596 CreateMockRead(resp_authentication, 1),
bnceb9aa7112017-01-05 01:03:465597 CreateMockRead(body_authentication, 2, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415598 CreateMockRead(resp_data, 4),
5599 CreateMockRead(body_data, 5),
rch8e6c6c42015-05-01 14:05:135600 MockRead(ASYNC, 0, 6),
[email protected]dc7bd1c52010-11-12 00:01:135601 };
5602
Ryan Sleevib8d7ea02018-05-07 20:01:015603 SequencedSocketData data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075604 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:135605
[email protected]8ddf8322012-02-23 18:08:065606 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365607 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075608 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:135609
[email protected]49639fa2011-12-20 23:22:415610 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:135611
bnc691fda62016-08-12 00:43:165612 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]dc7bd1c52010-11-12 00:01:135613
bnc691fda62016-08-12 00:43:165614 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015615 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:135616
5617 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015618 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:135619
bnc691fda62016-08-12 00:43:165620 const HttpResponseInfo* const response = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:135621
wezca1070932016-05-26 20:30:525622 ASSERT_TRUE(response);
5623 ASSERT_TRUE(response->headers);
[email protected]dc7bd1c52010-11-12 00:01:135624 EXPECT_EQ(407, response->headers->response_code());
5625 EXPECT_TRUE(response->was_fetched_via_spdy);
asanka098c0092016-06-16 20:18:435626 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:135627
[email protected]49639fa2011-12-20 23:22:415628 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:135629
bnc691fda62016-08-12 00:43:165630 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015631 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:135632
5633 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015634 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:135635
bnc691fda62016-08-12 00:43:165636 const HttpResponseInfo* const response_restart = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:135637
wezca1070932016-05-26 20:30:525638 ASSERT_TRUE(response_restart);
5639 ASSERT_TRUE(response_restart->headers);
[email protected]dc7bd1c52010-11-12 00:01:135640 EXPECT_EQ(200, response_restart->headers->response_code());
5641 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525642 EXPECT_FALSE(response_restart->auth_challenge);
[email protected]dc7bd1c52010-11-12 00:01:135643}
5644
[email protected]d9da5fe2010-10-13 22:37:165645// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
bncd16676a2016-07-20 16:23:015646TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:275647 HttpRequestInfo request;
5648 request.method = "GET";
bncce36dca22015-04-21 22:11:235649 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105650 request.traffic_annotation =
5651 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275652
[email protected]d9da5fe2010-10-13 22:37:165653 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495654 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5655 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515656 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075657 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095658 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165659
bnc691fda62016-08-12 00:43:165660 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165661
bncce36dca22015-04-21 22:11:235662 // CONNECT to www.example.org:443 via SPDY
Ryan Hamilton0239aac2018-05-19 00:03:135663 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235664 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
5665 // fetch https://www.example.org/ via HTTP
[email protected]d9da5fe2010-10-13 22:37:165666
bncce36dca22015-04-21 22:11:235667 const char get[] =
5668 "GET / HTTP/1.1\r\n"
5669 "Host: www.example.org\r\n"
5670 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:135671 spdy::SpdySerializedFrame wrapped_get(
Bence Békyd74f4382018-02-20 18:26:195672 spdy_util_.ConstructSpdyDataFrame(1, get, false));
Ryan Hamilton0239aac2018-05-19 00:03:135673 spdy::SpdySerializedFrame conn_resp(
5674 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:165675 const char resp[] = "HTTP/1.1 200 OK\r\n"
5676 "Content-Length: 10\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:135677 spdy::SpdySerializedFrame wrapped_get_resp(
Bence Békyd74f4382018-02-20 18:26:195678 spdy_util_.ConstructSpdyDataFrame(1, resp, false));
Ryan Hamilton0239aac2018-05-19 00:03:135679 spdy::SpdySerializedFrame wrapped_body(
Bence Békyd74f4382018-02-20 18:26:195680 spdy_util_.ConstructSpdyDataFrame(1, "1234567890", false));
Ryan Hamilton0239aac2018-05-19 00:03:135681 spdy::SpdySerializedFrame window_update(
bncdf80d44fd2016-07-15 20:27:415682 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
[email protected]8d2f7012012-02-16 00:08:045683
5684 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415685 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
5686 CreateMockWrite(window_update, 6),
[email protected]8d2f7012012-02-16 00:08:045687 };
5688
[email protected]d9da5fe2010-10-13 22:37:165689 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415690 CreateMockRead(conn_resp, 1, ASYNC),
5691 CreateMockRead(wrapped_get_resp, 3, ASYNC),
5692 CreateMockRead(wrapped_body, 4, ASYNC),
5693 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:135694 MockRead(ASYNC, 0, 7),
[email protected]d9da5fe2010-10-13 22:37:165695 };
5696
Ryan Sleevib8d7ea02018-05-07 20:01:015697 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075698 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165699
[email protected]8ddf8322012-02-23 18:08:065700 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365701 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075702 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065703 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075704 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165705
[email protected]49639fa2011-12-20 23:22:415706 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165707
bnc691fda62016-08-12 00:43:165708 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015709 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165710
5711 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015712 ASSERT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:165713
[email protected]58e32bb2013-01-21 18:23:255714 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165715 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255716 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5717
bnc691fda62016-08-12 00:43:165718 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525719 ASSERT_TRUE(response);
5720 ASSERT_TRUE(response->headers);
[email protected]d9da5fe2010-10-13 22:37:165721 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5722
5723 std::string response_data;
bnc691fda62016-08-12 00:43:165724 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]d9da5fe2010-10-13 22:37:165725 EXPECT_EQ("1234567890", response_data);
5726}
5727
5728// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
bncd16676a2016-07-20 16:23:015729TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
5730 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:385731
[email protected]cb9bf6ca2011-01-28 13:15:275732 HttpRequestInfo request;
5733 request.method = "GET";
bncce36dca22015-04-21 22:11:235734 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105735 request.traffic_annotation =
5736 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275737
[email protected]d9da5fe2010-10-13 22:37:165738 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495739 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5740 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515741 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075742 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095743 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165744
bnc691fda62016-08-12 00:43:165745 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165746
bncce36dca22015-04-21 22:11:235747 // CONNECT to www.example.org:443 via SPDY
Ryan Hamilton0239aac2018-05-19 00:03:135748 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235749 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
5750 // fetch https://www.example.org/ via SPDY
5751 const char kMyUrl[] = "https://www.example.org/";
Ryan Hamilton0239aac2018-05-19 00:03:135752 spdy::SpdySerializedFrame get(
bnc38dcd392016-02-09 23:19:495753 spdy_util_wrapped.ConstructSpdyGet(kMyUrl, 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:135754 spdy::SpdySerializedFrame wrapped_get(
5755 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
5756 spdy::SpdySerializedFrame conn_resp(
5757 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
5758 spdy::SpdySerializedFrame get_resp(
bnc42331402016-07-25 13:36:155759 spdy_util_wrapped.ConstructSpdyGetReply(NULL, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135760 spdy::SpdySerializedFrame wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:025761 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135762 spdy::SpdySerializedFrame body(
5763 spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
5764 spdy::SpdySerializedFrame wrapped_body(
[email protected]23e482282013-06-14 16:08:025765 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135766 spdy::SpdySerializedFrame window_update_get_resp(
bncdf80d44fd2016-07-15 20:27:415767 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
Ryan Hamilton0239aac2018-05-19 00:03:135768 spdy::SpdySerializedFrame window_update_body(
bncdf80d44fd2016-07-15 20:27:415769 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
[email protected]8d2f7012012-02-16 00:08:045770
5771 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415772 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
5773 CreateMockWrite(window_update_get_resp, 6),
5774 CreateMockWrite(window_update_body, 7),
[email protected]8d2f7012012-02-16 00:08:045775 };
5776
[email protected]d9da5fe2010-10-13 22:37:165777 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415778 CreateMockRead(conn_resp, 1, ASYNC),
rch32320842015-05-16 15:57:095779 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:415780 CreateMockRead(wrapped_get_resp, 4, ASYNC),
5781 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:135782 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:165783 };
5784
Ryan Sleevib8d7ea02018-05-07 20:01:015785 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075786 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165787
[email protected]8ddf8322012-02-23 18:08:065788 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365789 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075790 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065791 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365792 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075793 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165794
[email protected]49639fa2011-12-20 23:22:415795 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165796
bnc691fda62016-08-12 00:43:165797 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015798 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165799
rch32320842015-05-16 15:57:095800 // Allow the SpdyProxyClientSocket's write callback to complete.
fdoray92e35a72016-06-10 15:54:555801 base::RunLoop().RunUntilIdle();
rch32320842015-05-16 15:57:095802 // Now allow the read of the response to complete.
mmenkee24011922015-12-17 22:12:595803 spdy_data.Resume();
[email protected]d9da5fe2010-10-13 22:37:165804 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015805 EXPECT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:165806
[email protected]58e32bb2013-01-21 18:23:255807 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165808 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255809 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5810
bnc691fda62016-08-12 00:43:165811 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525812 ASSERT_TRUE(response);
5813 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025814 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d9da5fe2010-10-13 22:37:165815
5816 std::string response_data;
bnc691fda62016-08-12 00:43:165817 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235818 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:165819}
5820
5821// Test a SPDY CONNECT failure through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015822TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:275823 HttpRequestInfo request;
5824 request.method = "GET";
bncce36dca22015-04-21 22:11:235825 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105826 request.traffic_annotation =
5827 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275828
[email protected]d9da5fe2010-10-13 22:37:165829 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495830 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5831 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515832 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075833 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095834 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165835
bnc691fda62016-08-12 00:43:165836 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165837
bncce36dca22015-04-21 22:11:235838 // CONNECT to www.example.org:443 via SPDY
Ryan Hamilton0239aac2018-05-19 00:03:135839 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235840 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:135841 spdy::SpdySerializedFrame get(
5842 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:165843
5844 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415845 CreateMockWrite(connect, 0), CreateMockWrite(get, 2),
[email protected]d9da5fe2010-10-13 22:37:165846 };
5847
Ryan Hamilton0239aac2018-05-19 00:03:135848 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(1));
5849 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:165850 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415851 CreateMockRead(resp, 1, ASYNC), MockRead(ASYNC, 0, 3),
[email protected]d9da5fe2010-10-13 22:37:165852 };
5853
Ryan Sleevib8d7ea02018-05-07 20:01:015854 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075855 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165856
[email protected]8ddf8322012-02-23 18:08:065857 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365858 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075859 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065860 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365861 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075862 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165863
[email protected]49639fa2011-12-20 23:22:415864 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165865
bnc691fda62016-08-12 00:43:165866 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015867 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165868
5869 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015870 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]d9da5fe2010-10-13 22:37:165871
ttuttle960fcbf2016-04-19 13:26:325872 // TODO(juliatuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:165873}
5874
Matt Menkecb2cd0982018-12-19 17:54:045875// Test the case where a proxied H2 session doesn't exist when an auth challenge
5876// is observed, but does exist by the time auth credentials are provided.
5877// Proxy-Connection: Close is used so that there's a second DNS lookup, which is
5878// what causes the existing H2 session to be noticed and reused.
5879TEST_F(HttpNetworkTransactionTest, ProxiedH2SessionAppearsDuringAuth) {
5880 ProxyConfig proxy_config;
5881 proxy_config.set_auto_detect(true);
5882 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
5883
5884 CapturingProxyResolver capturing_proxy_resolver;
5885 capturing_proxy_resolver.set_proxy_server(
5886 ProxyServer(ProxyServer::SCHEME_HTTP, HostPortPair("myproxy", 70)));
5887 session_deps_.proxy_resolution_service =
5888 std::make_unique<ProxyResolutionService>(
5889 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
5890 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
5891 std::make_unique<CapturingProxyResolverFactory>(
5892 &capturing_proxy_resolver),
5893 nullptr);
5894
5895 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
5896
5897 const char kMyUrl[] = "https://www.example.org/";
5898 spdy::SpdySerializedFrame get(spdy_util_.ConstructSpdyGet(kMyUrl, 1, LOWEST));
5899 spdy::SpdySerializedFrame get_resp(
5900 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
5901 spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
5902
5903 spdy_util_.UpdateWithStreamDestruction(1);
5904 spdy::SpdySerializedFrame get2(
5905 spdy_util_.ConstructSpdyGet(kMyUrl, 3, LOWEST));
5906 spdy::SpdySerializedFrame get_resp2(
5907 spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
5908 spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
5909
5910 MockWrite auth_challenge_writes[] = {
5911 MockWrite(ASYNC, 0,
5912 "CONNECT www.example.org:443 HTTP/1.1\r\n"
5913 "Host: www.example.org:443\r\n"
5914 "Proxy-Connection: keep-alive\r\n\r\n"),
5915 };
5916
5917 MockRead auth_challenge_reads[] = {
5918 MockRead(ASYNC, 1,
5919 "HTTP/1.1 407 Authentication Required\r\n"
5920 "Content-Length: 0\r\n"
5921 "Proxy-Connection: close\r\n"
5922 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
5923 };
5924
5925 MockWrite spdy_writes[] = {
5926 MockWrite(ASYNC, 0,
5927 "CONNECT www.example.org:443 HTTP/1.1\r\n"
5928 "Host: www.example.org:443\r\n"
5929 "Proxy-Connection: keep-alive\r\n"
5930 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5931 CreateMockWrite(get, 2),
5932 CreateMockWrite(get2, 5),
5933 };
5934
5935 MockRead spdy_reads[] = {
5936 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\n\r\n"),
5937 CreateMockRead(get_resp, 3, ASYNC),
5938 CreateMockRead(body, 4, ASYNC),
5939 CreateMockRead(get_resp2, 6, ASYNC),
5940 CreateMockRead(body2, 7, ASYNC),
5941
5942 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 8),
5943 };
5944
5945 SequencedSocketData auth_challenge1(auth_challenge_reads,
5946 auth_challenge_writes);
5947 session_deps_.socket_factory->AddSocketDataProvider(&auth_challenge1);
5948
5949 SequencedSocketData auth_challenge2(auth_challenge_reads,
5950 auth_challenge_writes);
5951 session_deps_.socket_factory->AddSocketDataProvider(&auth_challenge2);
5952
5953 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
5954 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
5955
5956 SSLSocketDataProvider ssl(ASYNC, OK);
5957 ssl.next_proto = kProtoHTTP2;
5958 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5959
5960 TestCompletionCallback callback;
5961 std::string response_data;
5962
5963 // Run first request until an auth challenge is observed.
5964 HttpRequestInfo request1;
5965 request1.method = "GET";
5966 request1.url = GURL(kMyUrl);
5967 request1.traffic_annotation =
5968 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5969 HttpNetworkTransaction trans1(LOWEST, session.get());
5970 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
5971 EXPECT_THAT(callback.GetResult(rv), IsOk());
5972 const HttpResponseInfo* response = trans1.GetResponseInfo();
5973 ASSERT_TRUE(response);
5974 ASSERT_TRUE(response->headers);
5975 EXPECT_EQ(407, response->headers->response_code());
5976 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5977 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
5978
5979 // Run second request until an auth challenge is observed.
5980 HttpRequestInfo request2;
5981 request2.method = "GET";
5982 request2.url = GURL(kMyUrl);
5983 request2.traffic_annotation =
5984 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5985 HttpNetworkTransaction trans2(LOWEST, session.get());
5986 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
5987 EXPECT_THAT(callback.GetResult(rv), IsOk());
5988 response = trans2.GetResponseInfo();
5989 ASSERT_TRUE(response);
5990 ASSERT_TRUE(response->headers);
5991 EXPECT_EQ(407, response->headers->response_code());
5992 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5993 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
5994
5995 // Now provide credentials for the first request, and wait for it to complete.
5996 rv = trans1.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
5997 rv = callback.GetResult(rv);
5998 EXPECT_THAT(rv, IsOk());
5999 response = trans1.GetResponseInfo();
6000 ASSERT_TRUE(response);
6001 ASSERT_TRUE(response->headers);
6002 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
6003 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
6004 EXPECT_EQ(kUploadData, response_data);
6005
6006 // Now provide credentials for the second request. It should notice the
6007 // existing session, and reuse it.
6008 rv = trans2.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
6009 EXPECT_THAT(callback.GetResult(rv), IsOk());
6010 response = trans2.GetResponseInfo();
6011 ASSERT_TRUE(response);
6012 ASSERT_TRUE(response->headers);
6013 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
6014 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
6015 EXPECT_EQ(kUploadData, response_data);
6016}
6017
[email protected]f6c63db52013-02-02 00:35:226018// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
6019// HTTPS Proxy to different servers.
bncd16676a2016-07-20 16:23:016020TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:226021 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
6022 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496023 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6024 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:516025 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076026 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:096027 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:506028 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:226029
6030 HttpRequestInfo request1;
6031 request1.method = "GET";
bncce36dca22015-04-21 22:11:236032 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:226033 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:106034 request1.traffic_annotation =
6035 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226036
6037 HttpRequestInfo request2;
6038 request2.method = "GET";
bncce36dca22015-04-21 22:11:236039 request2.url = GURL("https://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:226040 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:106041 request2.traffic_annotation =
6042 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226043
bncce36dca22015-04-21 22:11:236044 // CONNECT to www.example.org:443 via SPDY.
Ryan Hamilton0239aac2018-05-19 00:03:136045 spdy::SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:236046 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:136047 spdy::SpdySerializedFrame conn_resp1(
6048 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:226049
bncce36dca22015-04-21 22:11:236050 // Fetch https://www.example.org/ via HTTP.
6051 const char get1[] =
6052 "GET / HTTP/1.1\r\n"
6053 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:226054 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136055 spdy::SpdySerializedFrame wrapped_get1(
Bence Békyd74f4382018-02-20 18:26:196056 spdy_util_.ConstructSpdyDataFrame(1, get1, false));
[email protected]f6c63db52013-02-02 00:35:226057 const char resp1[] = "HTTP/1.1 200 OK\r\n"
6058 "Content-Length: 1\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136059 spdy::SpdySerializedFrame wrapped_get_resp1(
Bence Békyd74f4382018-02-20 18:26:196060 spdy_util_.ConstructSpdyDataFrame(1, resp1, false));
Ryan Hamilton0239aac2018-05-19 00:03:136061 spdy::SpdySerializedFrame wrapped_body1(
Bence Békyd74f4382018-02-20 18:26:196062 spdy_util_.ConstructSpdyDataFrame(1, "1", false));
Ryan Hamilton0239aac2018-05-19 00:03:136063 spdy::SpdySerializedFrame window_update(
bncdf80d44fd2016-07-15 20:27:416064 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:226065
bncce36dca22015-04-21 22:11:236066 // CONNECT to mail.example.org:443 via SPDY.
Ryan Hamilton0239aac2018-05-19 00:03:136067 spdy::SpdyHeaderBlock connect2_block;
6068 connect2_block[spdy::kHttp2MethodHeader] = "CONNECT";
6069 connect2_block[spdy::kHttp2AuthorityHeader] = "mail.example.org:443";
6070 spdy::SpdySerializedFrame connect2(spdy_util_.ConstructSpdyHeaders(
bnc42331402016-07-25 13:36:156071 3, std::move(connect2_block), LOWEST, false));
[email protected]601e03f12014-04-06 16:26:396072
Ryan Hamilton0239aac2018-05-19 00:03:136073 spdy::SpdySerializedFrame conn_resp2(
6074 spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:226075
bncce36dca22015-04-21 22:11:236076 // Fetch https://mail.example.org/ via HTTP.
6077 const char get2[] =
6078 "GET / HTTP/1.1\r\n"
6079 "Host: mail.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:226080 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136081 spdy::SpdySerializedFrame wrapped_get2(
Bence Békyd74f4382018-02-20 18:26:196082 spdy_util_.ConstructSpdyDataFrame(3, get2, false));
[email protected]f6c63db52013-02-02 00:35:226083 const char resp2[] = "HTTP/1.1 200 OK\r\n"
6084 "Content-Length: 2\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136085 spdy::SpdySerializedFrame wrapped_get_resp2(
Bence Békyd74f4382018-02-20 18:26:196086 spdy_util_.ConstructSpdyDataFrame(3, resp2, false));
Ryan Hamilton0239aac2018-05-19 00:03:136087 spdy::SpdySerializedFrame wrapped_body2(
Bence Békyd74f4382018-02-20 18:26:196088 spdy_util_.ConstructSpdyDataFrame(3, "22", false));
[email protected]f6c63db52013-02-02 00:35:226089
6090 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:416091 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
6092 CreateMockWrite(connect2, 5), CreateMockWrite(wrapped_get2, 7),
[email protected]f6c63db52013-02-02 00:35:226093 };
6094
6095 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:416096 CreateMockRead(conn_resp1, 1, ASYNC),
6097 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
6098 CreateMockRead(wrapped_body1, 4, ASYNC),
6099 CreateMockRead(conn_resp2, 6, ASYNC),
6100 CreateMockRead(wrapped_get_resp2, 8, ASYNC),
6101 CreateMockRead(wrapped_body2, 9, ASYNC),
6102 MockRead(ASYNC, 0, 10),
[email protected]f6c63db52013-02-02 00:35:226103 };
6104
Ryan Sleevib8d7ea02018-05-07 20:01:016105 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
mmenke11eb5152015-06-09 14:50:506106 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:226107
6108 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:366109 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:506110 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:226111 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:506112 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:226113 SSLSocketDataProvider ssl3(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:506114 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:226115
6116 TestCompletionCallback callback;
6117
bnc691fda62016-08-12 00:43:166118 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206119 int rv = trans.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016120 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:226121
6122 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:166123 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]f6c63db52013-02-02 00:35:226124 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
6125
bnc691fda62016-08-12 00:43:166126 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526127 ASSERT_TRUE(response);
6128 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:226129 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6130
6131 std::string response_data;
Victor Costan9c7302b2018-08-27 16:39:446132 scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(256);
bnc691fda62016-08-12 00:43:166133 rv = trans.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:506134 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:226135
bnc691fda62016-08-12 00:43:166136 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206137 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016138 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:226139
6140 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:166141 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:226142 // Even though the SPDY connection is reused, a new tunnelled connection has
6143 // to be created, so the socket's load timing looks like a fresh connection.
6144 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
6145
6146 // The requests should have different IDs, since they each are using their own
6147 // separate stream.
6148 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
6149
bnc691fda62016-08-12 00:43:166150 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:506151 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:226152}
6153
6154// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
6155// HTTPS Proxy to the same server.
bncd16676a2016-07-20 16:23:016156TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:226157 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
6158 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496159 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6160 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:516161 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076162 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:096163 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:506164 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:226165
6166 HttpRequestInfo request1;
6167 request1.method = "GET";
bncce36dca22015-04-21 22:11:236168 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:226169 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:106170 request1.traffic_annotation =
6171 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226172
6173 HttpRequestInfo request2;
6174 request2.method = "GET";
bncce36dca22015-04-21 22:11:236175 request2.url = GURL("https://www.example.org/2");
[email protected]f6c63db52013-02-02 00:35:226176 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:106177 request2.traffic_annotation =
6178 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226179
bncce36dca22015-04-21 22:11:236180 // CONNECT to www.example.org:443 via SPDY.
Ryan Hamilton0239aac2018-05-19 00:03:136181 spdy::SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:236182 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:136183 spdy::SpdySerializedFrame conn_resp1(
6184 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:226185
bncce36dca22015-04-21 22:11:236186 // Fetch https://www.example.org/ via HTTP.
6187 const char get1[] =
6188 "GET / HTTP/1.1\r\n"
6189 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:226190 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136191 spdy::SpdySerializedFrame wrapped_get1(
Bence Békyd74f4382018-02-20 18:26:196192 spdy_util_.ConstructSpdyDataFrame(1, get1, false));
[email protected]f6c63db52013-02-02 00:35:226193 const char resp1[] = "HTTP/1.1 200 OK\r\n"
6194 "Content-Length: 1\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136195 spdy::SpdySerializedFrame wrapped_get_resp1(
Bence Békyd74f4382018-02-20 18:26:196196 spdy_util_.ConstructSpdyDataFrame(1, resp1, false));
Ryan Hamilton0239aac2018-05-19 00:03:136197 spdy::SpdySerializedFrame wrapped_body1(
Bence Békyd74f4382018-02-20 18:26:196198 spdy_util_.ConstructSpdyDataFrame(1, "1", false));
Ryan Hamilton0239aac2018-05-19 00:03:136199 spdy::SpdySerializedFrame window_update(
bncdf80d44fd2016-07-15 20:27:416200 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:226201
bncce36dca22015-04-21 22:11:236202 // Fetch https://www.example.org/2 via HTTP.
6203 const char get2[] =
6204 "GET /2 HTTP/1.1\r\n"
6205 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:226206 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136207 spdy::SpdySerializedFrame wrapped_get2(
Bence Békyd74f4382018-02-20 18:26:196208 spdy_util_.ConstructSpdyDataFrame(1, get2, false));
[email protected]f6c63db52013-02-02 00:35:226209 const char resp2[] = "HTTP/1.1 200 OK\r\n"
6210 "Content-Length: 2\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136211 spdy::SpdySerializedFrame wrapped_get_resp2(
Bence Békyd74f4382018-02-20 18:26:196212 spdy_util_.ConstructSpdyDataFrame(1, resp2, false));
Ryan Hamilton0239aac2018-05-19 00:03:136213 spdy::SpdySerializedFrame wrapped_body2(
Bence Békyd74f4382018-02-20 18:26:196214 spdy_util_.ConstructSpdyDataFrame(1, "22", false));
[email protected]f6c63db52013-02-02 00:35:226215
6216 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:416217 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
6218 CreateMockWrite(wrapped_get2, 5),
[email protected]f6c63db52013-02-02 00:35:226219 };
6220
6221 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:416222 CreateMockRead(conn_resp1, 1, ASYNC),
6223 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
bnceb9aa7112017-01-05 01:03:466224 CreateMockRead(wrapped_body1, 4, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:416225 CreateMockRead(wrapped_get_resp2, 6, ASYNC),
bnceb9aa7112017-01-05 01:03:466226 CreateMockRead(wrapped_body2, 7, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:416227 MockRead(ASYNC, 0, 8),
[email protected]f6c63db52013-02-02 00:35:226228 };
6229
Ryan Sleevib8d7ea02018-05-07 20:01:016230 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
mmenke11eb5152015-06-09 14:50:506231 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:226232
6233 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:366234 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:506235 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:226236 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:506237 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:226238
6239 TestCompletionCallback callback;
6240
bnc87dcefc2017-05-25 12:47:586241 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:196242 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206243 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016244 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:226245
6246 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016247 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:226248
6249 LoadTimingInfo load_timing_info;
6250 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6251 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
6252
6253 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526254 ASSERT_TRUE(response);
6255 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:226256 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6257
6258 std::string response_data;
Victor Costan9c7302b2018-08-27 16:39:446259 scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(256);
[email protected]90499482013-06-01 00:39:506260 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:226261 trans.reset();
6262
bnc87dcefc2017-05-25 12:47:586263 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:196264 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206265 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016266 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:226267
[email protected]f6c63db52013-02-02 00:35:226268 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016269 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:226270
6271 LoadTimingInfo load_timing_info2;
6272 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
6273 TestLoadTimingReused(load_timing_info2);
6274
6275 // The requests should have the same ID.
6276 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
6277
[email protected]90499482013-06-01 00:39:506278 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:226279}
6280
6281// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
6282// Proxy to different servers.
bncd16676a2016-07-20 16:23:016283TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) {
[email protected]f6c63db52013-02-02 00:35:226284 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496285 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6286 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:516287 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076288 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:096289 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:506290 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:226291
6292 HttpRequestInfo request1;
6293 request1.method = "GET";
bncce36dca22015-04-21 22:11:236294 request1.url = GURL("http://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:226295 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:106296 request1.traffic_annotation =
6297 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226298
6299 HttpRequestInfo request2;
6300 request2.method = "GET";
bncce36dca22015-04-21 22:11:236301 request2.url = GURL("http://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:226302 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:106303 request2.traffic_annotation =
6304 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226305
bncce36dca22015-04-21 22:11:236306 // http://www.example.org/
Ryan Hamilton0239aac2018-05-19 00:03:136307 spdy::SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:236308 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
Ryan Hamilton0239aac2018-05-19 00:03:136309 spdy::SpdySerializedFrame get1(
bnc42331402016-07-25 13:36:156310 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
Ryan Hamilton0239aac2018-05-19 00:03:136311 spdy::SpdySerializedFrame get_resp1(
6312 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
6313 spdy::SpdySerializedFrame body1(
6314 spdy_util_.ConstructSpdyDataFrame(1, "1", true));
rdsmithebb50aa2015-11-12 03:44:386315 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]f6c63db52013-02-02 00:35:226316
bncce36dca22015-04-21 22:11:236317 // http://mail.example.org/
Ryan Hamilton0239aac2018-05-19 00:03:136318 spdy::SpdyHeaderBlock headers2(
bncce36dca22015-04-21 22:11:236319 spdy_util_.ConstructGetHeaderBlockForProxy("http://mail.example.org/"));
Ryan Hamilton0239aac2018-05-19 00:03:136320 spdy::SpdySerializedFrame get2(
bnc42331402016-07-25 13:36:156321 spdy_util_.ConstructSpdyHeaders(3, std::move(headers2), LOWEST, true));
Ryan Hamilton0239aac2018-05-19 00:03:136322 spdy::SpdySerializedFrame get_resp2(
6323 spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
6324 spdy::SpdySerializedFrame body2(
6325 spdy_util_.ConstructSpdyDataFrame(3, "22", true));
[email protected]f6c63db52013-02-02 00:35:226326
6327 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:416328 CreateMockWrite(get1, 0), CreateMockWrite(get2, 3),
[email protected]f6c63db52013-02-02 00:35:226329 };
6330
6331 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:416332 CreateMockRead(get_resp1, 1, ASYNC),
6333 CreateMockRead(body1, 2, ASYNC),
6334 CreateMockRead(get_resp2, 4, ASYNC),
6335 CreateMockRead(body2, 5, ASYNC),
6336 MockRead(ASYNC, 0, 6),
[email protected]f6c63db52013-02-02 00:35:226337 };
6338
Ryan Sleevib8d7ea02018-05-07 20:01:016339 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
mmenke11eb5152015-06-09 14:50:506340 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:226341
6342 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:366343 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:506344 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:226345
6346 TestCompletionCallback callback;
6347
bnc87dcefc2017-05-25 12:47:586348 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:196349 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206350 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016351 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:226352
6353 LoadTimingInfo load_timing_info;
6354 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6355 TestLoadTimingNotReused(load_timing_info,
6356 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6357
6358 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526359 ASSERT_TRUE(response);
6360 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:026361 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]f6c63db52013-02-02 00:35:226362
6363 std::string response_data;
Victor Costan9c7302b2018-08-27 16:39:446364 scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(256);
mmenke11eb5152015-06-09 14:50:506365 rv = trans->Read(buf.get(), 256, callback.callback());
6366 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:226367 // Delete the first request, so the second one can reuse the socket.
6368 trans.reset();
6369
bnc691fda62016-08-12 00:43:166370 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206371 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016372 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:226373
6374 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:166375 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:226376 TestLoadTimingReused(load_timing_info2);
6377
6378 // The requests should have the same ID.
6379 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
6380
bnc691fda62016-08-12 00:43:166381 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:506382 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:226383}
6384
Matt Menke2436b2f2018-12-11 18:07:116385// Test that an HTTP/2 CONNECT through an HTTPS Proxy to a HTTP/2 server and a
6386// direct (non-proxied) request to the proxy server are not pooled, as that
6387// would break socket pool isolation.
6388TEST_F(HttpNetworkTransactionTest, SpdyProxyIsolation1) {
6389 ProxyConfig proxy_config;
6390 proxy_config.set_auto_detect(true);
6391 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
6392
6393 CapturingProxyResolver capturing_proxy_resolver;
6394 session_deps_.proxy_resolution_service =
6395 std::make_unique<ProxyResolutionService>(
6396 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
6397 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
6398 std::make_unique<CapturingProxyResolverFactory>(
6399 &capturing_proxy_resolver),
6400 nullptr);
6401
6402 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6403
6404 SpdyTestUtil spdy_util1;
6405 // CONNECT to www.example.org:443 via HTTP/2.
6406 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
6407 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
6408 // fetch https://www.example.org/ via HTTP/2.
6409 const char kMyUrl[] = "https://www.example.org/";
6410 spdy::SpdySerializedFrame get(spdy_util1.ConstructSpdyGet(kMyUrl, 1, LOWEST));
6411 spdy::SpdySerializedFrame wrapped_get(
6412 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
6413 spdy::SpdySerializedFrame conn_resp(
6414 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
6415 spdy::SpdySerializedFrame get_resp(
6416 spdy_util1.ConstructSpdyGetReply(NULL, 0, 1));
6417 spdy::SpdySerializedFrame wrapped_get_resp(
6418 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
6419 spdy::SpdySerializedFrame body(spdy_util1.ConstructSpdyDataFrame(1, true));
6420 spdy::SpdySerializedFrame wrapped_body(
6421 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
6422 spdy::SpdySerializedFrame window_update_get_resp(
6423 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
6424 spdy::SpdySerializedFrame window_update_body(
6425 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
6426
6427 MockWrite spdy_writes1[] = {
6428 CreateMockWrite(connect, 0),
6429 CreateMockWrite(wrapped_get, 2),
6430 CreateMockWrite(window_update_get_resp, 6),
6431 CreateMockWrite(window_update_body, 7),
6432 };
6433
6434 MockRead spdy_reads1[] = {
6435 CreateMockRead(conn_resp, 1, ASYNC),
6436 MockRead(ASYNC, ERR_IO_PENDING, 3),
6437 CreateMockRead(wrapped_get_resp, 4, ASYNC),
6438 CreateMockRead(wrapped_body, 5, ASYNC),
6439 MockRead(ASYNC, 0, 8),
6440 };
6441
6442 SequencedSocketData spdy_data1(spdy_reads1, spdy_writes1);
6443 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data1);
6444
6445 // Fetch https://proxy:70/ via HTTP/2. Needs a new SpdyTestUtil, since it uses
6446 // a new pipe.
6447 SpdyTestUtil spdy_util2;
6448 spdy::SpdySerializedFrame req(
6449 spdy_util2.ConstructSpdyGet("https://proxy:70/", 1, LOWEST));
6450 MockWrite spdy_writes2[] = {CreateMockWrite(req, 0)};
6451
6452 spdy::SpdySerializedFrame resp(
6453 spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
6454 spdy::SpdySerializedFrame data(spdy_util2.ConstructSpdyDataFrame(1, true));
6455 MockRead spdy_reads2[] = {
6456 CreateMockRead(resp, 1),
6457 CreateMockRead(data, 2),
6458 MockRead(ASYNC, 0, 3),
6459 };
6460 SequencedSocketData spdy_data2(spdy_reads2, spdy_writes2);
6461 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data2);
6462
6463 SSLSocketDataProvider ssl(ASYNC, OK);
6464 ssl.next_proto = kProtoHTTP2;
6465 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6466 SSLSocketDataProvider ssl2(ASYNC, OK);
6467 ssl2.next_proto = kProtoHTTP2;
6468 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6469 SSLSocketDataProvider ssl3(ASYNC, OK);
6470 ssl3.next_proto = kProtoHTTP2;
6471 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
6472
6473 TestCompletionCallback callback;
6474 std::string response_data;
6475
6476 // Make a request using proxy:70 as a HTTP/2 proxy.
6477 capturing_proxy_resolver.set_proxy_server(
6478 ProxyServer(ProxyServer::SCHEME_HTTPS, HostPortPair("proxy", 70)));
6479 HttpRequestInfo request1;
6480 request1.method = "GET";
6481 request1.url = GURL("https://www.example.org/");
6482 request1.traffic_annotation =
6483 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6484
6485 HttpNetworkTransaction trans1(LOWEST, session.get());
6486 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
6487 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6488
6489 // Allow the SpdyProxyClientSocket's write callback to complete.
6490 base::RunLoop().RunUntilIdle();
6491 // Now allow the read of the response to complete.
6492 spdy_data1.Resume();
6493 rv = callback.WaitForResult();
6494 EXPECT_THAT(rv, IsOk());
6495
6496 const HttpResponseInfo* response = trans1.GetResponseInfo();
6497 ASSERT_TRUE(response);
6498 ASSERT_TRUE(response->headers);
6499 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
6500
6501 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
6502 EXPECT_EQ(kUploadData, response_data);
6503 RunUntilIdle();
6504
6505 // Make a direct HTTP/2 request to proxy:70.
6506 capturing_proxy_resolver.set_proxy_server(ProxyServer::Direct());
6507 HttpRequestInfo request2;
6508 request2.method = "GET";
6509 request2.url = GURL("https://proxy:70/");
6510 request2.traffic_annotation =
6511 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6512 HttpNetworkTransaction trans2(LOWEST, session.get());
6513 EXPECT_THAT(callback.GetResult(trans2.Start(&request2, callback.callback(),
6514 NetLogWithSource())),
6515 IsOk());
6516 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
6517}
6518
6519// Same as above, but reverse request order, since the code to check for an
6520// existing session is different for tunnels and direct connections.
6521TEST_F(HttpNetworkTransactionTest, SpdyProxyIsolation2) {
6522 // Configure against https proxy server "myproxy:80".
6523 ProxyConfig proxy_config;
6524 proxy_config.set_auto_detect(true);
6525 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
6526
6527 CapturingProxyResolver capturing_proxy_resolver;
6528 session_deps_.proxy_resolution_service =
6529 std::make_unique<ProxyResolutionService>(
6530 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
6531 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
6532 std::make_unique<CapturingProxyResolverFactory>(
6533 &capturing_proxy_resolver),
6534 nullptr);
6535
6536 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6537 // Fetch https://proxy:70/ via HTTP/2.
6538 SpdyTestUtil spdy_util1;
6539 spdy::SpdySerializedFrame req(
6540 spdy_util1.ConstructSpdyGet("https://proxy:70/", 1, LOWEST));
6541 MockWrite spdy_writes1[] = {CreateMockWrite(req, 0)};
6542
6543 spdy::SpdySerializedFrame resp(
6544 spdy_util1.ConstructSpdyGetReply(nullptr, 0, 1));
6545 spdy::SpdySerializedFrame data(spdy_util1.ConstructSpdyDataFrame(1, true));
6546 MockRead spdy_reads1[] = {
6547 CreateMockRead(resp, 1),
6548 CreateMockRead(data, 2),
6549 MockRead(ASYNC, 0, 3),
6550 };
6551 SequencedSocketData spdy_data1(spdy_reads1, spdy_writes1);
6552 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data1);
6553
6554 SpdyTestUtil spdy_util2;
6555 // CONNECT to www.example.org:443 via HTTP/2.
6556 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
6557 nullptr, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
6558 // fetch https://www.example.org/ via HTTP/2.
6559 const char kMyUrl[] = "https://www.example.org/";
6560 spdy::SpdySerializedFrame get(spdy_util2.ConstructSpdyGet(kMyUrl, 1, LOWEST));
6561 spdy::SpdySerializedFrame wrapped_get(
6562 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
6563 spdy::SpdySerializedFrame conn_resp(
6564 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
6565 spdy::SpdySerializedFrame get_resp(
6566 spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
6567 spdy::SpdySerializedFrame wrapped_get_resp(
6568 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
6569 spdy::SpdySerializedFrame body(spdy_util2.ConstructSpdyDataFrame(1, true));
6570 spdy::SpdySerializedFrame wrapped_body(
6571 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
6572 spdy::SpdySerializedFrame window_update_get_resp(
6573 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
6574 spdy::SpdySerializedFrame window_update_body(
6575 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
6576
6577 MockWrite spdy_writes2[] = {
6578 CreateMockWrite(connect, 0),
6579 CreateMockWrite(wrapped_get, 2),
6580 CreateMockWrite(window_update_get_resp, 6),
6581 CreateMockWrite(window_update_body, 7),
6582 };
6583
6584 MockRead spdy_reads2[] = {
6585 CreateMockRead(conn_resp, 1, ASYNC),
6586 MockRead(ASYNC, ERR_IO_PENDING, 3),
6587 CreateMockRead(wrapped_get_resp, 4, ASYNC),
6588 CreateMockRead(wrapped_body, 5, ASYNC),
6589 MockRead(ASYNC, 0, 8),
6590 };
6591
6592 SequencedSocketData spdy_data2(spdy_reads2, spdy_writes2);
6593 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data2);
6594
6595 SSLSocketDataProvider ssl(ASYNC, OK);
6596 ssl.next_proto = kProtoHTTP2;
6597 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6598 SSLSocketDataProvider ssl2(ASYNC, OK);
6599 ssl2.next_proto = kProtoHTTP2;
6600 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6601 SSLSocketDataProvider ssl3(ASYNC, OK);
6602 ssl3.next_proto = kProtoHTTP2;
6603 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
6604
6605 TestCompletionCallback callback;
6606 std::string response_data;
6607
6608 // Make a direct HTTP/2 request to proxy:70.
6609 capturing_proxy_resolver.set_proxy_server(ProxyServer::Direct());
6610 HttpRequestInfo request1;
6611 request1.method = "GET";
6612 request1.url = GURL("https://proxy:70/");
6613 request1.traffic_annotation =
6614 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6615 HttpNetworkTransaction trans1(LOWEST, session.get());
6616 EXPECT_THAT(callback.GetResult(trans1.Start(&request1, callback.callback(),
6617 NetLogWithSource())),
6618 IsOk());
6619 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
6620 RunUntilIdle();
6621
6622 // Make a request using proxy:70 as a HTTP/2 proxy.
6623 capturing_proxy_resolver.set_proxy_server(
6624 ProxyServer(ProxyServer::SCHEME_HTTPS, HostPortPair("proxy", 70)));
6625 HttpRequestInfo request2;
6626 request2.method = "GET";
6627 request2.url = GURL("https://www.example.org/");
6628 request2.traffic_annotation =
6629 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6630
6631 HttpNetworkTransaction trans2(LOWEST, session.get());
6632 int rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
6633 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6634
6635 // Allow the SpdyProxyClientSocket's write callback to complete.
6636 base::RunLoop().RunUntilIdle();
6637 // Now allow the read of the response to complete.
6638 spdy_data2.Resume();
6639 rv = callback.WaitForResult();
6640 EXPECT_THAT(rv, IsOk());
6641
6642 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
6643 ASSERT_TRUE(response2);
6644 ASSERT_TRUE(response2->headers);
6645 EXPECT_EQ("HTTP/1.1 200", response2->headers->GetStatusLine());
6646
6647 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
6648 EXPECT_EQ(kUploadData, response_data);
6649}
6650
[email protected]2df19bb2010-08-25 20:13:466651// Test the challenge-response-retry sequence through an HTTPS Proxy
bncd16676a2016-07-20 16:23:016652TEST_F(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:466653 HttpRequestInfo request;
6654 request.method = "GET";
bncce36dca22015-04-21 22:11:236655 request.url = GURL("http://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:466656 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:296657 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:106658 request.traffic_annotation =
6659 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:466660
[email protected]79cb5c12011-09-12 13:12:046661 // Configure against https proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496662 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6663 "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:516664 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076665 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:096666 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276667
[email protected]2df19bb2010-08-25 20:13:466668 // Since we have proxy, should use full url
6669 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:166670 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
6671 "Host: www.example.org\r\n"
6672 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:466673
bnc691fda62016-08-12 00:43:166674 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:236675 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:166676 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
6677 "Host: www.example.org\r\n"
6678 "Proxy-Connection: keep-alive\r\n"
6679 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:466680 };
6681
6682 // The proxy responds to the GET with a 407, using a persistent
6683 // connection.
6684 MockRead data_reads1[] = {
6685 // No credentials.
6686 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
6687 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6688 MockRead("Proxy-Connection: keep-alive\r\n"),
6689 MockRead("Content-Length: 0\r\n\r\n"),
6690
6691 MockRead("HTTP/1.1 200 OK\r\n"),
6692 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6693 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066694 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:466695 };
6696
Ryan Sleevib8d7ea02018-05-07 20:01:016697 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:076698 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:066699 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076700 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:466701
[email protected]49639fa2011-12-20 23:22:416702 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:466703
bnc691fda62016-08-12 00:43:166704 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506705
bnc691fda62016-08-12 00:43:166706 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:016707 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:466708
6709 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016710 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:466711
[email protected]58e32bb2013-01-21 18:23:256712 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:166713 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:256714 TestLoadTimingNotReused(load_timing_info,
6715 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6716
bnc691fda62016-08-12 00:43:166717 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526718 ASSERT_TRUE(response);
6719 ASSERT_TRUE(response->headers);
[email protected]2df19bb2010-08-25 20:13:466720 EXPECT_EQ(407, response->headers->response_code());
6721 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
asanka098c0092016-06-16 20:18:436722 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:466723
[email protected]49639fa2011-12-20 23:22:416724 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:466725
bnc691fda62016-08-12 00:43:166726 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:016727 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:466728
6729 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016730 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:466731
[email protected]58e32bb2013-01-21 18:23:256732 load_timing_info = LoadTimingInfo();
bnc691fda62016-08-12 00:43:166733 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:256734 // Retrying with HTTP AUTH is considered to be reusing a socket.
6735 TestLoadTimingReused(load_timing_info);
6736
bnc691fda62016-08-12 00:43:166737 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526738 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:466739
6740 EXPECT_TRUE(response->headers->IsKeepAlive());
6741 EXPECT_EQ(200, response->headers->response_code());
6742 EXPECT_EQ(100, response->headers->GetContentLength());
6743 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6744
6745 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:526746 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:466747}
6748
[email protected]23e482282013-06-14 16:08:026749void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:086750 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:426751 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:086752 request.method = "GET";
bncce36dca22015-04-21 22:11:236753 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:106754 request.traffic_annotation =
6755 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]c744cf22009-02-27 07:28:086756
[email protected]cb9bf6ca2011-01-28 13:15:276757 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496758 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6759 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:096760 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276761
[email protected]c744cf22009-02-27 07:28:086762 // Since we have proxy, should try to establish tunnel.
6763 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:176764 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
6765 "Host: www.example.org:443\r\n"
6766 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:086767 };
6768
6769 MockRead data_reads[] = {
mmenked39192ee2015-12-09 00:57:236770 status, MockRead("Content-Length: 10\r\n\r\n"),
6771 // No response body because the test stops reading here.
6772 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]c744cf22009-02-27 07:28:086773 };
6774
Ryan Sleevib8d7ea02018-05-07 20:01:016775 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:076776 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:086777
[email protected]49639fa2011-12-20 23:22:416778 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:086779
bnc691fda62016-08-12 00:43:166780 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506781
tfarina42834112016-09-22 13:38:206782 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016783 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]c744cf22009-02-27 07:28:086784
6785 rv = callback.WaitForResult();
6786 EXPECT_EQ(expected_status, rv);
6787}
6788
[email protected]23e482282013-06-14 16:08:026789void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:236790 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:086791 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:426792 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:086793}
6794
bncd16676a2016-07-20 16:23:016795TEST_F(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:086796 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
6797}
6798
bncd16676a2016-07-20 16:23:016799TEST_F(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:086800 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
6801}
6802
bncd16676a2016-07-20 16:23:016803TEST_F(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:086804 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
6805}
6806
bncd16676a2016-07-20 16:23:016807TEST_F(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:086808 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
6809}
6810
bncd16676a2016-07-20 16:23:016811TEST_F(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:086812 ConnectStatusHelper(
6813 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
6814}
6815
bncd16676a2016-07-20 16:23:016816TEST_F(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:086817 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
6818}
6819
bncd16676a2016-07-20 16:23:016820TEST_F(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:086821 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
6822}
6823
bncd16676a2016-07-20 16:23:016824TEST_F(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:086825 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
6826}
6827
bncd16676a2016-07-20 16:23:016828TEST_F(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:086829 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
6830}
6831
bncd16676a2016-07-20 16:23:016832TEST_F(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:086833 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
6834}
6835
bncd16676a2016-07-20 16:23:016836TEST_F(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:086837 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
6838}
6839
bncd16676a2016-07-20 16:23:016840TEST_F(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:086841 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
6842}
6843
bncd16676a2016-07-20 16:23:016844TEST_F(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:086845 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
6846}
6847
bncd16676a2016-07-20 16:23:016848TEST_F(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:086849 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
6850}
6851
bncd16676a2016-07-20 16:23:016852TEST_F(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:086853 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
6854}
6855
bncd16676a2016-07-20 16:23:016856TEST_F(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:086857 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
6858}
6859
bncd16676a2016-07-20 16:23:016860TEST_F(HttpNetworkTransactionTest, ConnectStatus308) {
[email protected]0a17aab32014-04-24 03:32:376861 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
6862}
6863
bncd16676a2016-07-20 16:23:016864TEST_F(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:086865 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
6866}
6867
bncd16676a2016-07-20 16:23:016868TEST_F(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:086869 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
6870}
6871
bncd16676a2016-07-20 16:23:016872TEST_F(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:086873 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
6874}
6875
bncd16676a2016-07-20 16:23:016876TEST_F(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:086877 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
6878}
6879
bncd16676a2016-07-20 16:23:016880TEST_F(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:086881 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
6882}
6883
bncd16676a2016-07-20 16:23:016884TEST_F(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:086885 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
6886}
6887
bncd16676a2016-07-20 16:23:016888TEST_F(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:086889 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
6890}
6891
bncd16676a2016-07-20 16:23:016892TEST_F(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:086893 ConnectStatusHelperWithExpectedStatus(
6894 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:546895 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:086896}
6897
bncd16676a2016-07-20 16:23:016898TEST_F(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:086899 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
6900}
6901
bncd16676a2016-07-20 16:23:016902TEST_F(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:086903 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
6904}
6905
bncd16676a2016-07-20 16:23:016906TEST_F(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:086907 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
6908}
6909
bncd16676a2016-07-20 16:23:016910TEST_F(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:086911 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
6912}
6913
bncd16676a2016-07-20 16:23:016914TEST_F(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:086915 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
6916}
6917
bncd16676a2016-07-20 16:23:016918TEST_F(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:086919 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
6920}
6921
bncd16676a2016-07-20 16:23:016922TEST_F(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:086923 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
6924}
6925
bncd16676a2016-07-20 16:23:016926TEST_F(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:086927 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
6928}
6929
bncd16676a2016-07-20 16:23:016930TEST_F(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:086931 ConnectStatusHelper(
6932 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
6933}
6934
bncd16676a2016-07-20 16:23:016935TEST_F(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:086936 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
6937}
6938
bncd16676a2016-07-20 16:23:016939TEST_F(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:086940 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
6941}
6942
bncd16676a2016-07-20 16:23:016943TEST_F(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:086944 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
6945}
6946
bncd16676a2016-07-20 16:23:016947TEST_F(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:086948 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
6949}
6950
bncd16676a2016-07-20 16:23:016951TEST_F(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:086952 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
6953}
6954
bncd16676a2016-07-20 16:23:016955TEST_F(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:086956 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
6957}
6958
bncd16676a2016-07-20 16:23:016959TEST_F(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:086960 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
6961}
6962
[email protected]038e9a32008-10-08 22:40:166963// Test the flow when both the proxy server AND origin server require
6964// authentication. Again, this uses basic auth for both since that is
6965// the simplest to mock.
bncd16676a2016-07-20 16:23:016966TEST_F(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:276967 HttpRequestInfo request;
6968 request.method = "GET";
bncce36dca22015-04-21 22:11:236969 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:106970 request.traffic_annotation =
6971 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:276972
[email protected]038e9a32008-10-08 22:40:166973 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496974 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6975 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:096976 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:076977
bnc691fda62016-08-12 00:43:166978 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]038e9a32008-10-08 22:40:166979
[email protected]f9ee6b52008-11-08 06:46:236980 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236981 MockWrite(
6982 "GET http://www.example.org/ HTTP/1.1\r\n"
6983 "Host: www.example.org\r\n"
6984 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236985 };
6986
[email protected]038e9a32008-10-08 22:40:166987 MockRead data_reads1[] = {
6988 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
6989 // Give a couple authenticate options (only the middle one is actually
6990 // supported).
[email protected]22927ad2009-09-21 19:56:196991 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:166992 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6993 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
6994 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6995 // Large content-length -- won't matter, as connection will be reset.
6996 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066997 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:166998 };
6999
bnc691fda62016-08-12 00:43:167000 // After calling trans.RestartWithAuth() the first time, this is the
[email protected]038e9a32008-10-08 22:40:167001 // request we should be issuing -- the final header line contains the
7002 // proxy's credentials.
7003 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237004 MockWrite(
7005 "GET http://www.example.org/ HTTP/1.1\r\n"
7006 "Host: www.example.org\r\n"
7007 "Proxy-Connection: keep-alive\r\n"
7008 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:167009 };
7010
7011 // Now the proxy server lets the request pass through to origin server.
7012 // The origin server responds with a 401.
7013 MockRead data_reads2[] = {
7014 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7015 // Note: We are using the same realm-name as the proxy server. This is
7016 // completely valid, as realms are unique across hosts.
7017 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7018 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7019 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067020 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:167021 };
7022
bnc691fda62016-08-12 00:43:167023 // After calling trans.RestartWithAuth() the second time, we should send
[email protected]038e9a32008-10-08 22:40:167024 // the credentials for both the proxy and origin server.
7025 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237026 MockWrite(
7027 "GET http://www.example.org/ HTTP/1.1\r\n"
7028 "Host: www.example.org\r\n"
7029 "Proxy-Connection: keep-alive\r\n"
7030 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
7031 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:167032 };
7033
7034 // Lastly we get the desired content.
7035 MockRead data_reads3[] = {
7036 MockRead("HTTP/1.0 200 OK\r\n"),
7037 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7038 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067039 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:167040 };
7041
Ryan Sleevib8d7ea02018-05-07 20:01:017042 StaticSocketDataProvider data1(data_reads1, data_writes1);
7043 StaticSocketDataProvider data2(data_reads2, data_writes2);
7044 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]bb88e1d32013-05-03 23:11:077045 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7046 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7047 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:167048
[email protected]49639fa2011-12-20 23:22:417049 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:167050
tfarina42834112016-09-22 13:38:207051 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017052 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:167053
7054 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017055 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:167056
bnc691fda62016-08-12 00:43:167057 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527058 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047059 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:167060
[email protected]49639fa2011-12-20 23:22:417061 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:167062
bnc691fda62016-08-12 00:43:167063 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:017064 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:167065
7066 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017067 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:167068
bnc691fda62016-08-12 00:43:167069 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527070 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047071 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:167072
[email protected]49639fa2011-12-20 23:22:417073 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:167074
bnc691fda62016-08-12 00:43:167075 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
7076 callback3.callback());
robpercival214763f2016-07-01 23:27:017077 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:167078
7079 rv = callback3.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 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:167084 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:167085}
[email protected]4ddaf2502008-10-23 18:26:197086
[email protected]ea9dc9a2009-09-05 00:43:327087// For the NTLM implementation using SSPI, we skip the NTLM tests since we
7088// can't hook into its internals to cause it to generate predictable NTLM
7089// authorization headers.
7090#if defined(NTLM_PORTABLE)
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377091// The NTLM authentication unit tests are based on known test data from the
7092// [MS-NLMP] Specification [1]. These tests are primarily of the authentication
7093// flow rather than the implementation of the NTLM protocol. See net/ntlm
7094// for the implementation and testing of the protocol.
7095//
7096// [1] https://msdn.microsoft.com/en-us/library/cc236621.aspx
[email protected]385a4672009-03-11 22:21:297097
7098// Enter the correct password and authenticate successfully.
Zentaro Kavanagh1890a3d2018-01-29 19:52:557099TEST_F(HttpNetworkTransactionTest, NTLMAuthV2) {
[email protected]1c773ea12009-04-28 19:58:427100 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:247101 request.method = "GET";
Zentaro Kavanagh1890a3d2018-01-29 19:52:557102 request.url = GURL("https://server/kids/login.aspx");
Ramin Halavatib5e433e62018-02-07 07:41:107103 request.traffic_annotation =
7104 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2217aa22013-10-11 03:03:547105
7106 // Ensure load is not disrupted by flags which suppress behaviour specific
7107 // to other auth schemes.
7108 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:247109
Zentaro Kavanagh6ccee512017-09-28 18:34:097110 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
7111 MockGetMSTime, MockGenerateRandom, MockGetHostName);
danakj1fd259a02016-04-16 03:17:097112 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277113
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377114 // Generate the NTLM messages based on known test data.
7115 std::string negotiate_msg;
7116 std::string challenge_msg;
7117 std::string authenticate_msg;
7118 base::Base64Encode(
7119 base::StringPiece(
7120 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
Avi Drissman4365a4782018-12-28 19:26:247121 base::size(ntlm::test::kExpectedNegotiateMsg)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377122 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:557123 base::Base64Encode(
7124 base::StringPiece(
7125 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
Avi Drissman4365a4782018-12-28 19:26:247126 base::size(ntlm::test::kChallengeMsgFromSpecV2)),
Zentaro Kavanagh1890a3d2018-01-29 19:52:557127 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377128 base::Base64Encode(
7129 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:097130 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557131 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
Avi Drissman4365a4782018-12-28 19:26:247132 base::size(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557133 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377134 &authenticate_msg);
7135
[email protected]3f918782009-02-28 01:29:247136 MockWrite data_writes1[] = {
Zentaro Kavanagh1890a3d2018-01-29 19:52:557137 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
7138 "Host: server\r\n"
7139 "Connection: keep-alive\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:247140 };
7141
7142 MockRead data_reads1[] = {
7143 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:047144 // Negotiate and NTLM are often requested together. However, we only want
7145 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
7146 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:247147 MockRead("WWW-Authenticate: NTLM\r\n"),
7148 MockRead("Connection: close\r\n"),
7149 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:367150 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:247151 // Missing content -- won't matter, as connection will be reset.
[email protected]3f918782009-02-28 01:29:247152 };
7153
7154 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:167155 // After restarting with a null identity, this is the
7156 // request we should be issuing -- the final header line contains a Type
7157 // 1 message.
7158 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557159 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167160 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377161 "Authorization: NTLM "),
7162 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:247163
bnc691fda62016-08-12 00:43:167164 // After calling trans.RestartWithAuth(), we should send a Type 3 message
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377165 // (using correct credentials). The second request continues on the
7166 // same connection.
bnc691fda62016-08-12 00:43:167167 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557168 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167169 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377170 "Authorization: NTLM "),
7171 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:247172 };
7173
7174 MockRead data_reads2[] = {
Bence Béky1e4ef192017-09-18 19:58:027175 // The origin server responds with a Type 2 message.
7176 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377177 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
7178 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky1e4ef192017-09-18 19:58:027179 MockRead("Content-Type: text/html\r\n\r\n"),
7180 MockRead("You are not authorized to view this page\r\n"),
[email protected]3f918782009-02-28 01:29:247181
Bence Béky1e4ef192017-09-18 19:58:027182 // Lastly we get the desired content.
7183 MockRead("HTTP/1.1 200 OK\r\n"),
7184 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
7185 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
[email protected]3f918782009-02-28 01:29:247186 };
7187
Ryan Sleevib8d7ea02018-05-07 20:01:017188 StaticSocketDataProvider data1(data_reads1, data_writes1);
7189 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:077190 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7191 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:247192
Bence Béky83eb3512017-09-05 12:56:097193 SSLSocketDataProvider ssl1(ASYNC, OK);
7194 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
7195 SSLSocketDataProvider ssl2(ASYNC, OK);
7196 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
7197
[email protected]49639fa2011-12-20 23:22:417198 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:247199
bnc691fda62016-08-12 00:43:167200 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:507201
tfarina42834112016-09-22 13:38:207202 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017203 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:247204
7205 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017206 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:247207
bnc691fda62016-08-12 00:43:167208 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227209
bnc691fda62016-08-12 00:43:167210 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527211 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047212 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:247213
[email protected]49639fa2011-12-20 23:22:417214 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:257215
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377216 rv = trans.RestartWithAuth(
7217 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
7218 callback2.callback());
robpercival214763f2016-07-01 23:27:017219 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:257220
7221 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017222 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:257223
bnc691fda62016-08-12 00:43:167224 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:257225
bnc691fda62016-08-12 00:43:167226 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527227 ASSERT_TRUE(response);
7228 EXPECT_FALSE(response->auth_challenge);
[email protected]10af5fe72011-01-31 16:17:257229
[email protected]49639fa2011-12-20 23:22:417230 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:247231
bnc691fda62016-08-12 00:43:167232 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:017233 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:247234
[email protected]0757e7702009-03-27 04:00:227235 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017236 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:247237
bnc691fda62016-08-12 00:43:167238 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527239 ASSERT_TRUE(response);
7240 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:027241 EXPECT_EQ(14, response->headers->GetContentLength());
7242
7243 std::string response_data;
7244 rv = ReadTransaction(&trans, &response_data);
7245 EXPECT_THAT(rv, IsOk());
7246 EXPECT_EQ("Please Login\r\n", response_data);
7247
7248 EXPECT_TRUE(data1.AllReadDataConsumed());
7249 EXPECT_TRUE(data1.AllWriteDataConsumed());
7250 EXPECT_TRUE(data2.AllReadDataConsumed());
7251 EXPECT_TRUE(data2.AllWriteDataConsumed());
[email protected]3f918782009-02-28 01:29:247252}
7253
[email protected]385a4672009-03-11 22:21:297254// Enter a wrong password, and then the correct one.
Zentaro Kavanagh1890a3d2018-01-29 19:52:557255TEST_F(HttpNetworkTransactionTest, NTLMAuthV2WrongThenRightPassword) {
[email protected]1c773ea12009-04-28 19:58:427256 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:297257 request.method = "GET";
Zentaro Kavanagh1890a3d2018-01-29 19:52:557258 request.url = GURL("https://server/kids/login.aspx");
Ramin Halavatib5e433e62018-02-07 07:41:107259 request.traffic_annotation =
7260 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]385a4672009-03-11 22:21:297261
Zentaro Kavanagh6ccee512017-09-28 18:34:097262 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
7263 MockGetMSTime, MockGenerateRandom, MockGetHostName);
danakj1fd259a02016-04-16 03:17:097264 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277265
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377266 // Generate the NTLM messages based on known test data.
7267 std::string negotiate_msg;
7268 std::string challenge_msg;
7269 std::string authenticate_msg;
7270 base::Base64Encode(
7271 base::StringPiece(
7272 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
Avi Drissman4365a4782018-12-28 19:26:247273 base::size(ntlm::test::kExpectedNegotiateMsg)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377274 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:557275 base::Base64Encode(
7276 base::StringPiece(
7277 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
Avi Drissman4365a4782018-12-28 19:26:247278 base::size(ntlm::test::kChallengeMsgFromSpecV2)),
Zentaro Kavanagh1890a3d2018-01-29 19:52:557279 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377280 base::Base64Encode(
7281 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:097282 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557283 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
Avi Drissman4365a4782018-12-28 19:26:247284 base::size(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557285 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377286 &authenticate_msg);
7287
7288 // The authenticate message when |kWrongPassword| is sent.
7289 std::string wrong_password_authenticate_msg(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557290 "TlRMTVNTUAADAAAAGAAYAFgAAACKAIoAcAAAAAwADAD6AAAACAAIAAYBAAAQABAADgEAAAAA"
7291 "AABYAAAAA4IIAAAAAAAAAAAAAPknEYqtJQtusopDRSfYzAAAAAAAAAAAAAAAAAAAAAAAAAAA"
7292 "AAAAAOtVz38osnFdRRggUQHUJ3EBAQAAAAAAAIALyP0A1NIBqqqqqqqqqqoAAAAAAgAMAEQA"
7293 "bwBtAGEAaQBuAAEADABTAGUAcgB2AGUAcgAGAAQAAgAAAAoAEAAAAAAAAAAAAAAAAAAAAAAA"
7294 "CQAWAEgAVABUAFAALwBzAGUAcgB2AGUAcgAAAAAAAAAAAEQAbwBtAGEAaQBuAFUAcwBlAHIA"
7295 "QwBPAE0AUABVAFQARQBSAA==");
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377296
Zentaro Kavanagh1890a3d2018-01-29 19:52:557297 // Sanity check that it's the same length as the correct authenticate message
7298 // and that it's different.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377299 ASSERT_EQ(authenticate_msg.length(),
7300 wrong_password_authenticate_msg.length());
Zentaro Kavanagh1890a3d2018-01-29 19:52:557301 ASSERT_NE(authenticate_msg, wrong_password_authenticate_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377302
[email protected]385a4672009-03-11 22:21:297303 MockWrite data_writes1[] = {
Zentaro Kavanagh1890a3d2018-01-29 19:52:557304 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
7305 "Host: server\r\n"
7306 "Connection: keep-alive\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297307 };
7308
7309 MockRead data_reads1[] = {
7310 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:047311 // Negotiate and NTLM are often requested together. However, we only want
7312 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
7313 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:297314 MockRead("WWW-Authenticate: NTLM\r\n"),
7315 MockRead("Connection: close\r\n"),
7316 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:367317 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297318 // Missing content -- won't matter, as connection will be reset.
[email protected]385a4672009-03-11 22:21:297319 };
7320
7321 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:167322 // After restarting with a null identity, this is the
7323 // request we should be issuing -- the final header line contains a Type
7324 // 1 message.
7325 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557326 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167327 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377328 "Authorization: NTLM "),
7329 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297330
bnc691fda62016-08-12 00:43:167331 // After calling trans.RestartWithAuth(), we should send a Type 3 message
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377332 // (using incorrect credentials). The second request continues on the
7333 // same connection.
bnc691fda62016-08-12 00:43:167334 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557335 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167336 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377337 "Authorization: NTLM "),
7338 MockWrite(wrong_password_authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297339 };
7340
7341 MockRead data_reads2[] = {
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377342 // The origin server responds with a Type 2 message.
7343 MockRead("HTTP/1.1 401 Access Denied\r\n"),
7344 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
7345 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
7346 MockRead("Content-Type: text/html\r\n\r\n"),
7347 MockRead("You are not authorized to view this page\r\n"),
[email protected]385a4672009-03-11 22:21:297348
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377349 // Wrong password.
7350 MockRead("HTTP/1.1 401 Access Denied\r\n"),
7351 MockRead("WWW-Authenticate: NTLM\r\n"), MockRead("Connection: close\r\n"),
7352 MockRead("Content-Length: 42\r\n"),
7353 MockRead("Content-Type: text/html\r\n\r\n"),
7354 // Missing content -- won't matter, as connection will be reset.
[email protected]385a4672009-03-11 22:21:297355 };
7356
7357 MockWrite data_writes3[] = {
bnc691fda62016-08-12 00:43:167358 // After restarting with a null identity, this is the
7359 // request we should be issuing -- the final header line contains a Type
7360 // 1 message.
7361 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557362 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167363 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377364 "Authorization: NTLM "),
7365 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297366
bnc691fda62016-08-12 00:43:167367 // After calling trans.RestartWithAuth(), we should send a Type 3 message
7368 // (the credentials for the origin server). The second request continues
7369 // on the same connection.
7370 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557371 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167372 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377373 "Authorization: NTLM "),
7374 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297375 };
7376
7377 MockRead data_reads3[] = {
Bence Béky1e4ef192017-09-18 19:58:027378 // The origin server responds with a Type 2 message.
7379 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377380 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
7381 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky1e4ef192017-09-18 19:58:027382 MockRead("Content-Type: text/html\r\n\r\n"),
7383 MockRead("You are not authorized to view this page\r\n"),
[email protected]385a4672009-03-11 22:21:297384
Bence Béky1e4ef192017-09-18 19:58:027385 // Lastly we get the desired content.
7386 MockRead("HTTP/1.1 200 OK\r\n"),
7387 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
7388 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
[email protected]385a4672009-03-11 22:21:297389 };
7390
Ryan Sleevib8d7ea02018-05-07 20:01:017391 StaticSocketDataProvider data1(data_reads1, data_writes1);
7392 StaticSocketDataProvider data2(data_reads2, data_writes2);
7393 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]bb88e1d32013-05-03 23:11:077394 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7395 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7396 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:297397
Bence Béky83eb3512017-09-05 12:56:097398 SSLSocketDataProvider ssl1(ASYNC, OK);
7399 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
7400 SSLSocketDataProvider ssl2(ASYNC, OK);
7401 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
7402 SSLSocketDataProvider ssl3(ASYNC, OK);
7403 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
7404
[email protected]49639fa2011-12-20 23:22:417405 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:297406
bnc691fda62016-08-12 00:43:167407 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:507408
tfarina42834112016-09-22 13:38:207409 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017410 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:297411
7412 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017413 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:297414
bnc691fda62016-08-12 00:43:167415 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:297416
bnc691fda62016-08-12 00:43:167417 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527418 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047419 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:297420
[email protected]49639fa2011-12-20 23:22:417421 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:297422
[email protected]0757e7702009-03-27 04:00:227423 // Enter the wrong password.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377424 rv = trans.RestartWithAuth(
7425 AuthCredentials(ntlm::test::kDomainUserCombined, kWrongPassword),
7426 callback2.callback());
robpercival214763f2016-07-01 23:27:017427 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:297428
[email protected]10af5fe72011-01-31 16:17:257429 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017430 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:297431
bnc691fda62016-08-12 00:43:167432 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:417433 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:167434 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:017435 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:257436 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017437 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167438 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227439
bnc691fda62016-08-12 00:43:167440 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527441 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047442 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:227443
[email protected]49639fa2011-12-20 23:22:417444 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:227445
7446 // Now enter the right password.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377447 rv = trans.RestartWithAuth(
7448 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
7449 callback4.callback());
robpercival214763f2016-07-01 23:27:017450 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:257451
7452 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:017453 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:257454
bnc691fda62016-08-12 00:43:167455 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:257456
[email protected]49639fa2011-12-20 23:22:417457 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:257458
7459 // One more roundtrip
bnc691fda62016-08-12 00:43:167460 rv = trans.RestartWithAuth(AuthCredentials(), callback5.callback());
robpercival214763f2016-07-01 23:27:017461 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:227462
7463 rv = callback5.WaitForResult();
robpercival214763f2016-07-01 23:27:017464 EXPECT_THAT(rv, IsOk());
[email protected]0757e7702009-03-27 04:00:227465
bnc691fda62016-08-12 00:43:167466 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527467 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:027468 EXPECT_EQ(14, response->headers->GetContentLength());
7469
7470 std::string response_data;
7471 rv = ReadTransaction(&trans, &response_data);
7472 EXPECT_THAT(rv, IsOk());
7473 EXPECT_EQ("Please Login\r\n", response_data);
7474
7475 EXPECT_TRUE(data1.AllReadDataConsumed());
7476 EXPECT_TRUE(data1.AllWriteDataConsumed());
7477 EXPECT_TRUE(data2.AllReadDataConsumed());
7478 EXPECT_TRUE(data2.AllWriteDataConsumed());
7479 EXPECT_TRUE(data3.AllReadDataConsumed());
7480 EXPECT_TRUE(data3.AllWriteDataConsumed());
[email protected]385a4672009-03-11 22:21:297481}
Bence Béky83eb3512017-09-05 12:56:097482
Bence Béky3238f2e12017-09-22 22:44:497483// Server requests NTLM authentication, which is not supported over HTTP/2.
7484// Subsequent request with authorization header should be sent over HTTP/1.1.
Bence Béky83eb3512017-09-05 12:56:097485TEST_F(HttpNetworkTransactionTest, NTLMOverHttp2) {
Zentaro Kavanagh6ccee512017-09-28 18:34:097486 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
7487 MockGetMSTime, MockGenerateRandom, MockGetHostName);
Bence Béky83eb3512017-09-05 12:56:097488
Zentaro Kavanagh1890a3d2018-01-29 19:52:557489 const char* kUrl = "https://server/kids/login.aspx";
Bence Béky83eb3512017-09-05 12:56:097490
7491 HttpRequestInfo request;
7492 request.method = "GET";
7493 request.url = GURL(kUrl);
Ramin Halavatib5e433e62018-02-07 07:41:107494 request.traffic_annotation =
7495 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Béky83eb3512017-09-05 12:56:097496
7497 // First request without credentials.
Ryan Hamilton0239aac2018-05-19 00:03:137498 spdy::SpdyHeaderBlock request_headers0(
7499 spdy_util_.ConstructGetHeaderBlock(kUrl));
7500 spdy::SpdySerializedFrame request0(spdy_util_.ConstructSpdyHeaders(
Bence Béky83eb3512017-09-05 12:56:097501 1, std::move(request_headers0), LOWEST, true));
7502
Ryan Hamilton0239aac2018-05-19 00:03:137503 spdy::SpdyHeaderBlock response_headers0;
7504 response_headers0[spdy::kHttp2StatusHeader] = "401";
Bence Béky83eb3512017-09-05 12:56:097505 response_headers0["www-authenticate"] = "NTLM";
Ryan Hamilton0239aac2018-05-19 00:03:137506 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyResponseHeaders(
Bence Béky83eb3512017-09-05 12:56:097507 1, std::move(response_headers0), true));
7508
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377509 // Stream 1 is closed.
7510 spdy_util_.UpdateWithStreamDestruction(1);
7511
7512 // Generate the NTLM messages based on known test data.
7513 std::string negotiate_msg;
7514 std::string challenge_msg;
7515 std::string authenticate_msg;
7516 base::Base64Encode(
7517 base::StringPiece(
7518 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
Avi Drissman4365a4782018-12-28 19:26:247519 base::size(ntlm::test::kExpectedNegotiateMsg)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377520 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:557521 base::Base64Encode(
7522 base::StringPiece(
7523 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
Avi Drissman4365a4782018-12-28 19:26:247524 base::size(ntlm::test::kChallengeMsgFromSpecV2)),
Zentaro Kavanagh1890a3d2018-01-29 19:52:557525 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377526 base::Base64Encode(
7527 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:097528 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557529 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
Avi Drissman4365a4782018-12-28 19:26:247530 base::size(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557531 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377532 &authenticate_msg);
7533
7534 // Retry with authorization header.
Ryan Hamilton0239aac2018-05-19 00:03:137535 spdy::SpdyHeaderBlock request_headers1(
7536 spdy_util_.ConstructGetHeaderBlock(kUrl));
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377537 request_headers1["authorization"] = std::string("NTLM ") + negotiate_msg;
Ryan Hamilton0239aac2018-05-19 00:03:137538 spdy::SpdySerializedFrame request1(spdy_util_.ConstructSpdyHeaders(
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377539 3, std::move(request_headers1), LOWEST, true));
7540
Ryan Hamilton0239aac2018-05-19 00:03:137541 spdy::SpdySerializedFrame rst(
7542 spdy_util_.ConstructSpdyRstStream(3, spdy::ERROR_CODE_HTTP_1_1_REQUIRED));
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377543
Bence Béky3238f2e12017-09-22 22:44:497544 MockWrite writes0[] = {CreateMockWrite(request0, 0)};
7545 MockRead reads0[] = {CreateMockRead(resp, 1), MockRead(ASYNC, 0, 2)};
Bence Béky83eb3512017-09-05 12:56:097546
7547 // Retry yet again using HTTP/1.1.
7548 MockWrite writes1[] = {
7549 // After restarting with a null identity, this is the
7550 // request we should be issuing -- the final header line contains a Type
7551 // 1 message.
7552 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557553 "Host: server\r\n"
Bence Béky83eb3512017-09-05 12:56:097554 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377555 "Authorization: NTLM "),
7556 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
Bence Béky83eb3512017-09-05 12:56:097557
7558 // After calling trans.RestartWithAuth(), we should send a Type 3 message
7559 // (the credentials for the origin server). The second request continues
7560 // on the same connection.
7561 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557562 "Host: server\r\n"
Bence Béky83eb3512017-09-05 12:56:097563 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377564 "Authorization: NTLM "),
7565 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
Bence Béky83eb3512017-09-05 12:56:097566 };
7567
7568 MockRead reads1[] = {
7569 // The origin server responds with a Type 2 message.
7570 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377571 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
7572 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky83eb3512017-09-05 12:56:097573 MockRead("Content-Type: text/html\r\n\r\n"),
7574 MockRead("You are not authorized to view this page\r\n"),
7575
7576 // Lastly we get the desired content.
7577 MockRead("HTTP/1.1 200 OK\r\n"),
7578 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
Bence Béky1e4ef192017-09-18 19:58:027579 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
Bence Béky83eb3512017-09-05 12:56:097580 };
Ryan Sleevib8d7ea02018-05-07 20:01:017581 SequencedSocketData data0(reads0, writes0);
7582 StaticSocketDataProvider data1(reads1, writes1);
Bence Béky83eb3512017-09-05 12:56:097583 session_deps_.socket_factory->AddSocketDataProvider(&data0);
7584 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7585
7586 SSLSocketDataProvider ssl0(ASYNC, OK);
7587 ssl0.next_proto = kProtoHTTP2;
7588 SSLSocketDataProvider ssl1(ASYNC, OK);
7589 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl0);
7590 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
7591
7592 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7593 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
7594
7595 TestCompletionCallback callback1;
7596 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
7597 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7598
7599 rv = callback1.WaitForResult();
7600 EXPECT_THAT(rv, IsOk());
7601
7602 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
7603
7604 const HttpResponseInfo* response = trans.GetResponseInfo();
7605 ASSERT_TRUE(response);
7606 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
7607
7608 TestCompletionCallback callback2;
7609
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377610 rv = trans.RestartWithAuth(
7611 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
7612 callback2.callback());
Bence Béky83eb3512017-09-05 12:56:097613 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7614
7615 rv = callback2.WaitForResult();
7616 EXPECT_THAT(rv, IsOk());
7617
7618 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
7619
7620 response = trans.GetResponseInfo();
7621 ASSERT_TRUE(response);
7622 EXPECT_FALSE(response->auth_challenge);
7623
7624 TestCompletionCallback callback3;
7625
7626 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
7627 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7628
7629 rv = callback3.WaitForResult();
7630 EXPECT_THAT(rv, IsOk());
7631
7632 response = trans.GetResponseInfo();
7633 ASSERT_TRUE(response);
7634 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:027635 EXPECT_EQ(14, response->headers->GetContentLength());
7636
7637 std::string response_data;
7638 rv = ReadTransaction(&trans, &response_data);
7639 EXPECT_THAT(rv, IsOk());
7640 EXPECT_EQ("Please Login\r\n", response_data);
7641
7642 EXPECT_TRUE(data0.AllReadDataConsumed());
7643 EXPECT_TRUE(data0.AllWriteDataConsumed());
7644 EXPECT_TRUE(data1.AllReadDataConsumed());
7645 EXPECT_TRUE(data1.AllWriteDataConsumed());
Bence Béky83eb3512017-09-05 12:56:097646}
David Benjamin5cb91132018-04-06 05:54:497647
7648// Test that, if we have an NTLM proxy and the origin resets the connection, we
7649// do no retry forever checking for TLS version interference. This is a
7650// regression test for https://crbug.com/823387.
7651TEST_F(HttpNetworkTransactionTest, NTLMProxyTLSHandshakeReset) {
7652 // The NTLM test data expects the proxy to be named 'server'. The origin is
7653 // https://origin/.
7654 session_deps_.proxy_resolution_service =
7655 ProxyResolutionService::CreateFixedFromPacResult(
7656 "PROXY server", TRAFFIC_ANNOTATION_FOR_TESTS);
7657
7658 SSLConfig config;
David Benjamin5cb91132018-04-06 05:54:497659 session_deps_.ssl_config_service =
Ryan Sleevib8449e02018-07-15 04:31:077660 std::make_unique<TestSSLConfigService>(config);
David Benjamin5cb91132018-04-06 05:54:497661
7662 HttpRequestInfo request;
7663 request.method = "GET";
7664 request.url = GURL("https://origin/");
7665 request.traffic_annotation =
7666 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7667
7668 // Ensure load is not disrupted by flags which suppress behaviour specific
7669 // to other auth schemes.
7670 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
7671
7672 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
7673 MockGetMSTime, MockGenerateRandom, MockGetHostName);
7674 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7675
7676 // Generate the NTLM messages based on known test data.
7677 std::string negotiate_msg;
7678 std::string challenge_msg;
7679 std::string authenticate_msg;
7680 base::Base64Encode(
7681 base::StringPiece(
7682 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
Avi Drissman4365a4782018-12-28 19:26:247683 base::size(ntlm::test::kExpectedNegotiateMsg)),
David Benjamin5cb91132018-04-06 05:54:497684 &negotiate_msg);
7685 base::Base64Encode(
7686 base::StringPiece(
7687 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
Avi Drissman4365a4782018-12-28 19:26:247688 base::size(ntlm::test::kChallengeMsgFromSpecV2)),
David Benjamin5cb91132018-04-06 05:54:497689 &challenge_msg);
7690 base::Base64Encode(
7691 base::StringPiece(
7692 reinterpret_cast<const char*>(
7693 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
Avi Drissman4365a4782018-12-28 19:26:247694 base::size(
David Benjamin5cb91132018-04-06 05:54:497695 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
7696 &authenticate_msg);
7697
7698 MockWrite data_writes[] = {
7699 // The initial CONNECT request.
7700 MockWrite("CONNECT origin:443 HTTP/1.1\r\n"
7701 "Host: origin:443\r\n"
7702 "Proxy-Connection: keep-alive\r\n\r\n"),
7703
7704 // After restarting with an identity.
7705 MockWrite("CONNECT origin:443 HTTP/1.1\r\n"
7706 "Host: origin:443\r\n"
7707 "Proxy-Connection: keep-alive\r\n"
7708 "Proxy-Authorization: NTLM "),
7709 MockWrite(negotiate_msg.c_str()),
7710 // End headers.
7711 MockWrite("\r\n\r\n"),
7712
7713 // The second restart.
7714 MockWrite("CONNECT origin:443 HTTP/1.1\r\n"
7715 "Host: origin:443\r\n"
7716 "Proxy-Connection: keep-alive\r\n"
7717 "Proxy-Authorization: NTLM "),
7718 MockWrite(authenticate_msg.c_str()),
7719 // End headers.
7720 MockWrite("\r\n\r\n"),
7721 };
7722
7723 MockRead data_reads[] = {
7724 // The initial NTLM response.
7725 MockRead("HTTP/1.1 407 Access Denied\r\n"
7726 "Content-Length: 0\r\n"
7727 "Proxy-Authenticate: NTLM\r\n\r\n"),
7728
7729 // The NTLM challenge message.
7730 MockRead("HTTP/1.1 407 Access Denied\r\n"
7731 "Content-Length: 0\r\n"
7732 "Proxy-Authenticate: NTLM "),
7733 MockRead(challenge_msg.c_str()),
7734 // End headers.
7735 MockRead("\r\n\r\n"),
7736
7737 // Finally the tunnel is established.
7738 MockRead("HTTP/1.1 200 Connected\r\n\r\n"),
7739 };
7740
Ryan Sleevib8d7ea02018-05-07 20:01:017741 StaticSocketDataProvider data(data_reads, data_writes);
David Benjamin5cb91132018-04-06 05:54:497742 SSLSocketDataProvider data_ssl(ASYNC, ERR_CONNECTION_RESET);
Ryan Sleevib8d7ea02018-05-07 20:01:017743 StaticSocketDataProvider data2(data_reads, data_writes);
David Benjamin5cb91132018-04-06 05:54:497744 SSLSocketDataProvider data_ssl2(ASYNC, ERR_CONNECTION_RESET);
Steven Valdez0ef94d02018-11-19 23:28:137745 data_ssl2.expected_ssl_version_max = SSL_PROTOCOL_VERSION_TLS1_2;
David Benjamin5cb91132018-04-06 05:54:497746 session_deps_.socket_factory->AddSocketDataProvider(&data);
7747 session_deps_.socket_factory->AddSSLSocketDataProvider(&data_ssl);
7748 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7749 session_deps_.socket_factory->AddSSLSocketDataProvider(&data_ssl2);
7750
7751 // Start the transaction. The proxy responds with an NTLM authentication
7752 // request.
7753 TestCompletionCallback callback;
7754 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
7755 int rv = callback.GetResult(
7756 trans.Start(&request, callback.callback(), NetLogWithSource()));
7757
7758 EXPECT_THAT(rv, IsOk());
7759 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
7760 const HttpResponseInfo* response = trans.GetResponseInfo();
7761 ASSERT_TRUE(response);
7762 EXPECT_TRUE(CheckNTLMProxyAuth(response->auth_challenge.get()));
7763
7764 // Configure credentials. The proxy responds with the challenge message.
7765 rv = callback.GetResult(trans.RestartWithAuth(
7766 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
7767 callback.callback()));
7768 EXPECT_THAT(rv, IsOk());
7769 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
7770 response = trans.GetResponseInfo();
7771 ASSERT_TRUE(response);
7772 EXPECT_FALSE(response->auth_challenge);
7773
7774 // Restart once more. The tunnel will be established and the the SSL handshake
7775 // will reset. The TLS 1.3 version interference probe will then kick in and
7776 // restart the process. The proxy responds with another NTLM authentiation
7777 // request, but we don't need to provide credentials as the cached ones work/
7778 rv = callback.GetResult(
7779 trans.RestartWithAuth(AuthCredentials(), callback.callback()));
7780 EXPECT_THAT(rv, IsOk());
7781 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
7782 response = trans.GetResponseInfo();
7783 ASSERT_TRUE(response);
7784 EXPECT_FALSE(response->auth_challenge);
7785
7786 // The proxy responds with the NTLM challenge message.
7787 rv = callback.GetResult(
7788 trans.RestartWithAuth(AuthCredentials(), callback.callback()));
7789 EXPECT_THAT(rv, IsOk());
7790 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
7791 response = trans.GetResponseInfo();
7792 ASSERT_TRUE(response);
7793 EXPECT_FALSE(response->auth_challenge);
7794
7795 // Send the NTLM authenticate message. The tunnel is established and the
7796 // handshake resets again. We should not retry again.
7797 rv = callback.GetResult(
7798 trans.RestartWithAuth(AuthCredentials(), callback.callback()));
7799 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
7800}
7801
[email protected]ea9dc9a2009-09-05 00:43:327802#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:297803
[email protected]4ddaf2502008-10-23 18:26:197804// Test reading a server response which has only headers, and no body.
7805// After some maximum number of bytes is consumed, the transaction should
7806// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
bncd16676a2016-07-20 16:23:017807TEST_F(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:427808 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:197809 request.method = "GET";
bncce36dca22015-04-21 22:11:237810 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:107811 request.traffic_annotation =
7812 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]4ddaf2502008-10-23 18:26:197813
danakj1fd259a02016-04-16 03:17:097814 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167815 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277816
[email protected]b75b7b2f2009-10-06 00:54:537817 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:437818 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:537819 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:197820
7821 MockRead data_reads[] = {
7822 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:067823 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:197824 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:067825 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:197826 };
Ryan Sleevib8d7ea02018-05-07 20:01:017827 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:077828 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:197829
[email protected]49639fa2011-12-20 23:22:417830 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:197831
tfarina42834112016-09-22 13:38:207832 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017833 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]4ddaf2502008-10-23 18:26:197834
7835 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017836 EXPECT_THAT(rv, IsError(ERR_RESPONSE_HEADERS_TOO_BIG));
[email protected]4ddaf2502008-10-23 18:26:197837}
[email protected]f4e426b2008-11-05 00:24:497838
7839// Make sure that we don't try to reuse a TCPClientSocket when failing to
7840// establish tunnel.
7841// http://code.google.com/p/chromium/issues/detail?id=3772
bncd16676a2016-07-20 16:23:017842TEST_F(HttpNetworkTransactionTest, DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:277843 HttpRequestInfo request;
7844 request.method = "GET";
bncce36dca22015-04-21 22:11:237845 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:107846 request.traffic_annotation =
7847 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:277848
[email protected]f4e426b2008-11-05 00:24:497849 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:497850 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
7851 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]db8f44c2008-12-13 04:52:017852
danakj1fd259a02016-04-16 03:17:097853 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:497854
bnc87dcefc2017-05-25 12:47:587855 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:197856 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]f4e426b2008-11-05 00:24:497857
[email protected]f4e426b2008-11-05 00:24:497858 // Since we have proxy, should try to establish tunnel.
7859 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:177860 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7861 "Host: www.example.org:443\r\n"
7862 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:497863 };
7864
[email protected]77848d12008-11-14 00:00:227865 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:497866 // connection. Usually a proxy would return 501 (not implemented),
7867 // or 200 (tunnel established).
7868 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:237869 MockRead("HTTP/1.1 404 Not Found\r\n"),
7870 MockRead("Content-Length: 10\r\n\r\n"),
7871 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]f4e426b2008-11-05 00:24:497872 };
7873
Ryan Sleevib8d7ea02018-05-07 20:01:017874 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:077875 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:497876
[email protected]49639fa2011-12-20 23:22:417877 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:497878
tfarina42834112016-09-22 13:38:207879 int rv = trans->Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017880 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f4e426b2008-11-05 00:24:497881
7882 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017883 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]f4e426b2008-11-05 00:24:497884
[email protected]b4404c02009-04-10 16:38:527885 // Empty the current queue. This is necessary because idle sockets are
7886 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557887 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:527888
[email protected]f4e426b2008-11-05 00:24:497889 // We now check to make sure the TCPClientSocket was not added back to
7890 // the pool.
[email protected]90499482013-06-01 00:39:507891 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:497892 trans.reset();
fdoray92e35a72016-06-10 15:54:557893 base::RunLoop().RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:497894 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:507895 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:497896}
[email protected]372d34a2008-11-05 21:30:517897
[email protected]1b157c02009-04-21 01:55:407898// Make sure that we recycle a socket after reading all of the response body.
bncd16676a2016-07-20 16:23:017899TEST_F(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:427900 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:407901 request.method = "GET";
bncce36dca22015-04-21 22:11:237902 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:107903 request.traffic_annotation =
7904 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1b157c02009-04-21 01:55:407905
danakj1fd259a02016-04-16 03:17:097906 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277907
bnc691fda62016-08-12 00:43:167908 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277909
[email protected]1b157c02009-04-21 01:55:407910 MockRead data_reads[] = {
7911 // A part of the response body is received with the response headers.
7912 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
7913 // The rest of the response body is received in two parts.
7914 MockRead("lo"),
7915 MockRead(" world"),
7916 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:067917 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:407918 };
7919
Ryan Sleevib8d7ea02018-05-07 20:01:017920 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:077921 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:407922
[email protected]49639fa2011-12-20 23:22:417923 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:407924
tfarina42834112016-09-22 13:38:207925 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017926 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1b157c02009-04-21 01:55:407927
7928 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017929 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:407930
bnc691fda62016-08-12 00:43:167931 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527932 ASSERT_TRUE(response);
[email protected]1b157c02009-04-21 01:55:407933
wezca1070932016-05-26 20:30:527934 EXPECT_TRUE(response->headers);
[email protected]1b157c02009-04-21 01:55:407935 std::string status_line = response->headers->GetStatusLine();
7936 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
7937
[email protected]90499482013-06-01 00:39:507938 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:407939
7940 std::string response_data;
bnc691fda62016-08-12 00:43:167941 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017942 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:407943 EXPECT_EQ("hello world", response_data);
7944
7945 // Empty the current queue. This is necessary because idle sockets are
7946 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557947 base::RunLoop().RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:407948
7949 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507950 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:407951}
7952
[email protected]76a505b2010-08-25 06:23:007953// Make sure that we recycle a SSL socket after reading all of the response
7954// body.
bncd16676a2016-07-20 16:23:017955TEST_F(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:007956 HttpRequestInfo request;
7957 request.method = "GET";
bncce36dca22015-04-21 22:11:237958 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:107959 request.traffic_annotation =
7960 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:007961
7962 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237963 MockWrite(
7964 "GET / HTTP/1.1\r\n"
7965 "Host: www.example.org\r\n"
7966 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:007967 };
7968
7969 MockRead data_reads[] = {
7970 MockRead("HTTP/1.1 200 OK\r\n"),
7971 MockRead("Content-Length: 11\r\n\r\n"),
7972 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:067973 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:007974 };
7975
[email protected]8ddf8322012-02-23 18:08:067976 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077977 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:007978
Ryan Sleevib8d7ea02018-05-07 20:01:017979 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:077980 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:007981
[email protected]49639fa2011-12-20 23:22:417982 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:007983
danakj1fd259a02016-04-16 03:17:097984 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167985 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:007986
tfarina42834112016-09-22 13:38:207987 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:007988
robpercival214763f2016-07-01 23:27:017989 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7990 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:007991
bnc691fda62016-08-12 00:43:167992 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527993 ASSERT_TRUE(response);
7994 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:007995 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7996
[email protected]90499482013-06-01 00:39:507997 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007998
7999 std::string response_data;
bnc691fda62016-08-12 00:43:168000 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:018001 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:008002 EXPECT_EQ("hello world", response_data);
8003
8004 // Empty the current queue. This is necessary because idle sockets are
8005 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:558006 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:008007
8008 // We now check to make sure the socket was added back to the pool.
Matt Menke9d5e2c92019-02-05 01:42:238009 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008010}
8011
8012// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
8013// from the pool and make sure that we recover okay.
bncd16676a2016-07-20 16:23:018014TEST_F(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:008015 HttpRequestInfo request;
8016 request.method = "GET";
bncce36dca22015-04-21 22:11:238017 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:108018 request.traffic_annotation =
8019 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:008020
8021 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238022 MockWrite(
8023 "GET / HTTP/1.1\r\n"
8024 "Host: www.example.org\r\n"
8025 "Connection: keep-alive\r\n\r\n"),
8026 MockWrite(
8027 "GET / HTTP/1.1\r\n"
8028 "Host: www.example.org\r\n"
8029 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:008030 };
8031
8032 MockRead data_reads[] = {
mmenke911ee0222015-12-04 03:58:428033 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
8034 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
[email protected]76a505b2010-08-25 06:23:008035
[email protected]8ddf8322012-02-23 18:08:068036 SSLSocketDataProvider ssl(ASYNC, OK);
8037 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078038 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8039 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:008040
Ryan Sleevib8d7ea02018-05-07 20:01:018041 StaticSocketDataProvider data(data_reads, data_writes);
8042 StaticSocketDataProvider data2(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:078043 session_deps_.socket_factory->AddSocketDataProvider(&data);
8044 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:008045
[email protected]49639fa2011-12-20 23:22:418046 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:008047
danakj1fd259a02016-04-16 03:17:098048 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:588049 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:198050 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:008051
tfarina42834112016-09-22 13:38:208052 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:008053
robpercival214763f2016-07-01 23:27:018054 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8055 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:008056
8057 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528058 ASSERT_TRUE(response);
8059 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:008060 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8061
[email protected]90499482013-06-01 00:39:508062 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008063
8064 std::string response_data;
8065 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018066 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:008067 EXPECT_EQ("hello world", response_data);
8068
8069 // Empty the current queue. This is necessary because idle sockets are
8070 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:558071 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:008072
8073 // We now check to make sure the socket was added back to the pool.
Matt Menke9d5e2c92019-02-05 01:42:238074 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008075
8076 // Now start the second transaction, which should reuse the previous socket.
8077
bnc87dcefc2017-05-25 12:47:588078 trans =
Jeremy Roman0579ed62017-08-29 15:56:198079 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:008080
tfarina42834112016-09-22 13:38:208081 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:008082
robpercival214763f2016-07-01 23:27:018083 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8084 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:008085
8086 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528087 ASSERT_TRUE(response);
8088 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:008089 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8090
[email protected]90499482013-06-01 00:39:508091 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008092
8093 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018094 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:008095 EXPECT_EQ("hello world", response_data);
8096
8097 // Empty the current queue. This is necessary because idle sockets are
8098 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:558099 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:008100
8101 // We now check to make sure the socket was added back to the pool.
Matt Menke9d5e2c92019-02-05 01:42:238102 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008103}
8104
maksim.sisov0adf8592016-07-15 06:25:568105// Grab a socket, use it, and put it back into the pool. Then, make
8106// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:018107TEST_F(HttpNetworkTransactionTest, FlushSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:568108 HttpRequestInfo request;
8109 request.method = "GET";
8110 request.url = GURL("http://www.example.org/");
8111 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:108112 request.traffic_annotation =
8113 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
maksim.sisov0adf8592016-07-15 06:25:568114
8115 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8116
bnc691fda62016-08-12 00:43:168117 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:568118
8119 MockRead data_reads[] = {
8120 // A part of the response body is received with the response headers.
8121 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
8122 // The rest of the response body is received in two parts.
8123 MockRead("lo"), MockRead(" world"),
8124 MockRead("junk"), // Should not be read!!
8125 MockRead(SYNCHRONOUS, OK),
8126 };
8127
Ryan Sleevib8d7ea02018-05-07 20:01:018128 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
maksim.sisov0adf8592016-07-15 06:25:568129 session_deps_.socket_factory->AddSocketDataProvider(&data);
8130
8131 TestCompletionCallback callback;
8132
tfarina42834112016-09-22 13:38:208133 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:568134 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8135
8136 EXPECT_THAT(callback.GetResult(rv), IsOk());
8137
bnc691fda62016-08-12 00:43:168138 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:568139 ASSERT_TRUE(response);
8140 EXPECT_TRUE(response->headers);
8141 std::string status_line = response->headers->GetStatusLine();
8142 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
8143
8144 // Make memory critical notification and ensure the transaction still has been
8145 // operating right.
8146 base::MemoryPressureListener::NotifyMemoryPressure(
8147 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8148 base::RunLoop().RunUntilIdle();
8149
8150 // Socket should not be flushed as long as it is not idle.
8151 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
8152
8153 std::string response_data;
bnc691fda62016-08-12 00:43:168154 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:568155 EXPECT_THAT(rv, IsOk());
8156 EXPECT_EQ("hello world", response_data);
8157
8158 // Empty the current queue. This is necessary because idle sockets are
8159 // added to the connection pool asynchronously with a PostTask.
8160 base::RunLoop().RunUntilIdle();
8161
8162 // We now check to make sure the socket was added back to the pool.
8163 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
8164
8165 // Idle sockets should be flushed now.
8166 base::MemoryPressureListener::NotifyMemoryPressure(
8167 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8168 base::RunLoop().RunUntilIdle();
8169
8170 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
8171}
8172
yucliu48f235d2018-01-11 00:59:558173// Disable idle socket closing on memory pressure.
8174// Grab a socket, use it, and put it back into the pool. Then, make
8175// low memory notification and ensure the socket pool is NOT flushed.
8176TEST_F(HttpNetworkTransactionTest, NoFlushSocketPoolOnLowMemoryNotifications) {
8177 HttpRequestInfo request;
8178 request.method = "GET";
8179 request.url = GURL("http://www.example.org/");
8180 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:108181 request.traffic_annotation =
8182 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
yucliu48f235d2018-01-11 00:59:558183
8184 // Disable idle socket closing on memory pressure.
8185 session_deps_.disable_idle_sockets_close_on_memory_pressure = true;
8186 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8187
8188 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
8189
8190 MockRead data_reads[] = {
8191 // A part of the response body is received with the response headers.
8192 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
8193 // The rest of the response body is received in two parts.
8194 MockRead("lo"), MockRead(" world"),
8195 MockRead("junk"), // Should not be read!!
8196 MockRead(SYNCHRONOUS, OK),
8197 };
8198
Ryan Sleevib8d7ea02018-05-07 20:01:018199 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
yucliu48f235d2018-01-11 00:59:558200 session_deps_.socket_factory->AddSocketDataProvider(&data);
8201
8202 TestCompletionCallback callback;
8203
8204 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
8205 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8206
8207 EXPECT_THAT(callback.GetResult(rv), IsOk());
8208
8209 const HttpResponseInfo* response = trans.GetResponseInfo();
8210 ASSERT_TRUE(response);
8211 EXPECT_TRUE(response->headers);
8212 std::string status_line = response->headers->GetStatusLine();
8213 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
8214
8215 // Make memory critical notification and ensure the transaction still has been
8216 // operating right.
8217 base::MemoryPressureListener::NotifyMemoryPressure(
8218 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8219 base::RunLoop().RunUntilIdle();
8220
8221 // Socket should not be flushed as long as it is not idle.
8222 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
8223
8224 std::string response_data;
8225 rv = ReadTransaction(&trans, &response_data);
8226 EXPECT_THAT(rv, IsOk());
8227 EXPECT_EQ("hello world", response_data);
8228
8229 // Empty the current queue. This is necessary because idle sockets are
8230 // added to the connection pool asynchronously with a PostTask.
8231 base::RunLoop().RunUntilIdle();
8232
8233 // We now check to make sure the socket was added back to the pool.
8234 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
8235
8236 // Idle sockets should NOT be flushed on moderate memory pressure.
8237 base::MemoryPressureListener::NotifyMemoryPressure(
8238 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE);
8239 base::RunLoop().RunUntilIdle();
8240
8241 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
8242
8243 // Idle sockets should NOT be flushed on critical memory pressure.
8244 base::MemoryPressureListener::NotifyMemoryPressure(
8245 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8246 base::RunLoop().RunUntilIdle();
8247
8248 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
8249}
8250
maksim.sisov0adf8592016-07-15 06:25:568251// Grab an SSL socket, use it, and put it back into the pool. Then, make
8252// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:018253TEST_F(HttpNetworkTransactionTest, FlushSSLSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:568254 HttpRequestInfo request;
8255 request.method = "GET";
8256 request.url = GURL("https://www.example.org/");
8257 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:108258 request.traffic_annotation =
8259 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
maksim.sisov0adf8592016-07-15 06:25:568260
8261 MockWrite data_writes[] = {
8262 MockWrite("GET / HTTP/1.1\r\n"
8263 "Host: www.example.org\r\n"
8264 "Connection: keep-alive\r\n\r\n"),
8265 };
8266
8267 MockRead data_reads[] = {
8268 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
8269 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
8270
8271 SSLSocketDataProvider ssl(ASYNC, OK);
8272 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8273
Ryan Sleevib8d7ea02018-05-07 20:01:018274 StaticSocketDataProvider data(data_reads, data_writes);
maksim.sisov0adf8592016-07-15 06:25:568275 session_deps_.socket_factory->AddSocketDataProvider(&data);
8276
8277 TestCompletionCallback callback;
8278
8279 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168280 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:568281
Matt Menke9d5e2c92019-02-05 01:42:238282 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
tfarina42834112016-09-22 13:38:208283 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:568284
8285 EXPECT_THAT(callback.GetResult(rv), IsOk());
8286
bnc691fda62016-08-12 00:43:168287 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:568288 ASSERT_TRUE(response);
8289 ASSERT_TRUE(response->headers);
8290 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8291
8292 // Make memory critical notification and ensure the transaction still has been
8293 // operating right.
8294 base::MemoryPressureListener::NotifyMemoryPressure(
8295 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8296 base::RunLoop().RunUntilIdle();
8297
Matt Menke9d5e2c92019-02-05 01:42:238298 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
maksim.sisov0adf8592016-07-15 06:25:568299
8300 std::string response_data;
bnc691fda62016-08-12 00:43:168301 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:568302 EXPECT_THAT(rv, IsOk());
8303 EXPECT_EQ("hello world", response_data);
8304
8305 // Empty the current queue. This is necessary because idle sockets are
8306 // added to the connection pool asynchronously with a PostTask.
8307 base::RunLoop().RunUntilIdle();
8308
8309 // We now check to make sure the socket was added back to the pool.
Matt Menke9d5e2c92019-02-05 01:42:238310 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
maksim.sisov0adf8592016-07-15 06:25:568311
8312 // Make memory notification once again and ensure idle socket is closed.
8313 base::MemoryPressureListener::NotifyMemoryPressure(
8314 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8315 base::RunLoop().RunUntilIdle();
8316
Matt Menke9d5e2c92019-02-05 01:42:238317 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
maksim.sisov0adf8592016-07-15 06:25:568318}
8319
[email protected]b4404c02009-04-10 16:38:528320// Make sure that we recycle a socket after a zero-length response.
8321// http://crbug.com/9880
bncd16676a2016-07-20 16:23:018322TEST_F(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:428323 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:528324 request.method = "GET";
bncce36dca22015-04-21 22:11:238325 request.url = GURL(
8326 "http://www.example.org/csi?v=3&s=web&action=&"
8327 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
8328 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
8329 "rt=prt.2642,ol.2649,xjs.2951");
Ramin Halavatib5e433e62018-02-07 07:41:108330 request.traffic_annotation =
8331 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]b4404c02009-04-10 16:38:528332
danakj1fd259a02016-04-16 03:17:098333 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:278334
[email protected]b4404c02009-04-10 16:38:528335 MockRead data_reads[] = {
8336 MockRead("HTTP/1.1 204 No Content\r\n"
8337 "Content-Length: 0\r\n"
8338 "Content-Type: text/html\r\n\r\n"),
8339 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:068340 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:528341 };
8342
Ryan Sleevib8d7ea02018-05-07 20:01:018343 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:078344 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:528345
mmenkecc2298e2015-12-07 18:20:188346 // Transaction must be created after the MockReads, so it's destroyed before
8347 // them.
bnc691fda62016-08-12 00:43:168348 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkecc2298e2015-12-07 18:20:188349
[email protected]49639fa2011-12-20 23:22:418350 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:528351
tfarina42834112016-09-22 13:38:208352 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018353 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]b4404c02009-04-10 16:38:528354
8355 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018356 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:528357
bnc691fda62016-08-12 00:43:168358 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528359 ASSERT_TRUE(response);
[email protected]b4404c02009-04-10 16:38:528360
wezca1070932016-05-26 20:30:528361 EXPECT_TRUE(response->headers);
[email protected]b4404c02009-04-10 16:38:528362 std::string status_line = response->headers->GetStatusLine();
8363 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
8364
[email protected]90499482013-06-01 00:39:508365 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:528366
8367 std::string response_data;
bnc691fda62016-08-12 00:43:168368 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:018369 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:528370 EXPECT_EQ("", response_data);
8371
8372 // Empty the current queue. This is necessary because idle sockets are
8373 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:558374 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:528375
8376 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:508377 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:528378}
8379
bncd16676a2016-07-20 16:23:018380TEST_F(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
danakj1fd259a02016-04-16 03:17:098381 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:228382 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:198383 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:228384 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:278385
[email protected]1c773ea12009-04-28 19:58:428386 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:518387 // Transaction 1: a GET request that succeeds. The socket is recycled
8388 // after use.
8389 request[0].method = "GET";
8390 request[0].url = GURL("http://www.google.com/");
8391 request[0].load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:108392 request[0].traffic_annotation =
8393 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]372d34a2008-11-05 21:30:518394 // Transaction 2: a POST request. Reuses the socket kept alive from
8395 // transaction 1. The first attempts fails when writing the POST data.
8396 // This causes the transaction to retry with a new socket. The second
8397 // attempt succeeds.
8398 request[1].method = "POST";
8399 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:278400 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:518401 request[1].load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:108402 request[1].traffic_annotation =
8403 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]372d34a2008-11-05 21:30:518404
danakj1fd259a02016-04-16 03:17:098405 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:518406
8407 // The first socket is used for transaction 1 and the first attempt of
8408 // transaction 2.
8409
8410 // The response of transaction 1.
8411 MockRead data_reads1[] = {
8412 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
8413 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068414 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:518415 };
8416 // The mock write results of transaction 1 and the first attempt of
8417 // transaction 2.
8418 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:068419 MockWrite(SYNCHRONOUS, 64), // GET
8420 MockWrite(SYNCHRONOUS, 93), // POST
8421 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:518422 };
Ryan Sleevib8d7ea02018-05-07 20:01:018423 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]372d34a2008-11-05 21:30:518424
8425 // The second socket is used for the second attempt of transaction 2.
8426
8427 // The response of transaction 2.
8428 MockRead data_reads2[] = {
8429 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
8430 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:068431 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:518432 };
8433 // The mock write results of the second attempt of transaction 2.
8434 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:068435 MockWrite(SYNCHRONOUS, 93), // POST
8436 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:518437 };
Ryan Sleevib8d7ea02018-05-07 20:01:018438 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]372d34a2008-11-05 21:30:518439
[email protected]bb88e1d32013-05-03 23:11:078440 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8441 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:518442
thestig9d3bb0c2015-01-24 00:49:518443 const char* const kExpectedResponseData[] = {
[email protected]372d34a2008-11-05 21:30:518444 "hello world", "welcome"
8445 };
8446
8447 for (int i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:168448 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]372d34a2008-11-05 21:30:518449
[email protected]49639fa2011-12-20 23:22:418450 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:518451
tfarina42834112016-09-22 13:38:208452 int rv = trans.Start(&request[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018453 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]372d34a2008-11-05 21:30:518454
8455 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018456 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:518457
bnc691fda62016-08-12 00:43:168458 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528459 ASSERT_TRUE(response);
[email protected]372d34a2008-11-05 21:30:518460
wezca1070932016-05-26 20:30:528461 EXPECT_TRUE(response->headers);
[email protected]372d34a2008-11-05 21:30:518462 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8463
8464 std::string response_data;
bnc691fda62016-08-12 00:43:168465 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:018466 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:518467 EXPECT_EQ(kExpectedResponseData[i], response_data);
8468 }
8469}
[email protected]f9ee6b52008-11-08 06:46:238470
8471// Test the request-challenge-retry sequence for basic auth when there is
8472// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:168473// it fails the identity from the URL is used to answer the challenge.
bncd16676a2016-07-20 16:23:018474TEST_F(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:428475 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238476 request.method = "GET";
bncce36dca22015-04-21 22:11:238477 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:418478 request.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:108479 request.traffic_annotation =
8480 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]a97cca42009-08-14 01:00:298481
danakj1fd259a02016-04-16 03:17:098482 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168483 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278484
[email protected]a97cca42009-08-14 01:00:298485 // The password contains an escaped character -- for this test to pass it
8486 // will need to be unescaped by HttpNetworkTransaction.
8487 EXPECT_EQ("b%40r", request.url.password());
8488
[email protected]f9ee6b52008-11-08 06:46:238489 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238490 MockWrite(
8491 "GET / HTTP/1.1\r\n"
8492 "Host: www.example.org\r\n"
8493 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238494 };
8495
8496 MockRead data_reads1[] = {
8497 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8498 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8499 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068500 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238501 };
8502
[email protected]2262e3a2012-05-22 16:08:168503 // After the challenge above, the transaction will be restarted using the
8504 // identity from the url (foo, b@r) to answer the challenge.
8505 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238506 MockWrite(
8507 "GET / HTTP/1.1\r\n"
8508 "Host: www.example.org\r\n"
8509 "Connection: keep-alive\r\n"
8510 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:168511 };
8512
8513 MockRead data_reads2[] = {
8514 MockRead("HTTP/1.0 200 OK\r\n"),
8515 MockRead("Content-Length: 100\r\n\r\n"),
8516 MockRead(SYNCHRONOUS, OK),
8517 };
8518
Ryan Sleevib8d7ea02018-05-07 20:01:018519 StaticSocketDataProvider data1(data_reads1, data_writes1);
8520 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:078521 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8522 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:238523
[email protected]49639fa2011-12-20 23:22:418524 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:208525 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018526 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238527 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018528 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168529 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:168530
8531 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:168532 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:018533 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:168534 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018535 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168536 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:228537
bnc691fda62016-08-12 00:43:168538 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528539 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:168540
8541 // There is no challenge info, since the identity in URL worked.
wezca1070932016-05-26 20:30:528542 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:168543
8544 EXPECT_EQ(100, response->headers->GetContentLength());
8545
8546 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:558547 base::RunLoop().RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:168548}
8549
8550// Test the request-challenge-retry sequence for basic auth when there is an
8551// incorrect identity in the URL. The identity from the URL should be used only
8552// once.
bncd16676a2016-07-20 16:23:018553TEST_F(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:168554 HttpRequestInfo request;
8555 request.method = "GET";
8556 // Note: the URL has a username:password in it. The password "baz" is
8557 // wrong (should be "bar").
bncce36dca22015-04-21 22:11:238558 request.url = GURL("http://foo:[email protected]/");
[email protected]2262e3a2012-05-22 16:08:168559
8560 request.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:108561 request.traffic_annotation =
8562 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2262e3a2012-05-22 16:08:168563
danakj1fd259a02016-04-16 03:17:098564 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168565 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2262e3a2012-05-22 16:08:168566
8567 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238568 MockWrite(
8569 "GET / HTTP/1.1\r\n"
8570 "Host: www.example.org\r\n"
8571 "Connection: keep-alive\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:168572 };
8573
8574 MockRead data_reads1[] = {
8575 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8576 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8577 MockRead("Content-Length: 10\r\n\r\n"),
8578 MockRead(SYNCHRONOUS, ERR_FAILED),
8579 };
8580
8581 // After the challenge above, the transaction will be restarted using the
8582 // identity from the url (foo, baz) to answer the challenge.
8583 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238584 MockWrite(
8585 "GET / HTTP/1.1\r\n"
8586 "Host: www.example.org\r\n"
8587 "Connection: keep-alive\r\n"
8588 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:168589 };
8590
8591 MockRead data_reads2[] = {
8592 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8593 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8594 MockRead("Content-Length: 10\r\n\r\n"),
8595 MockRead(SYNCHRONOUS, ERR_FAILED),
8596 };
8597
8598 // After the challenge above, the transaction will be restarted using the
8599 // identity supplied by the user (foo, bar) to answer the challenge.
8600 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:238601 MockWrite(
8602 "GET / HTTP/1.1\r\n"
8603 "Host: www.example.org\r\n"
8604 "Connection: keep-alive\r\n"
8605 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:168606 };
8607
8608 MockRead data_reads3[] = {
8609 MockRead("HTTP/1.0 200 OK\r\n"),
8610 MockRead("Content-Length: 100\r\n\r\n"),
8611 MockRead(SYNCHRONOUS, OK),
8612 };
8613
Ryan Sleevib8d7ea02018-05-07 20:01:018614 StaticSocketDataProvider data1(data_reads1, data_writes1);
8615 StaticSocketDataProvider data2(data_reads2, data_writes2);
8616 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]bb88e1d32013-05-03 23:11:078617 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8618 session_deps_.socket_factory->AddSocketDataProvider(&data2);
8619 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:168620
8621 TestCompletionCallback callback1;
8622
tfarina42834112016-09-22 13:38:208623 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018624 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:168625
8626 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018627 EXPECT_THAT(rv, IsOk());
[email protected]2262e3a2012-05-22 16:08:168628
bnc691fda62016-08-12 00:43:168629 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:168630 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:168631 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:018632 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:168633 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018634 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168635 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:168636
bnc691fda62016-08-12 00:43:168637 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528638 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:168639 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
8640
8641 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:168642 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:018643 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:168644 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:018645 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168646 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:168647
bnc691fda62016-08-12 00:43:168648 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528649 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:168650
8651 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:528652 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:168653
8654 EXPECT_EQ(100, response->headers->GetContentLength());
8655
[email protected]ea9dc9a2009-09-05 00:43:328656 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:558657 base::RunLoop().RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:328658}
8659
[email protected]2217aa22013-10-11 03:03:548660
8661// Test the request-challenge-retry sequence for basic auth when there is a
8662// correct identity in the URL, but its use is being suppressed. The identity
8663// from the URL should never be used.
bncd16676a2016-07-20 16:23:018664TEST_F(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
[email protected]2217aa22013-10-11 03:03:548665 HttpRequestInfo request;
8666 request.method = "GET";
bncce36dca22015-04-21 22:11:238667 request.url = GURL("http://foo:[email protected]/");
[email protected]2217aa22013-10-11 03:03:548668 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
Ramin Halavatib5e433e62018-02-07 07:41:108669 request.traffic_annotation =
8670 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2217aa22013-10-11 03:03:548671
danakj1fd259a02016-04-16 03:17:098672 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168673 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2217aa22013-10-11 03:03:548674
8675 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238676 MockWrite(
8677 "GET / HTTP/1.1\r\n"
8678 "Host: www.example.org\r\n"
8679 "Connection: keep-alive\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:548680 };
8681
8682 MockRead data_reads1[] = {
8683 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8684 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8685 MockRead("Content-Length: 10\r\n\r\n"),
8686 MockRead(SYNCHRONOUS, ERR_FAILED),
8687 };
8688
8689 // After the challenge above, the transaction will be restarted using the
8690 // identity supplied by the user, not the one in the URL, to answer the
8691 // challenge.
8692 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:238693 MockWrite(
8694 "GET / HTTP/1.1\r\n"
8695 "Host: www.example.org\r\n"
8696 "Connection: keep-alive\r\n"
8697 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:548698 };
8699
8700 MockRead data_reads3[] = {
8701 MockRead("HTTP/1.0 200 OK\r\n"),
8702 MockRead("Content-Length: 100\r\n\r\n"),
8703 MockRead(SYNCHRONOUS, OK),
8704 };
8705
Ryan Sleevib8d7ea02018-05-07 20:01:018706 StaticSocketDataProvider data1(data_reads1, data_writes1);
8707 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]2217aa22013-10-11 03:03:548708 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8709 session_deps_.socket_factory->AddSocketDataProvider(&data3);
8710
8711 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:208712 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018713 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:548714 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018715 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168716 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:548717
bnc691fda62016-08-12 00:43:168718 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528719 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:548720 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
8721
8722 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:168723 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:018724 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:548725 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:018726 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168727 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:548728
bnc691fda62016-08-12 00:43:168729 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528730 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:548731
8732 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:528733 EXPECT_FALSE(response->auth_challenge);
[email protected]2217aa22013-10-11 03:03:548734 EXPECT_EQ(100, response->headers->GetContentLength());
8735
8736 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:558737 base::RunLoop().RunUntilIdle();
[email protected]2217aa22013-10-11 03:03:548738}
8739
[email protected]f9ee6b52008-11-08 06:46:238740// Test that previously tried username/passwords for a realm get re-used.
bncd16676a2016-07-20 16:23:018741TEST_F(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
danakj1fd259a02016-04-16 03:17:098742 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:238743
8744 // Transaction 1: authenticate (foo, bar) on MyRealm1
8745 {
[email protected]1c773ea12009-04-28 19:58:428746 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238747 request.method = "GET";
bncce36dca22015-04-21 22:11:238748 request.url = GURL("http://www.example.org/x/y/z");
Ramin Halavatib5e433e62018-02-07 07:41:108749 request.traffic_annotation =
8750 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238751
bnc691fda62016-08-12 00:43:168752 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278753
[email protected]f9ee6b52008-11-08 06:46:238754 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238755 MockWrite(
8756 "GET /x/y/z HTTP/1.1\r\n"
8757 "Host: www.example.org\r\n"
8758 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238759 };
8760
8761 MockRead data_reads1[] = {
8762 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8763 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8764 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068765 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238766 };
8767
8768 // Resend with authorization (username=foo, password=bar)
8769 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238770 MockWrite(
8771 "GET /x/y/z HTTP/1.1\r\n"
8772 "Host: www.example.org\r\n"
8773 "Connection: keep-alive\r\n"
8774 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238775 };
8776
8777 // Sever accepts the authorization.
8778 MockRead data_reads2[] = {
8779 MockRead("HTTP/1.0 200 OK\r\n"),
8780 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068781 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238782 };
8783
Ryan Sleevib8d7ea02018-05-07 20:01:018784 StaticSocketDataProvider data1(data_reads1, data_writes1);
8785 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:078786 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8787 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:238788
[email protected]49639fa2011-12-20 23:22:418789 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238790
tfarina42834112016-09-22 13:38:208791 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018792 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238793
8794 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018795 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238796
bnc691fda62016-08-12 00:43:168797 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528798 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:048799 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:238800
[email protected]49639fa2011-12-20 23:22:418801 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:238802
bnc691fda62016-08-12 00:43:168803 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
8804 callback2.callback());
robpercival214763f2016-07-01 23:27:018805 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238806
8807 rv = callback2.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 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528811 ASSERT_TRUE(response);
8812 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238813 EXPECT_EQ(100, response->headers->GetContentLength());
8814 }
8815
8816 // ------------------------------------------------------------------------
8817
8818 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
8819 {
[email protected]1c773ea12009-04-28 19:58:428820 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238821 request.method = "GET";
8822 // Note that Transaction 1 was at /x/y/z, so this is in the same
8823 // protection space as MyRealm1.
bncce36dca22015-04-21 22:11:238824 request.url = GURL("http://www.example.org/x/y/a/b");
Ramin Halavatib5e433e62018-02-07 07:41:108825 request.traffic_annotation =
8826 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238827
bnc691fda62016-08-12 00:43:168828 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278829
[email protected]f9ee6b52008-11-08 06:46:238830 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238831 MockWrite(
8832 "GET /x/y/a/b HTTP/1.1\r\n"
8833 "Host: www.example.org\r\n"
8834 "Connection: keep-alive\r\n"
8835 // Send preemptive authorization for MyRealm1
8836 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238837 };
8838
8839 // The server didn't like the preemptive authorization, and
8840 // challenges us for a different realm (MyRealm2).
8841 MockRead data_reads1[] = {
8842 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8843 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
8844 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068845 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238846 };
8847
8848 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
8849 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238850 MockWrite(
8851 "GET /x/y/a/b HTTP/1.1\r\n"
8852 "Host: www.example.org\r\n"
8853 "Connection: keep-alive\r\n"
8854 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238855 };
8856
8857 // Sever accepts the authorization.
8858 MockRead data_reads2[] = {
8859 MockRead("HTTP/1.0 200 OK\r\n"),
8860 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068861 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238862 };
8863
Ryan Sleevib8d7ea02018-05-07 20:01:018864 StaticSocketDataProvider data1(data_reads1, data_writes1);
8865 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:078866 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8867 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:238868
[email protected]49639fa2011-12-20 23:22:418869 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238870
tfarina42834112016-09-22 13:38:208871 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018872 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238873
8874 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018875 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238876
bnc691fda62016-08-12 00:43:168877 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528878 ASSERT_TRUE(response);
8879 ASSERT_TRUE(response->auth_challenge);
[email protected]79cb5c12011-09-12 13:12:048880 EXPECT_FALSE(response->auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:438881 EXPECT_EQ("http://www.example.org",
8882 response->auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:048883 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
aberentbba302d2015-12-03 10:20:198884 EXPECT_EQ(kBasicAuthScheme, response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:238885
[email protected]49639fa2011-12-20 23:22:418886 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:238887
bnc691fda62016-08-12 00:43:168888 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
8889 callback2.callback());
robpercival214763f2016-07-01 23:27:018890 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238891
8892 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018893 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238894
bnc691fda62016-08-12 00:43:168895 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528896 ASSERT_TRUE(response);
8897 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238898 EXPECT_EQ(100, response->headers->GetContentLength());
8899 }
8900
8901 // ------------------------------------------------------------------------
8902
8903 // Transaction 3: Resend a request in MyRealm's protection space --
8904 // succeed with preemptive authorization.
8905 {
[email protected]1c773ea12009-04-28 19:58:428906 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238907 request.method = "GET";
bncce36dca22015-04-21 22:11:238908 request.url = GURL("http://www.example.org/x/y/z2");
Ramin Halavatib5e433e62018-02-07 07:41:108909 request.traffic_annotation =
8910 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238911
bnc691fda62016-08-12 00:43:168912 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278913
[email protected]f9ee6b52008-11-08 06:46:238914 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238915 MockWrite(
8916 "GET /x/y/z2 HTTP/1.1\r\n"
8917 "Host: www.example.org\r\n"
8918 "Connection: keep-alive\r\n"
8919 // The authorization for MyRealm1 gets sent preemptively
8920 // (since the url is in the same protection space)
8921 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238922 };
8923
8924 // Sever accepts the preemptive authorization
8925 MockRead data_reads1[] = {
8926 MockRead("HTTP/1.0 200 OK\r\n"),
8927 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068928 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238929 };
8930
Ryan Sleevib8d7ea02018-05-07 20:01:018931 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:078932 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:238933
[email protected]49639fa2011-12-20 23:22:418934 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238935
tfarina42834112016-09-22 13:38:208936 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018937 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238938
8939 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018940 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238941
bnc691fda62016-08-12 00:43:168942 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528943 ASSERT_TRUE(response);
[email protected]f9ee6b52008-11-08 06:46:238944
wezca1070932016-05-26 20:30:528945 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238946 EXPECT_EQ(100, response->headers->GetContentLength());
8947 }
8948
8949 // ------------------------------------------------------------------------
8950
8951 // Transaction 4: request another URL in MyRealm (however the
8952 // url is not known to belong to the protection space, so no pre-auth).
8953 {
[email protected]1c773ea12009-04-28 19:58:428954 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238955 request.method = "GET";
bncce36dca22015-04-21 22:11:238956 request.url = GURL("http://www.example.org/x/1");
Ramin Halavatib5e433e62018-02-07 07:41:108957 request.traffic_annotation =
8958 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238959
bnc691fda62016-08-12 00:43:168960 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278961
[email protected]f9ee6b52008-11-08 06:46:238962 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238963 MockWrite(
8964 "GET /x/1 HTTP/1.1\r\n"
8965 "Host: www.example.org\r\n"
8966 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238967 };
8968
8969 MockRead data_reads1[] = {
8970 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8971 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8972 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068973 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238974 };
8975
8976 // Resend with authorization from MyRealm's cache.
8977 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238978 MockWrite(
8979 "GET /x/1 HTTP/1.1\r\n"
8980 "Host: www.example.org\r\n"
8981 "Connection: keep-alive\r\n"
8982 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238983 };
8984
8985 // Sever accepts the authorization.
8986 MockRead data_reads2[] = {
8987 MockRead("HTTP/1.0 200 OK\r\n"),
8988 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068989 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238990 };
8991
Ryan Sleevib8d7ea02018-05-07 20:01:018992 StaticSocketDataProvider data1(data_reads1, data_writes1);
8993 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:078994 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8995 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:238996
[email protected]49639fa2011-12-20 23:22:418997 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238998
tfarina42834112016-09-22 13:38:208999 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019000 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:239001
9002 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019003 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:239004
bnc691fda62016-08-12 00:43:169005 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:419006 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:169007 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:019008 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:229009 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:019010 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:169011 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:229012
bnc691fda62016-08-12 00:43:169013 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529014 ASSERT_TRUE(response);
9015 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:239016 EXPECT_EQ(100, response->headers->GetContentLength());
9017 }
9018
9019 // ------------------------------------------------------------------------
9020
9021 // Transaction 5: request a URL in MyRealm, but the server rejects the
9022 // cached identity. Should invalidate and re-prompt.
9023 {
[email protected]1c773ea12009-04-28 19:58:429024 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:239025 request.method = "GET";
bncce36dca22015-04-21 22:11:239026 request.url = GURL("http://www.example.org/p/q/t");
Ramin Halavatib5e433e62018-02-07 07:41:109027 request.traffic_annotation =
9028 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:239029
bnc691fda62016-08-12 00:43:169030 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279031
[email protected]f9ee6b52008-11-08 06:46:239032 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239033 MockWrite(
9034 "GET /p/q/t HTTP/1.1\r\n"
9035 "Host: www.example.org\r\n"
9036 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:239037 };
9038
9039 MockRead data_reads1[] = {
9040 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
9041 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9042 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069043 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:239044 };
9045
9046 // Resend with authorization from cache for MyRealm.
9047 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:239048 MockWrite(
9049 "GET /p/q/t HTTP/1.1\r\n"
9050 "Host: www.example.org\r\n"
9051 "Connection: keep-alive\r\n"
9052 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:239053 };
9054
9055 // Sever rejects the authorization.
9056 MockRead data_reads2[] = {
9057 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
9058 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9059 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069060 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:239061 };
9062
9063 // At this point we should prompt for new credentials for MyRealm.
9064 // Restart with username=foo3, password=foo4.
9065 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:239066 MockWrite(
9067 "GET /p/q/t HTTP/1.1\r\n"
9068 "Host: www.example.org\r\n"
9069 "Connection: keep-alive\r\n"
9070 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:239071 };
9072
9073 // Sever accepts the authorization.
9074 MockRead data_reads3[] = {
9075 MockRead("HTTP/1.0 200 OK\r\n"),
9076 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069077 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:239078 };
9079
Ryan Sleevib8d7ea02018-05-07 20:01:019080 StaticSocketDataProvider data1(data_reads1, data_writes1);
9081 StaticSocketDataProvider data2(data_reads2, data_writes2);
9082 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]bb88e1d32013-05-03 23:11:079083 session_deps_.socket_factory->AddSocketDataProvider(&data1);
9084 session_deps_.socket_factory->AddSocketDataProvider(&data2);
9085 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:239086
[email protected]49639fa2011-12-20 23:22:419087 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:239088
tfarina42834112016-09-22 13:38:209089 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019090 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:239091
9092 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019093 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:239094
bnc691fda62016-08-12 00:43:169095 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:419096 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:169097 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:019098 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:229099 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:019100 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:169101 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:229102
bnc691fda62016-08-12 00:43:169103 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529104 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:049105 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:239106
[email protected]49639fa2011-12-20 23:22:419107 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:239108
bnc691fda62016-08-12 00:43:169109 rv = trans.RestartWithAuth(AuthCredentials(kFoo3, kBar3),
9110 callback3.callback());
robpercival214763f2016-07-01 23:27:019111 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:239112
[email protected]0757e7702009-03-27 04:00:229113 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:019114 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:239115
bnc691fda62016-08-12 00:43:169116 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529117 ASSERT_TRUE(response);
9118 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:239119 EXPECT_EQ(100, response->headers->GetContentLength());
9120 }
9121}
[email protected]89ceba9a2009-03-21 03:46:069122
[email protected]3c32c5f2010-05-18 15:18:129123// Tests that nonce count increments when multiple auth attempts
9124// are started with the same nonce.
bncd16676a2016-07-20 16:23:019125TEST_F(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:449126 HttpAuthHandlerDigest::Factory* digest_factory =
9127 new HttpAuthHandlerDigest::Factory();
9128 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
9129 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
9130 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:079131 session_deps_.http_auth_handler_factory.reset(digest_factory);
danakj1fd259a02016-04-16 03:17:099132 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:129133
9134 // Transaction 1: authenticate (foo, bar) on MyRealm1
9135 {
[email protected]3c32c5f2010-05-18 15:18:129136 HttpRequestInfo request;
9137 request.method = "GET";
bncce36dca22015-04-21 22:11:239138 request.url = GURL("http://www.example.org/x/y/z");
Ramin Halavatib5e433e62018-02-07 07:41:109139 request.traffic_annotation =
9140 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3c32c5f2010-05-18 15:18:129141
bnc691fda62016-08-12 00:43:169142 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279143
[email protected]3c32c5f2010-05-18 15:18:129144 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239145 MockWrite(
9146 "GET /x/y/z HTTP/1.1\r\n"
9147 "Host: www.example.org\r\n"
9148 "Connection: keep-alive\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:129149 };
9150
9151 MockRead data_reads1[] = {
9152 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
9153 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
9154 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069155 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:129156 };
9157
9158 // Resend with authorization (username=foo, password=bar)
9159 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:239160 MockWrite(
9161 "GET /x/y/z HTTP/1.1\r\n"
9162 "Host: www.example.org\r\n"
9163 "Connection: keep-alive\r\n"
9164 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
9165 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
9166 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
9167 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:129168 };
9169
9170 // Sever accepts the authorization.
9171 MockRead data_reads2[] = {
zmo9528c9f42015-08-04 22:12:089172 MockRead("HTTP/1.0 200 OK\r\n"),
9173 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:129174 };
9175
Ryan Sleevib8d7ea02018-05-07 20:01:019176 StaticSocketDataProvider data1(data_reads1, data_writes1);
9177 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:079178 session_deps_.socket_factory->AddSocketDataProvider(&data1);
9179 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:129180
[email protected]49639fa2011-12-20 23:22:419181 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:129182
tfarina42834112016-09-22 13:38:209183 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019184 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:129185
9186 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019187 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:129188
bnc691fda62016-08-12 00:43:169189 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529190 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:049191 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:129192
[email protected]49639fa2011-12-20 23:22:419193 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:129194
bnc691fda62016-08-12 00:43:169195 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
9196 callback2.callback());
robpercival214763f2016-07-01 23:27:019197 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:129198
9199 rv = callback2.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 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529203 ASSERT_TRUE(response);
9204 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:129205 }
9206
9207 // ------------------------------------------------------------------------
9208
9209 // Transaction 2: Request another resource in digestive's protection space.
9210 // This will preemptively add an Authorization header which should have an
9211 // "nc" value of 2 (as compared to 1 in the first use.
9212 {
[email protected]3c32c5f2010-05-18 15:18:129213 HttpRequestInfo request;
9214 request.method = "GET";
9215 // Note that Transaction 1 was at /x/y/z, so this is in the same
9216 // protection space as digest.
bncce36dca22015-04-21 22:11:239217 request.url = GURL("http://www.example.org/x/y/a/b");
Ramin Halavatib5e433e62018-02-07 07:41:109218 request.traffic_annotation =
9219 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3c32c5f2010-05-18 15:18:129220
bnc691fda62016-08-12 00:43:169221 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279222
[email protected]3c32c5f2010-05-18 15:18:129223 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239224 MockWrite(
9225 "GET /x/y/a/b HTTP/1.1\r\n"
9226 "Host: www.example.org\r\n"
9227 "Connection: keep-alive\r\n"
9228 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
9229 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
9230 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
9231 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:129232 };
9233
9234 // Sever accepts the authorization.
9235 MockRead data_reads1[] = {
9236 MockRead("HTTP/1.0 200 OK\r\n"),
9237 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069238 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:129239 };
9240
Ryan Sleevib8d7ea02018-05-07 20:01:019241 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:079242 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:129243
[email protected]49639fa2011-12-20 23:22:419244 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:129245
tfarina42834112016-09-22 13:38:209246 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019247 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:129248
9249 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019250 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:129251
bnc691fda62016-08-12 00:43:169252 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529253 ASSERT_TRUE(response);
9254 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:129255 }
9256}
9257
[email protected]89ceba9a2009-03-21 03:46:069258// Test the ResetStateForRestart() private method.
bncd16676a2016-07-20 16:23:019259TEST_F(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:069260 // Create a transaction (the dependencies aren't important).
danakj1fd259a02016-04-16 03:17:099261 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169262 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]89ceba9a2009-03-21 03:46:069263
9264 // Setup some state (which we expect ResetStateForRestart() will clear).
Victor Costan9c7302b2018-08-27 16:39:449265 trans.read_buf_ = base::MakeRefCounted<IOBuffer>(15);
bnc691fda62016-08-12 00:43:169266 trans.read_buf_len_ = 15;
9267 trans.request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:069268
9269 // Setup state in response_
bnc691fda62016-08-12 00:43:169270 HttpResponseInfo* response = &trans.response_;
[email protected]0877e3d2009-10-17 22:29:579271 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:089272 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:579273 response->response_time = base::Time::Now();
9274 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:069275
9276 { // Setup state for response_.vary_data
9277 HttpRequestInfo request;
9278 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
9279 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:279280 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:439281 request.extra_headers.SetHeader("Foo", "1");
9282 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:509283 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:069284 }
9285
9286 // Cause the above state to be reset.
bnc691fda62016-08-12 00:43:169287 trans.ResetStateForRestart();
[email protected]89ceba9a2009-03-21 03:46:069288
9289 // Verify that the state that needed to be reset, has been reset.
bnc691fda62016-08-12 00:43:169290 EXPECT_FALSE(trans.read_buf_);
9291 EXPECT_EQ(0, trans.read_buf_len_);
9292 EXPECT_TRUE(trans.request_headers_.IsEmpty());
wezca1070932016-05-26 20:30:529293 EXPECT_FALSE(response->auth_challenge);
9294 EXPECT_FALSE(response->headers);
[email protected]34f40942010-10-04 00:34:049295 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:089296 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:579297 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:069298}
9299
[email protected]bacff652009-03-31 17:50:339300// Test HTTPS connections to a site with a bad certificate
bncd16676a2016-07-20 16:23:019301TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:339302 HttpRequestInfo request;
9303 request.method = "GET";
bncce36dca22015-04-21 22:11:239304 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109305 request.traffic_annotation =
9306 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]bacff652009-03-31 17:50:339307
danakj1fd259a02016-04-16 03:17:099308 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169309 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279310
[email protected]bacff652009-03-31 17:50:339311 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239312 MockWrite(
9313 "GET / HTTP/1.1\r\n"
9314 "Host: www.example.org\r\n"
9315 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:339316 };
9317
9318 MockRead data_reads[] = {
9319 MockRead("HTTP/1.0 200 OK\r\n"),
9320 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9321 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069322 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:339323 };
9324
[email protected]5ecc992a42009-11-11 01:41:599325 StaticSocketDataProvider ssl_bad_certificate;
Ryan Sleevib8d7ea02018-05-07 20:01:019326 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069327 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
9328 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:339329
[email protected]bb88e1d32013-05-03 23:11:079330 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
9331 session_deps_.socket_factory->AddSocketDataProvider(&data);
9332 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
9333 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:339334
[email protected]49639fa2011-12-20 23:22:419335 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:339336
tfarina42834112016-09-22 13:38:209337 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019338 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:339339
9340 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019341 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:339342
bnc691fda62016-08-12 00:43:169343 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:019344 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:339345
9346 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019347 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:339348
bnc691fda62016-08-12 00:43:169349 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:339350
wezca1070932016-05-26 20:30:529351 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:339352 EXPECT_EQ(100, response->headers->GetContentLength());
9353}
9354
9355// Test HTTPS connections to a site with a bad certificate, going through a
9356// proxy
bncd16676a2016-07-20 16:23:019357TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
Ramin Halavatica8d5252018-03-12 05:33:499358 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9359 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]bacff652009-03-31 17:50:339360
9361 HttpRequestInfo request;
9362 request.method = "GET";
bncce36dca22015-04-21 22:11:239363 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109364 request.traffic_annotation =
9365 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]bacff652009-03-31 17:50:339366
9367 MockWrite proxy_writes[] = {
rsleevidb16bb02015-11-12 23:47:179368 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9369 "Host: www.example.org:443\r\n"
9370 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:339371 };
9372
9373 MockRead proxy_reads[] = {
9374 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069375 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:339376 };
9377
9378 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179379 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9380 "Host: www.example.org:443\r\n"
9381 "Proxy-Connection: keep-alive\r\n\r\n"),
9382 MockWrite("GET / HTTP/1.1\r\n"
9383 "Host: www.example.org\r\n"
9384 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:339385 };
9386
9387 MockRead data_reads[] = {
9388 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
9389 MockRead("HTTP/1.0 200 OK\r\n"),
9390 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9391 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069392 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:339393 };
9394
Ryan Sleevib8d7ea02018-05-07 20:01:019395 StaticSocketDataProvider ssl_bad_certificate(proxy_reads, proxy_writes);
9396 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069397 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
9398 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:339399
[email protected]bb88e1d32013-05-03 23:11:079400 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
9401 session_deps_.socket_factory->AddSocketDataProvider(&data);
9402 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
9403 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:339404
[email protected]49639fa2011-12-20 23:22:419405 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:339406
9407 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:079408 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:339409
danakj1fd259a02016-04-16 03:17:099410 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169411 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bacff652009-03-31 17:50:339412
tfarina42834112016-09-22 13:38:209413 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019414 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:339415
9416 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019417 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:339418
bnc691fda62016-08-12 00:43:169419 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:019420 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:339421
9422 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019423 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:339424
bnc691fda62016-08-12 00:43:169425 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:339426
wezca1070932016-05-26 20:30:529427 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:339428 EXPECT_EQ(100, response->headers->GetContentLength());
9429 }
9430}
9431
[email protected]2df19bb2010-08-25 20:13:469432
9433// Test HTTPS connections to a site, going through an HTTPS proxy
bncd16676a2016-07-20 16:23:019434TEST_F(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:599435 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499436 ProxyResolutionService::CreateFixedFromPacResult(
9437 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519438 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079439 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:469440
9441 HttpRequestInfo request;
9442 request.method = "GET";
bncce36dca22015-04-21 22:11:239443 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109444 request.traffic_annotation =
9445 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:469446
9447 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179448 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9449 "Host: www.example.org:443\r\n"
9450 "Proxy-Connection: keep-alive\r\n\r\n"),
9451 MockWrite("GET / HTTP/1.1\r\n"
9452 "Host: www.example.org\r\n"
9453 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:469454 };
9455
9456 MockRead data_reads[] = {
9457 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
9458 MockRead("HTTP/1.1 200 OK\r\n"),
9459 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9460 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069461 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:469462 };
9463
Ryan Sleevib8d7ea02018-05-07 20:01:019464 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069465 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
9466 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:469467
[email protected]bb88e1d32013-05-03 23:11:079468 session_deps_.socket_factory->AddSocketDataProvider(&data);
9469 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
9470 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:469471
[email protected]49639fa2011-12-20 23:22:419472 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:469473
danakj1fd259a02016-04-16 03:17:099474 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169475 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:469476
tfarina42834112016-09-22 13:38:209477 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019478 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:469479
9480 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019481 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:169482 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:469483
wezca1070932016-05-26 20:30:529484 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:469485
tbansal2ecbbc72016-10-06 17:15:479486 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:469487 EXPECT_TRUE(response->headers->IsKeepAlive());
9488 EXPECT_EQ(200, response->headers->response_code());
9489 EXPECT_EQ(100, response->headers->GetContentLength());
9490 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:209491
9492 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169493 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209494 TestLoadTimingNotReusedWithPac(load_timing_info,
9495 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:469496}
9497
[email protected]511f6f52010-12-17 03:58:299498// Test an HTTPS Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:019499TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:599500 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499501 ProxyResolutionService::CreateFixedFromPacResult(
9502 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519503 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079504 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:299505
Matt Menkeecfecfc72019-02-05 19:15:289506 base::TimeTicks start_time = base::TimeTicks::Now();
9507 const base::TimeDelta kTimeIncrement = base::TimeDelta::FromSeconds(4);
9508 session_deps_.host_resolver->set_ondemand_mode(true);
9509
[email protected]511f6f52010-12-17 03:58:299510 HttpRequestInfo request;
9511 request.method = "GET";
bncce36dca22015-04-21 22:11:239512 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109513 request.traffic_annotation =
9514 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299515
9516 MockWrite data_writes[] = {
Matt Menkeecfecfc72019-02-05 19:15:289517 MockWrite(ASYNC, 0,
9518 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:179519 "Host: www.example.org:443\r\n"
9520 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:299521 };
9522
9523 MockRead data_reads[] = {
Matt Menkeecfecfc72019-02-05 19:15:289524 // Pause on first read.
9525 MockRead(ASYNC, ERR_IO_PENDING, 1),
9526 MockRead(ASYNC, 2, "HTTP/1.1 302 Redirect\r\n"),
9527 MockRead(ASYNC, 3, "Location: http://login.example.com/\r\n"),
9528 MockRead(ASYNC, 4, "Content-Length: 0\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:299529 };
9530
Matt Menkeecfecfc72019-02-05 19:15:289531 SequencedSocketData data(MockConnect(ASYNC, OK), data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069532 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:299533
[email protected]bb88e1d32013-05-03 23:11:079534 session_deps_.socket_factory->AddSocketDataProvider(&data);
9535 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:299536
[email protected]49639fa2011-12-20 23:22:419537 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:299538
danakj1fd259a02016-04-16 03:17:099539 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169540 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:299541
tfarina42834112016-09-22 13:38:209542 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019543 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Matt Menkeecfecfc72019-02-05 19:15:289544 EXPECT_TRUE(session_deps_.host_resolver->has_pending_requests());
9545
9546 // Host resolution takes |kTimeIncrement|.
9547 FastForwardBy(kTimeIncrement);
9548 // Resolving the current request with |ResolveNow| will cause the pending
9549 // request to instantly complete, and the async connect will start as well.
9550 session_deps_.host_resolver->ResolveOnlyRequestNow();
9551
9552 // Connecting takes |kTimeIncrement|.
9553 FastForwardBy(kTimeIncrement);
9554 data.RunUntilPaused();
9555
9556 // The server takes |kTimeIncrement| to respond.
9557 FastForwardBy(kTimeIncrement);
9558 data.Resume();
[email protected]511f6f52010-12-17 03:58:299559
9560 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019561 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:169562 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:299563
wezca1070932016-05-26 20:30:529564 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:299565
9566 EXPECT_EQ(302, response->headers->response_code());
9567 std::string url;
9568 EXPECT_TRUE(response->headers->IsRedirect(&url));
9569 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:209570
[email protected]029c83b62013-01-24 05:28:209571 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169572 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209573
9574 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:199575 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:209576
Matt Menkeecfecfc72019-02-05 19:15:289577 // In the case of redirects from proxies, just as with all responses from
9578 // proxies, DNS and SSL times reflect timing to look up the destination's
9579 // name, and negotiate an SSL connection to it (Neither of which are done in
9580 // this case), which the DNS and SSL times for the proxy are all included in
9581 // connect_start / connect_end. See
9582 // HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
9583
9584 EXPECT_TRUE(load_timing_info.connect_timing.dns_start.is_null());
9585 EXPECT_TRUE(load_timing_info.connect_timing.dns_end.is_null());
9586 EXPECT_TRUE(load_timing_info.connect_timing.ssl_start.is_null());
9587 EXPECT_TRUE(load_timing_info.connect_timing.ssl_end.is_null());
9588
9589 EXPECT_EQ(start_time, load_timing_info.proxy_resolve_start);
9590 EXPECT_EQ(start_time, load_timing_info.proxy_resolve_end);
9591 EXPECT_EQ(start_time, load_timing_info.connect_timing.connect_start);
9592 EXPECT_EQ(start_time + 3 * kTimeIncrement,
9593 load_timing_info.connect_timing.connect_end);
[email protected]029c83b62013-01-24 05:28:209594
9595 EXPECT_TRUE(load_timing_info.send_start.is_null());
9596 EXPECT_TRUE(load_timing_info.send_end.is_null());
9597 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:299598}
9599
9600// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:019601TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
Ramin Halavatica8d5252018-03-12 05:33:499602 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9603 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Matt Menkeecfecfc72019-02-05 19:15:289604 TestNetLog net_log;
9605 session_deps_.net_log = &net_log;
9606
9607 base::TimeTicks start_time = base::TimeTicks::Now();
9608 const base::TimeDelta kTimeIncrement = base::TimeDelta::FromSeconds(4);
9609 session_deps_.host_resolver->set_ondemand_mode(true);
[email protected]511f6f52010-12-17 03:58:299610
9611 HttpRequestInfo request;
9612 request.method = "GET";
bncce36dca22015-04-21 22:11:239613 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109614 request.traffic_annotation =
9615 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299616
Ryan Hamilton0239aac2018-05-19 00:03:139617 spdy::SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:239618 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:139619 spdy::SpdySerializedFrame goaway(
9620 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:299621 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:419622 CreateMockWrite(conn, 0, SYNCHRONOUS),
Matt Menkeecfecfc72019-02-05 19:15:289623 CreateMockWrite(goaway, 3, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:299624 };
9625
9626 static const char* const kExtraHeaders[] = {
9627 "location",
9628 "http://login.example.com/",
9629 };
Ryan Hamilton0239aac2018-05-19 00:03:139630 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
Avi Drissman4365a4782018-12-28 19:26:249631 "302", kExtraHeaders, base::size(kExtraHeaders) / 2, 1));
[email protected]511f6f52010-12-17 03:58:299632 MockRead data_reads[] = {
Matt Menkeecfecfc72019-02-05 19:15:289633 // Pause on first read.
9634 MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(resp, 2),
9635 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:299636 };
9637
Matt Menkeecfecfc72019-02-05 19:15:289638 SequencedSocketData data(MockConnect(ASYNC, OK), data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069639 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:369640 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:299641
[email protected]bb88e1d32013-05-03 23:11:079642 session_deps_.socket_factory->AddSocketDataProvider(&data);
9643 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:299644
[email protected]49639fa2011-12-20 23:22:419645 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:299646
danakj1fd259a02016-04-16 03:17:099647 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169648 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:299649
tfarina42834112016-09-22 13:38:209650 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019651 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Matt Menkeecfecfc72019-02-05 19:15:289652 EXPECT_TRUE(session_deps_.host_resolver->has_pending_requests());
[email protected]511f6f52010-12-17 03:58:299653
Matt Menkeecfecfc72019-02-05 19:15:289654 // Host resolution takes |kTimeIncrement|.
9655 FastForwardBy(kTimeIncrement);
9656 // Resolving the current request with |ResolveNow| will cause the pending
9657 // request to instantly complete, and the async connect will start as well.
9658 session_deps_.host_resolver->ResolveOnlyRequestNow();
9659
9660 // Connecting takes |kTimeIncrement|.
9661 FastForwardBy(kTimeIncrement);
9662 data.RunUntilPaused();
9663
9664 FastForwardBy(kTimeIncrement);
9665 data.Resume();
[email protected]511f6f52010-12-17 03:58:299666 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019667 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:169668 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:299669
wezca1070932016-05-26 20:30:529670 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:299671
9672 EXPECT_EQ(302, response->headers->response_code());
9673 std::string url;
9674 EXPECT_TRUE(response->headers->IsRedirect(&url));
9675 EXPECT_EQ("http://login.example.com/", url);
Matt Menkeecfecfc72019-02-05 19:15:289676
9677 LoadTimingInfo load_timing_info;
9678 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
9679
9680 EXPECT_FALSE(load_timing_info.socket_reused);
9681 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
9682
9683 // No proxy resolution times, since there's no PAC script.
9684 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
9685 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
9686
9687 // In the case of redirects from proxies, just as with all responses from
9688 // proxies, DNS and SSL times reflect timing to look up the destination's
9689 // name, and negotiate an SSL connection to it (Neither of which are done in
9690 // this case), which the DNS and SSL times for the proxy are all included in
9691 // connect_start / connect_end. See
9692 // HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
9693
9694 EXPECT_TRUE(load_timing_info.connect_timing.dns_start.is_null());
9695 EXPECT_TRUE(load_timing_info.connect_timing.dns_end.is_null());
9696 EXPECT_TRUE(load_timing_info.connect_timing.ssl_start.is_null());
9697 EXPECT_TRUE(load_timing_info.connect_timing.ssl_end.is_null());
9698
9699 EXPECT_EQ(start_time, load_timing_info.connect_timing.connect_start);
9700 EXPECT_EQ(start_time + 3 * kTimeIncrement,
9701 load_timing_info.connect_timing.connect_end);
9702
9703 EXPECT_TRUE(load_timing_info.send_start.is_null());
9704 EXPECT_TRUE(load_timing_info.send_end.is_null());
9705 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:299706}
9707
[email protected]4eddbc732012-08-09 05:40:179708// Test that an HTTPS proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:019709TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaHttpsProxy) {
Ramin Halavatica8d5252018-03-12 05:33:499710 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9711 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299712
9713 HttpRequestInfo request;
9714 request.method = "GET";
bncce36dca22015-04-21 22:11:239715 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109716 request.traffic_annotation =
9717 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299718
9719 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179720 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9721 "Host: www.example.org:443\r\n"
9722 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:299723 };
9724
9725 MockRead data_reads[] = {
9726 MockRead("HTTP/1.1 404 Not Found\r\n"),
9727 MockRead("Content-Length: 23\r\n\r\n"),
9728 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:069729 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:299730 };
9731
Ryan Sleevib8d7ea02018-05-07 20:01:019732 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069733 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:299734
[email protected]bb88e1d32013-05-03 23:11:079735 session_deps_.socket_factory->AddSocketDataProvider(&data);
9736 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:299737
[email protected]49639fa2011-12-20 23:22:419738 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:299739
danakj1fd259a02016-04-16 03:17:099740 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169741 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:299742
tfarina42834112016-09-22 13:38:209743 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019744 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:299745
9746 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019747 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:299748
ttuttle960fcbf2016-04-19 13:26:329749 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:299750}
9751
[email protected]4eddbc732012-08-09 05:40:179752// Test that a SPDY proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:019753TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaSpdyProxy) {
Ramin Halavatica8d5252018-03-12 05:33:499754 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9755 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299756
9757 HttpRequestInfo request;
9758 request.method = "GET";
bncce36dca22015-04-21 22:11:239759 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109760 request.traffic_annotation =
9761 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299762
Ryan Hamilton0239aac2018-05-19 00:03:139763 spdy::SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:239764 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:139765 spdy::SpdySerializedFrame rst(
9766 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:299767 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:419768 CreateMockWrite(conn, 0), CreateMockWrite(rst, 3),
[email protected]511f6f52010-12-17 03:58:299769 };
9770
9771 static const char* const kExtraHeaders[] = {
9772 "location",
9773 "http://login.example.com/",
9774 };
Ryan Hamilton0239aac2018-05-19 00:03:139775 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
Avi Drissman4365a4782018-12-28 19:26:249776 "404", kExtraHeaders, base::size(kExtraHeaders) / 2, 1));
Ryan Hamilton0239aac2018-05-19 00:03:139777 spdy::SpdySerializedFrame body(
Bence Békyd74f4382018-02-20 18:26:199778 spdy_util_.ConstructSpdyDataFrame(1, "The host does not exist", true));
[email protected]511f6f52010-12-17 03:58:299779 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:419780 CreateMockRead(resp, 1), CreateMockRead(body, 2),
rch8e6c6c42015-05-01 14:05:139781 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:299782 };
9783
Ryan Sleevib8d7ea02018-05-07 20:01:019784 SequencedSocketData data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069785 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:369786 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:299787
[email protected]bb88e1d32013-05-03 23:11:079788 session_deps_.socket_factory->AddSocketDataProvider(&data);
9789 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:299790
[email protected]49639fa2011-12-20 23:22:419791 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:299792
danakj1fd259a02016-04-16 03:17:099793 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169794 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:299795
tfarina42834112016-09-22 13:38:209796 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019797 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:299798
9799 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019800 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:299801
ttuttle960fcbf2016-04-19 13:26:329802 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:299803}
9804
[email protected]0c5fb722012-02-28 11:50:359805// Test the request-challenge-retry sequence for basic auth, through
9806// a SPDY proxy over a single SPDY session.
bncd16676a2016-07-20 16:23:019807TEST_F(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:359808 HttpRequestInfo request;
9809 request.method = "GET";
bncce36dca22015-04-21 22:11:239810 request.url = GURL("https://www.example.org/");
[email protected]0c5fb722012-02-28 11:50:359811 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:299812 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:109813 request.traffic_annotation =
9814 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0c5fb722012-02-28 11:50:359815
9816 // Configure against https proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:599817 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499818 ProxyResolutionService::CreateFixedFromPacResult(
9819 "HTTPS myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519820 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:079821 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:099822 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:359823
9824 // Since we have proxy, should try to establish tunnel.
Ryan Hamilton0239aac2018-05-19 00:03:139825 spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:239826 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:139827 spdy::SpdySerializedFrame rst(
9828 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
rdsmithebb50aa2015-11-12 03:44:389829 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]0c5fb722012-02-28 11:50:359830
bnc691fda62016-08-12 00:43:169831 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0c5fb722012-02-28 11:50:359832 // be issuing -- the final header line contains the credentials.
9833 const char* const kAuthCredentials[] = {
9834 "proxy-authorization", "Basic Zm9vOmJhcg==",
9835 };
Ryan Hamilton0239aac2018-05-19 00:03:139836 spdy::SpdySerializedFrame connect2(spdy_util_.ConstructSpdyConnect(
Avi Drissman4365a4782018-12-28 19:26:249837 kAuthCredentials, base::size(kAuthCredentials) / 2, 3, LOWEST,
bncce36dca22015-04-21 22:11:239838 HostPortPair("www.example.org", 443)));
9839 // fetch https://www.example.org/ via HTTP
9840 const char get[] =
9841 "GET / HTTP/1.1\r\n"
9842 "Host: www.example.org\r\n"
9843 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:139844 spdy::SpdySerializedFrame wrapped_get(
Bence Békyd74f4382018-02-20 18:26:199845 spdy_util_.ConstructSpdyDataFrame(3, get, false));
[email protected]0c5fb722012-02-28 11:50:359846
9847 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:419848 CreateMockWrite(req, 0, ASYNC), CreateMockWrite(rst, 2, ASYNC),
9849 CreateMockWrite(connect2, 3), CreateMockWrite(wrapped_get, 5),
[email protected]0c5fb722012-02-28 11:50:359850 };
9851
9852 // The proxy responds to the connect with a 407, using a persistent
9853 // connection.
thestig9d3bb0c2015-01-24 00:49:519854 const char kAuthStatus[] = "407";
[email protected]0c5fb722012-02-28 11:50:359855 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:359856 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
9857 };
Ryan Hamilton0239aac2018-05-19 00:03:139858 spdy::SpdySerializedFrame conn_auth_resp(spdy_util_.ConstructSpdyReplyError(
Avi Drissman4365a4782018-12-28 19:26:249859 kAuthStatus, kAuthChallenge, base::size(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:359860
Ryan Hamilton0239aac2018-05-19 00:03:139861 spdy::SpdySerializedFrame conn_resp(
9862 spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:359863 const char resp[] = "HTTP/1.1 200 OK\r\n"
9864 "Content-Length: 5\r\n\r\n";
9865
Ryan Hamilton0239aac2018-05-19 00:03:139866 spdy::SpdySerializedFrame wrapped_get_resp(
Bence Békyd74f4382018-02-20 18:26:199867 spdy_util_.ConstructSpdyDataFrame(3, resp, false));
Ryan Hamilton0239aac2018-05-19 00:03:139868 spdy::SpdySerializedFrame wrapped_body(
Bence Békyd74f4382018-02-20 18:26:199869 spdy_util_.ConstructSpdyDataFrame(3, "hello", false));
[email protected]0c5fb722012-02-28 11:50:359870 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:419871 CreateMockRead(conn_auth_resp, 1, ASYNC),
9872 CreateMockRead(conn_resp, 4, ASYNC),
9873 CreateMockRead(wrapped_get_resp, 6, ASYNC),
9874 CreateMockRead(wrapped_body, 7, ASYNC),
rch8e6c6c42015-05-01 14:05:139875 MockRead(ASYNC, OK, 8), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:359876 };
9877
Ryan Sleevib8d7ea02018-05-07 20:01:019878 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:079879 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:359880 // Negotiate SPDY to the proxy
9881 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:369882 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:079883 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:359884 // Vanilla SSL to the server
9885 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:079886 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:359887
9888 TestCompletionCallback callback1;
9889
bnc87dcefc2017-05-25 12:47:589890 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:199891 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0c5fb722012-02-28 11:50:359892
9893 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:019894 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:359895
9896 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019897 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:469898 TestNetLogEntry::List entries;
[email protected]0c5fb722012-02-28 11:50:359899 log.GetEntries(&entries);
9900 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:009901 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
9902 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:359903 ExpectLogContainsSomewhere(
9904 entries, pos,
mikecirone8b85c432016-09-08 19:11:009905 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
9906 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:359907
9908 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529909 ASSERT_TRUE(response);
9910 ASSERT_TRUE(response->headers);
[email protected]0c5fb722012-02-28 11:50:359911 EXPECT_EQ(407, response->headers->response_code());
9912 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
wezca1070932016-05-26 20:30:529913 EXPECT_TRUE(response->auth_challenge);
asanka098c0092016-06-16 20:18:439914 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]0c5fb722012-02-28 11:50:359915
9916 TestCompletionCallback callback2;
9917
9918 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
9919 callback2.callback());
robpercival214763f2016-07-01 23:27:019920 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:359921
9922 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:019923 EXPECT_THAT(rv, IsOk());
[email protected]0c5fb722012-02-28 11:50:359924
9925 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529926 ASSERT_TRUE(response);
[email protected]0c5fb722012-02-28 11:50:359927
9928 EXPECT_TRUE(response->headers->IsKeepAlive());
9929 EXPECT_EQ(200, response->headers->response_code());
9930 EXPECT_EQ(5, response->headers->GetContentLength());
9931 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
9932
9933 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:529934 EXPECT_FALSE(response->auth_challenge);
[email protected]0c5fb722012-02-28 11:50:359935
[email protected]029c83b62013-01-24 05:28:209936 LoadTimingInfo load_timing_info;
9937 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
9938 TestLoadTimingNotReusedWithPac(load_timing_info,
9939 CONNECT_TIMING_HAS_SSL_TIMES);
9940
[email protected]0c5fb722012-02-28 11:50:359941 trans.reset();
9942 session->CloseAllConnections();
9943}
9944
[email protected]7c6f7ba2012-04-03 04:09:299945// Test that an explicitly trusted SPDY proxy can push a resource from an
9946// origin that is different from that of its associated resource.
bncd16676a2016-07-20 16:23:019947TEST_F(HttpNetworkTransactionTest, CrossOriginSPDYProxyPush) {
tbansal28e68f82016-02-04 02:56:159948 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:199949 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:159950 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
9951 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]7c6f7ba2012-04-03 04:09:299952 HttpRequestInfo request;
9953 HttpRequestInfo push_request;
Ramin Halavatib5e433e62018-02-07 07:41:109954 request.traffic_annotation =
9955 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7c6f7ba2012-04-03 04:09:299956
[email protected]7c6f7ba2012-04-03 04:09:299957 request.method = "GET";
bncce36dca22015-04-21 22:11:239958 request.url = GURL("http://www.example.org/");
[email protected]7c6f7ba2012-04-03 04:09:299959 push_request.method = "GET";
9960 push_request.url = GURL("http://www.another-origin.com/foo.dat");
Ramin Halavatib5e433e62018-02-07 07:41:109961 push_request.traffic_annotation =
9962 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7c6f7ba2012-04-03 04:09:299963
tbansal28e68f82016-02-04 02:56:159964 // Configure against https proxy server "myproxy:443".
Lily Houghton8c2f97d2018-01-22 05:06:599965 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499966 ProxyResolutionService::CreateFixedFromPacResult(
9967 "HTTPS myproxy:443", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519968 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:079969 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:509970
Eric Roman3d8546a2018-09-10 17:00:529971 session_deps_.proxy_resolution_service->SetProxyDelegate(
9972 proxy_delegate.get());
[email protected]61b4efc2012-04-27 18:12:509973
danakj1fd259a02016-04-16 03:17:099974 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:299975
Ryan Hamilton0239aac2018-05-19 00:03:139976 spdy::SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:459977 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:139978 spdy::SpdySerializedFrame stream2_priority(
tombergan5d22c182017-01-11 02:05:359979 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
[email protected]7c6f7ba2012-04-03 04:09:299980
9981 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:419982 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:359983 CreateMockWrite(stream2_priority, 3, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:299984 };
9985
Ryan Hamilton0239aac2018-05-19 00:03:139986 spdy::SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
Bence Béky7bf94362018-01-10 13:19:369987 NULL, 0, 2, 1, "http://www.another-origin.com/foo.dat"));
9988
Ryan Hamilton0239aac2018-05-19 00:03:139989 spdy::SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:159990 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:299991
Ryan Hamilton0239aac2018-05-19 00:03:139992 spdy::SpdySerializedFrame stream1_body(
9993 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:299994
Ryan Hamilton0239aac2018-05-19 00:03:139995 spdy::SpdySerializedFrame stream2_body(
Bence Békyd74f4382018-02-20 18:26:199996 spdy_util_.ConstructSpdyDataFrame(2, "pushed", true));
[email protected]7c6f7ba2012-04-03 04:09:299997
9998 MockRead spdy_reads[] = {
Bence Béky7bf94362018-01-10 13:19:369999 CreateMockRead(stream2_syn, 1, ASYNC),
10000 CreateMockRead(stream1_reply, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:3510001 CreateMockRead(stream1_body, 4, ASYNC),
10002 CreateMockRead(stream2_body, 5, ASYNC),
10003 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
[email protected]7c6f7ba2012-04-03 04:09:2910004 };
10005
Ryan Sleevib8d7ea02018-05-07 20:01:0110006 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0710007 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:2910008 // Negotiate SPDY to the proxy
10009 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610010 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0710011 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:2910012
bnc87dcefc2017-05-25 12:47:5810013 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1910014 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7c6f7ba2012-04-03 04:09:2910015 TestCompletionCallback callback;
10016 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0110017 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:2910018
10019 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110020 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:2910021 const HttpResponseInfo* response = trans->GetResponseInfo();
10022
bnc87dcefc2017-05-25 12:47:5810023 auto push_trans =
Jeremy Roman0579ed62017-08-29 15:56:1910024 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]90499482013-06-01 00:39:5010025 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0110026 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:2910027
10028 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110029 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:2910030 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
10031
wezca1070932016-05-26 20:30:5210032 ASSERT_TRUE(response);
[email protected]7c6f7ba2012-04-03 04:09:2910033 EXPECT_TRUE(response->headers->IsKeepAlive());
10034
10035 EXPECT_EQ(200, response->headers->response_code());
10036 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10037
10038 std::string response_data;
10039 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:0110040 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:2910041 EXPECT_EQ("hello!", response_data);
10042
[email protected]029c83b62013-01-24 05:28:2010043 LoadTimingInfo load_timing_info;
10044 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10045 TestLoadTimingNotReusedWithPac(load_timing_info,
10046 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
10047
[email protected]7c6f7ba2012-04-03 04:09:2910048 // Verify the pushed stream.
wezca1070932016-05-26 20:30:5210049 EXPECT_TRUE(push_response->headers);
[email protected]7c6f7ba2012-04-03 04:09:2910050 EXPECT_EQ(200, push_response->headers->response_code());
10051
10052 rv = ReadTransaction(push_trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:0110053 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:2910054 EXPECT_EQ("pushed", response_data);
10055
[email protected]029c83b62013-01-24 05:28:2010056 LoadTimingInfo push_load_timing_info;
10057 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
10058 TestLoadTimingReusedWithPac(push_load_timing_info);
10059 // The transactions should share a socket ID, despite being for different
10060 // origins.
10061 EXPECT_EQ(load_timing_info.socket_log_id,
10062 push_load_timing_info.socket_log_id);
10063
[email protected]7c6f7ba2012-04-03 04:09:2910064 trans.reset();
10065 push_trans.reset();
10066 session->CloseAllConnections();
10067}
10068
[email protected]8c843192012-04-05 07:15:0010069// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
bncd16676a2016-07-20 16:23:0110070TEST_F(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:1510071 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:1910072 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:1510073 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
10074 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]8c843192012-04-05 07:15:0010075 HttpRequestInfo request;
10076
10077 request.method = "GET";
bncce36dca22015-04-21 22:11:2310078 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010079 request.traffic_annotation =
10080 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c843192012-04-05 07:15:0010081
Ramin Halavatica8d5252018-03-12 05:33:4910082 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
10083 "https://myproxy:443", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110084 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710085 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:5010086
10087 // Enable cross-origin push.
Eric Roman3d8546a2018-09-10 17:00:5210088 session_deps_.proxy_resolution_service->SetProxyDelegate(
10089 proxy_delegate.get());
[email protected]61b4efc2012-04-27 18:12:5010090
danakj1fd259a02016-04-16 03:17:0910091 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:0010092
Ryan Hamilton0239aac2018-05-19 00:03:1310093 spdy::SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:4510094 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
[email protected]8c843192012-04-05 07:15:0010095
Ryan Hamilton0239aac2018-05-19 00:03:1310096 spdy::SpdySerializedFrame push_rst(
10097 spdy_util_.ConstructSpdyRstStream(2, spdy::ERROR_CODE_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:0010098
10099 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4110100 CreateMockWrite(stream1_syn, 0, ASYNC), CreateMockWrite(push_rst, 3),
[email protected]8c843192012-04-05 07:15:0010101 };
10102
Ryan Hamilton0239aac2018-05-19 00:03:1310103 spdy::SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:1510104 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:0010105
Ryan Hamilton0239aac2018-05-19 00:03:1310106 spdy::SpdySerializedFrame stream1_body(
10107 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]8c843192012-04-05 07:15:0010108
Ryan Hamilton0239aac2018-05-19 00:03:1310109 spdy::SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
bncb03b1092016-04-06 11:19:5510110 NULL, 0, 2, 1, "https://www.another-origin.com/foo.dat"));
[email protected]8c843192012-04-05 07:15:0010111
10112 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4110113 CreateMockRead(stream1_reply, 1, ASYNC),
10114 CreateMockRead(stream2_syn, 2, ASYNC),
10115 CreateMockRead(stream1_body, 4, ASYNC),
mmenkee24011922015-12-17 22:12:5910116 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
[email protected]8c843192012-04-05 07:15:0010117 };
10118
Ryan Sleevib8d7ea02018-05-07 20:01:0110119 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0710120 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:0010121 // Negotiate SPDY to the proxy
10122 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610123 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0710124 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:0010125
bnc87dcefc2017-05-25 12:47:5810126 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1910127 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]8c843192012-04-05 07:15:0010128 TestCompletionCallback callback;
10129 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0110130 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c843192012-04-05 07:15:0010131
10132 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110133 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:0010134 const HttpResponseInfo* response = trans->GetResponseInfo();
10135
wezca1070932016-05-26 20:30:5210136 ASSERT_TRUE(response);
[email protected]8c843192012-04-05 07:15:0010137 EXPECT_TRUE(response->headers->IsKeepAlive());
10138
10139 EXPECT_EQ(200, response->headers->response_code());
10140 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10141
10142 std::string response_data;
10143 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:0110144 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:0010145 EXPECT_EQ("hello!", response_data);
10146
10147 trans.reset();
10148 session->CloseAllConnections();
10149}
10150
tbansal8ef1d3e2016-02-03 04:05:4210151// Test that an explicitly trusted SPDY proxy can push same-origin HTTPS
10152// resources.
bncd16676a2016-07-20 16:23:0110153TEST_F(HttpNetworkTransactionTest, SameOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:1510154 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:1910155 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:1510156 proxy_delegate->set_trusted_spdy_proxy(
10157 net::ProxyServer::FromURI("myproxy:70", net::ProxyServer::SCHEME_HTTP));
10158
tbansal8ef1d3e2016-02-03 04:05:4210159 HttpRequestInfo request;
10160
10161 request.method = "GET";
10162 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010163 request.traffic_annotation =
10164 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal8ef1d3e2016-02-03 04:05:4210165
10166 // Configure against https proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:4910167 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
10168 "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal8ef1d3e2016-02-03 04:05:4210169 BoundTestNetLog log;
10170 session_deps_.net_log = log.bound().net_log();
10171
10172 // Enable cross-origin push.
Eric Roman3d8546a2018-09-10 17:00:5210173 session_deps_.proxy_resolution_service->SetProxyDelegate(
10174 proxy_delegate.get());
tbansal8ef1d3e2016-02-03 04:05:4210175
danakj1fd259a02016-04-16 03:17:0910176 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
tbansal8ef1d3e2016-02-03 04:05:4210177
Ryan Hamilton0239aac2018-05-19 00:03:1310178 spdy::SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:4510179 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1310180 spdy::SpdySerializedFrame stream2_priority(
tombergan5d22c182017-01-11 02:05:3510181 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
tbansal8ef1d3e2016-02-03 04:05:4210182
10183 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4110184 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:3510185 CreateMockWrite(stream2_priority, 3, ASYNC),
tbansal8ef1d3e2016-02-03 04:05:4210186 };
10187
Ryan Hamilton0239aac2018-05-19 00:03:1310188 spdy::SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:1510189 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:4210190
Ryan Hamilton0239aac2018-05-19 00:03:1310191 spdy::SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
Bence Béky096cf052017-08-08 23:55:3310192 nullptr, 0, 2, 1, "http://www.example.org/foo.dat"));
bnc38dcd392016-02-09 23:19:4910193
Ryan Hamilton0239aac2018-05-19 00:03:1310194 spdy::SpdySerializedFrame stream1_body(
10195 spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:4210196
Ryan Hamilton0239aac2018-05-19 00:03:1310197 spdy::SpdySerializedFrame stream2_reply(
bnc42331402016-07-25 13:36:1510198 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:4210199
Ryan Hamilton0239aac2018-05-19 00:03:1310200 spdy::SpdySerializedFrame stream2_body(
10201 spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:4210202
10203 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4110204 CreateMockRead(stream1_reply, 1, ASYNC),
10205 CreateMockRead(stream2_syn, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:3510206 CreateMockRead(stream1_body, 4, ASYNC),
10207 CreateMockRead(stream2_body, 5, ASYNC),
10208 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
tbansal8ef1d3e2016-02-03 04:05:4210209 };
10210
Ryan Sleevib8d7ea02018-05-07 20:01:0110211 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
tbansal8ef1d3e2016-02-03 04:05:4210212 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
10213 // Negotiate SPDY to the proxy
10214 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610215 proxy.next_proto = kProtoHTTP2;
tbansal8ef1d3e2016-02-03 04:05:4210216 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
10217
bnc87dcefc2017-05-25 12:47:5810218 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1910219 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tbansal8ef1d3e2016-02-03 04:05:4210220 TestCompletionCallback callback;
10221 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0110222 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
tbansal8ef1d3e2016-02-03 04:05:4210223
10224 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110225 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:4210226 const HttpResponseInfo* response = trans->GetResponseInfo();
10227
wezca1070932016-05-26 20:30:5210228 ASSERT_TRUE(response);
tbansal8ef1d3e2016-02-03 04:05:4210229 EXPECT_TRUE(response->headers->IsKeepAlive());
10230
10231 EXPECT_EQ(200, response->headers->response_code());
10232 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10233
10234 std::string response_data;
10235 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:0110236 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:4210237 EXPECT_EQ("hello!", response_data);
10238
10239 trans.reset();
10240 session->CloseAllConnections();
10241}
10242
[email protected]2df19bb2010-08-25 20:13:4610243// Test HTTPS connections to a site with a bad certificate, going through an
10244// HTTPS proxy
bncd16676a2016-07-20 16:23:0110245TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
Ramin Halavatica8d5252018-03-12 05:33:4910246 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
10247 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:4610248
10249 HttpRequestInfo request;
10250 request.method = "GET";
bncce36dca22015-04-21 22:11:2310251 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010252 request.traffic_annotation =
10253 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:4610254
10255 // Attempt to fetch the URL from a server with a bad cert
10256 MockWrite bad_cert_writes[] = {
rsleevidb16bb02015-11-12 23:47:1710257 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
10258 "Host: www.example.org:443\r\n"
10259 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:4610260 };
10261
10262 MockRead bad_cert_reads[] = {
10263 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610264 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:4610265 };
10266
10267 // Attempt to fetch the URL with a good cert
10268 MockWrite good_data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1710269 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
10270 "Host: www.example.org:443\r\n"
10271 "Proxy-Connection: keep-alive\r\n\r\n"),
10272 MockWrite("GET / HTTP/1.1\r\n"
10273 "Host: www.example.org\r\n"
10274 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:4610275 };
10276
10277 MockRead good_cert_reads[] = {
10278 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
10279 MockRead("HTTP/1.0 200 OK\r\n"),
10280 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10281 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610282 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:4610283 };
10284
Ryan Sleevib8d7ea02018-05-07 20:01:0110285 StaticSocketDataProvider ssl_bad_certificate(bad_cert_reads, bad_cert_writes);
10286 StaticSocketDataProvider data(good_cert_reads, good_data_writes);
[email protected]8ddf8322012-02-23 18:08:0610287 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
10288 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:4610289
10290 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:0710291 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10292 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
10293 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:4610294
10295 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:0710296 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10297 session_deps_.socket_factory->AddSocketDataProvider(&data);
10298 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:4610299
[email protected]49639fa2011-12-20 23:22:4110300 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:4610301
danakj1fd259a02016-04-16 03:17:0910302 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610303 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:4610304
tfarina42834112016-09-22 13:38:2010305 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110306 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:4610307
10308 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110309 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]2df19bb2010-08-25 20:13:4610310
bnc691fda62016-08-12 00:43:1610311 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:0110312 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:4610313
10314 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110315 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:4610316
bnc691fda62016-08-12 00:43:1610317 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:4610318
wezca1070932016-05-26 20:30:5210319 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:4610320 EXPECT_EQ(100, response->headers->GetContentLength());
10321}
10322
bncd16676a2016-07-20 16:23:0110323TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:4210324 HttpRequestInfo request;
10325 request.method = "GET";
bncce36dca22015-04-21 22:11:2310326 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:4310327 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
10328 "Chromium Ultra Awesome X Edition");
Ramin Halavatib5e433e62018-02-07 07:41:1010329 request.traffic_annotation =
10330 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210331
danakj1fd259a02016-04-16 03:17:0910332 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610333 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710334
[email protected]1c773ea12009-04-28 19:58:4210335 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310336 MockWrite(
10337 "GET / HTTP/1.1\r\n"
10338 "Host: www.example.org\r\n"
10339 "Connection: keep-alive\r\n"
10340 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210341 };
10342
10343 // Lastly, the server responds with the actual content.
10344 MockRead data_reads[] = {
10345 MockRead("HTTP/1.0 200 OK\r\n"),
10346 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10347 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610348 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210349 };
10350
Ryan Sleevib8d7ea02018-05-07 20:01:0110351 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710352 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210353
[email protected]49639fa2011-12-20 23:22:4110354 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210355
tfarina42834112016-09-22 13:38:2010356 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110357 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210358
10359 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110360 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210361}
10362
bncd16676a2016-07-20 16:23:0110363TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:2910364 HttpRequestInfo request;
10365 request.method = "GET";
bncce36dca22015-04-21 22:11:2310366 request.url = GURL("https://www.example.org/");
[email protected]da81f132010-08-18 23:39:2910367 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
10368 "Chromium Ultra Awesome X Edition");
Ramin Halavatib5e433e62018-02-07 07:41:1010369 request.traffic_annotation =
10370 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]da81f132010-08-18 23:39:2910371
Ramin Halavatica8d5252018-03-12 05:33:4910372 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
10373 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:0910374 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610375 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710376
[email protected]da81f132010-08-18 23:39:2910377 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1710378 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
10379 "Host: www.example.org:443\r\n"
10380 "Proxy-Connection: keep-alive\r\n"
10381 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]da81f132010-08-18 23:39:2910382 };
10383 MockRead data_reads[] = {
10384 // Return an error, so the transaction stops here (this test isn't
10385 // interested in the rest).
10386 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
10387 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
10388 MockRead("Proxy-Connection: close\r\n\r\n"),
10389 };
10390
Ryan Sleevib8d7ea02018-05-07 20:01:0110391 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710392 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:2910393
[email protected]49639fa2011-12-20 23:22:4110394 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:2910395
tfarina42834112016-09-22 13:38:2010396 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110397 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]da81f132010-08-18 23:39:2910398
10399 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110400 EXPECT_THAT(rv, IsOk());
[email protected]da81f132010-08-18 23:39:2910401}
10402
bncd16676a2016-07-20 16:23:0110403TEST_F(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:4210404 HttpRequestInfo request;
10405 request.method = "GET";
bncce36dca22015-04-21 22:11:2310406 request.url = GURL("http://www.example.org/");
[email protected]c10450102011-06-27 09:06:1610407 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
10408 "http://the.previous.site.com/");
Ramin Halavatib5e433e62018-02-07 07:41:1010409 request.traffic_annotation =
10410 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210411
danakj1fd259a02016-04-16 03:17:0910412 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610413 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710414
[email protected]1c773ea12009-04-28 19:58:4210415 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310416 MockWrite(
10417 "GET / HTTP/1.1\r\n"
10418 "Host: www.example.org\r\n"
10419 "Connection: keep-alive\r\n"
10420 "Referer: http://the.previous.site.com/\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210421 };
10422
10423 // Lastly, the server responds with the actual content.
10424 MockRead data_reads[] = {
10425 MockRead("HTTP/1.0 200 OK\r\n"),
10426 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10427 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610428 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210429 };
10430
Ryan Sleevib8d7ea02018-05-07 20:01:0110431 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710432 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210433
[email protected]49639fa2011-12-20 23:22:4110434 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210435
tfarina42834112016-09-22 13:38:2010436 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110437 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210438
10439 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110440 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210441}
10442
bncd16676a2016-07-20 16:23:0110443TEST_F(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:4210444 HttpRequestInfo request;
10445 request.method = "POST";
bncce36dca22015-04-21 22:11:2310446 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010447 request.traffic_annotation =
10448 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210449
danakj1fd259a02016-04-16 03:17:0910450 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610451 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710452
[email protected]1c773ea12009-04-28 19:58:4210453 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310454 MockWrite(
10455 "POST / HTTP/1.1\r\n"
10456 "Host: www.example.org\r\n"
10457 "Connection: keep-alive\r\n"
10458 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210459 };
10460
10461 // Lastly, the server responds with the actual content.
10462 MockRead data_reads[] = {
10463 MockRead("HTTP/1.0 200 OK\r\n"),
10464 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10465 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610466 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210467 };
10468
Ryan Sleevib8d7ea02018-05-07 20:01:0110469 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710470 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210471
[email protected]49639fa2011-12-20 23:22:4110472 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210473
tfarina42834112016-09-22 13:38:2010474 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110475 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210476
10477 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110478 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210479}
10480
bncd16676a2016-07-20 16:23:0110481TEST_F(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:4210482 HttpRequestInfo request;
10483 request.method = "PUT";
bncce36dca22015-04-21 22:11:2310484 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010485 request.traffic_annotation =
10486 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210487
danakj1fd259a02016-04-16 03:17:0910488 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610489 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710490
[email protected]1c773ea12009-04-28 19:58:4210491 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310492 MockWrite(
10493 "PUT / HTTP/1.1\r\n"
10494 "Host: www.example.org\r\n"
10495 "Connection: keep-alive\r\n"
10496 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210497 };
10498
10499 // Lastly, the server responds with the actual content.
10500 MockRead data_reads[] = {
10501 MockRead("HTTP/1.0 200 OK\r\n"),
10502 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10503 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610504 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210505 };
10506
Ryan Sleevib8d7ea02018-05-07 20:01:0110507 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710508 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210509
[email protected]49639fa2011-12-20 23:22:4110510 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210511
tfarina42834112016-09-22 13:38:2010512 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110513 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210514
10515 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110516 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210517}
10518
bncd16676a2016-07-20 16:23:0110519TEST_F(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:4210520 HttpRequestInfo request;
10521 request.method = "HEAD";
bncce36dca22015-04-21 22:11:2310522 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010523 request.traffic_annotation =
10524 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210525
danakj1fd259a02016-04-16 03:17:0910526 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610527 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710528
[email protected]1c773ea12009-04-28 19:58:4210529 MockWrite data_writes[] = {
csharrisonf473dd192015-08-18 13:54:1310530 MockWrite("HEAD / HTTP/1.1\r\n"
10531 "Host: www.example.org\r\n"
10532 "Connection: keep-alive\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210533 };
10534
10535 // Lastly, the server responds with the actual content.
10536 MockRead data_reads[] = {
10537 MockRead("HTTP/1.0 200 OK\r\n"),
10538 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10539 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610540 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210541 };
10542
Ryan Sleevib8d7ea02018-05-07 20:01:0110543 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710544 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210545
[email protected]49639fa2011-12-20 23:22:4110546 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210547
tfarina42834112016-09-22 13:38:2010548 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110549 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210550
10551 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110552 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210553}
10554
bncd16676a2016-07-20 16:23:0110555TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:4210556 HttpRequestInfo request;
10557 request.method = "GET";
bncce36dca22015-04-21 22:11:2310558 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:4210559 request.load_flags = LOAD_BYPASS_CACHE;
Ramin Halavatib5e433e62018-02-07 07:41:1010560 request.traffic_annotation =
10561 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210562
danakj1fd259a02016-04-16 03:17:0910563 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610564 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710565
[email protected]1c773ea12009-04-28 19:58:4210566 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310567 MockWrite(
10568 "GET / HTTP/1.1\r\n"
10569 "Host: www.example.org\r\n"
10570 "Connection: keep-alive\r\n"
10571 "Pragma: no-cache\r\n"
10572 "Cache-Control: no-cache\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210573 };
10574
10575 // Lastly, the server responds with the actual content.
10576 MockRead data_reads[] = {
10577 MockRead("HTTP/1.0 200 OK\r\n"),
10578 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10579 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610580 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210581 };
10582
Ryan Sleevib8d7ea02018-05-07 20:01:0110583 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710584 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210585
[email protected]49639fa2011-12-20 23:22:4110586 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210587
tfarina42834112016-09-22 13:38:2010588 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110589 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210590
10591 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110592 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210593}
10594
bncd16676a2016-07-20 16:23:0110595TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:4210596 HttpRequestInfo request;
10597 request.method = "GET";
bncce36dca22015-04-21 22:11:2310598 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:4210599 request.load_flags = LOAD_VALIDATE_CACHE;
Ramin Halavatib5e433e62018-02-07 07:41:1010600 request.traffic_annotation =
10601 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210602
danakj1fd259a02016-04-16 03:17:0910603 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610604 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710605
[email protected]1c773ea12009-04-28 19:58:4210606 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310607 MockWrite(
10608 "GET / HTTP/1.1\r\n"
10609 "Host: www.example.org\r\n"
10610 "Connection: keep-alive\r\n"
10611 "Cache-Control: max-age=0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210612 };
10613
10614 // Lastly, the server responds with the actual content.
10615 MockRead data_reads[] = {
10616 MockRead("HTTP/1.0 200 OK\r\n"),
10617 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10618 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610619 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210620 };
10621
Ryan Sleevib8d7ea02018-05-07 20:01:0110622 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710623 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210624
[email protected]49639fa2011-12-20 23:22:4110625 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210626
tfarina42834112016-09-22 13:38:2010627 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110628 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210629
10630 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110631 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210632}
10633
bncd16676a2016-07-20 16:23:0110634TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:4210635 HttpRequestInfo request;
10636 request.method = "GET";
bncce36dca22015-04-21 22:11:2310637 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:4310638 request.extra_headers.SetHeader("FooHeader", "Bar");
Ramin Halavatib5e433e62018-02-07 07:41:1010639 request.traffic_annotation =
10640 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210641
danakj1fd259a02016-04-16 03:17:0910642 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610643 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710644
[email protected]1c773ea12009-04-28 19:58:4210645 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310646 MockWrite(
10647 "GET / HTTP/1.1\r\n"
10648 "Host: www.example.org\r\n"
10649 "Connection: keep-alive\r\n"
10650 "FooHeader: Bar\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210651 };
10652
10653 // Lastly, the server responds with the actual content.
10654 MockRead data_reads[] = {
10655 MockRead("HTTP/1.0 200 OK\r\n"),
10656 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10657 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610658 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210659 };
10660
Ryan Sleevib8d7ea02018-05-07 20:01:0110661 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710662 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210663
[email protected]49639fa2011-12-20 23:22:4110664 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210665
tfarina42834112016-09-22 13:38:2010666 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110667 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210668
10669 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110670 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210671}
10672
bncd16676a2016-07-20 16:23:0110673TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:4710674 HttpRequestInfo request;
10675 request.method = "GET";
bncce36dca22015-04-21 22:11:2310676 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:4310677 request.extra_headers.SetHeader("referer", "www.foo.com");
10678 request.extra_headers.SetHeader("hEllo", "Kitty");
10679 request.extra_headers.SetHeader("FoO", "bar");
Ramin Halavatib5e433e62018-02-07 07:41:1010680 request.traffic_annotation =
10681 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]270c6412010-03-29 22:02:4710682
danakj1fd259a02016-04-16 03:17:0910683 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610684 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710685
[email protected]270c6412010-03-29 22:02:4710686 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310687 MockWrite(
10688 "GET / HTTP/1.1\r\n"
10689 "Host: www.example.org\r\n"
10690 "Connection: keep-alive\r\n"
10691 "referer: www.foo.com\r\n"
10692 "hEllo: Kitty\r\n"
10693 "FoO: bar\r\n\r\n"),
[email protected]270c6412010-03-29 22:02:4710694 };
10695
10696 // Lastly, the server responds with the actual content.
10697 MockRead data_reads[] = {
10698 MockRead("HTTP/1.0 200 OK\r\n"),
10699 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10700 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610701 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:4710702 };
10703
Ryan Sleevib8d7ea02018-05-07 20:01:0110704 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710705 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:4710706
[email protected]49639fa2011-12-20 23:22:4110707 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:4710708
tfarina42834112016-09-22 13:38:2010709 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110710 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]270c6412010-03-29 22:02:4710711
10712 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110713 EXPECT_THAT(rv, IsOk());
[email protected]270c6412010-03-29 22:02:4710714}
10715
bncd16676a2016-07-20 16:23:0110716TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:2710717 HttpRequestInfo request;
10718 request.method = "GET";
bncce36dca22015-04-21 22:11:2310719 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010720 request.traffic_annotation =
10721 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710722
Lily Houghton8c2f97d2018-01-22 05:06:5910723 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910724 ProxyResolutionService::CreateFixedFromPacResult(
10725 "SOCKS myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110726 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710727 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:0210728
danakj1fd259a02016-04-16 03:17:0910729 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610730 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:0210731
[email protected]3cd17242009-06-23 02:59:0210732 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
10733 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
10734
10735 MockWrite data_writes[] = {
Avi Drissman4365a4782018-12-28 19:26:2410736 MockWrite(ASYNC, write_buffer, base::size(write_buffer)),
10737 MockWrite("GET / HTTP/1.1\r\n"
10738 "Host: www.example.org\r\n"
10739 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:0210740
10741 MockRead data_reads[] = {
Avi Drissman4365a4782018-12-28 19:26:2410742 MockRead(ASYNC, read_buffer, base::size(read_buffer)),
10743 MockRead("HTTP/1.0 200 OK\r\n"),
10744 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
10745 MockRead("Payload"), MockRead(SYNCHRONOUS, OK)};
[email protected]3cd17242009-06-23 02:59:0210746
Ryan Sleevib8d7ea02018-05-07 20:01:0110747 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710748 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:0210749
[email protected]49639fa2011-12-20 23:22:4110750 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:0210751
tfarina42834112016-09-22 13:38:2010752 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110753 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:0210754
10755 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110756 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0210757
bnc691fda62016-08-12 00:43:1610758 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210759 ASSERT_TRUE(response);
[email protected]3cd17242009-06-23 02:59:0210760
tbansal2ecbbc72016-10-06 17:15:4710761 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]029c83b62013-01-24 05:28:2010762 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1610763 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2010764 TestLoadTimingNotReusedWithPac(load_timing_info,
10765 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
10766
[email protected]3cd17242009-06-23 02:59:0210767 std::string response_text;
bnc691fda62016-08-12 00:43:1610768 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0110769 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0210770 EXPECT_EQ("Payload", response_text);
10771}
10772
bncd16676a2016-07-20 16:23:0110773TEST_F(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:2710774 HttpRequestInfo request;
10775 request.method = "GET";
bncce36dca22015-04-21 22:11:2310776 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010777 request.traffic_annotation =
10778 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710779
Lily Houghton8c2f97d2018-01-22 05:06:5910780 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910781 ProxyResolutionService::CreateFixedFromPacResult(
10782 "SOCKS myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110783 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710784 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:0210785
danakj1fd259a02016-04-16 03:17:0910786 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610787 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:0210788
[email protected]3cd17242009-06-23 02:59:0210789 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
10790 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
10791
10792 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310793 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
Avi Drissman4365a4782018-12-28 19:26:2410794 base::size(write_buffer)),
10795 MockWrite("GET / HTTP/1.1\r\n"
10796 "Host: www.example.org\r\n"
10797 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:0210798
10799 MockRead data_reads[] = {
Avi Drissman4365a4782018-12-28 19:26:2410800 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
10801 base::size(read_buffer)),
10802 MockRead("HTTP/1.0 200 OK\r\n"),
10803 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
10804 MockRead("Payload"), MockRead(SYNCHRONOUS, OK)};
[email protected]e0c27be2009-07-15 13:09:3510805
Ryan Sleevib8d7ea02018-05-07 20:01:0110806 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710807 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:3510808
[email protected]8ddf8322012-02-23 18:08:0610809 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710810 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:3510811
[email protected]49639fa2011-12-20 23:22:4110812 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:3510813
tfarina42834112016-09-22 13:38:2010814 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110815 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:3510816
10817 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110818 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3510819
[email protected]029c83b62013-01-24 05:28:2010820 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1610821 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2010822 TestLoadTimingNotReusedWithPac(load_timing_info,
10823 CONNECT_TIMING_HAS_SSL_TIMES);
10824
bnc691fda62016-08-12 00:43:1610825 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210826 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:4710827 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:3510828
10829 std::string response_text;
bnc691fda62016-08-12 00:43:1610830 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0110831 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3510832 EXPECT_EQ("Payload", response_text);
10833}
10834
bncd16676a2016-07-20 16:23:0110835TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:2010836 HttpRequestInfo request;
10837 request.method = "GET";
bncce36dca22015-04-21 22:11:2310838 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010839 request.traffic_annotation =
10840 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:2010841
Ramin Halavatica8d5252018-03-12 05:33:4910842 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
10843 "socks4://myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110844 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710845 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:2010846
danakj1fd259a02016-04-16 03:17:0910847 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610848 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:2010849
10850 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
10851 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
10852
10853 MockWrite data_writes[] = {
Avi Drissman4365a4782018-12-28 19:26:2410854 MockWrite(ASYNC, write_buffer, base::size(write_buffer)),
10855 MockWrite("GET / HTTP/1.1\r\n"
10856 "Host: www.example.org\r\n"
10857 "Connection: keep-alive\r\n\r\n")};
[email protected]029c83b62013-01-24 05:28:2010858
10859 MockRead data_reads[] = {
Avi Drissman4365a4782018-12-28 19:26:2410860 MockRead(ASYNC, read_buffer, base::size(read_buffer)),
10861 MockRead("HTTP/1.0 200 OK\r\n"),
10862 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
10863 MockRead("Payload"), MockRead(SYNCHRONOUS, OK)};
[email protected]029c83b62013-01-24 05:28:2010864
Ryan Sleevib8d7ea02018-05-07 20:01:0110865 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710866 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:2010867
10868 TestCompletionCallback callback;
10869
tfarina42834112016-09-22 13:38:2010870 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110871 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:2010872
10873 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110874 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:2010875
bnc691fda62016-08-12 00:43:1610876 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210877 ASSERT_TRUE(response);
[email protected]029c83b62013-01-24 05:28:2010878
10879 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1610880 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2010881 TestLoadTimingNotReused(load_timing_info,
10882 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
10883
10884 std::string response_text;
bnc691fda62016-08-12 00:43:1610885 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0110886 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:2010887 EXPECT_EQ("Payload", response_text);
10888}
10889
bncd16676a2016-07-20 16:23:0110890TEST_F(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:2710891 HttpRequestInfo request;
10892 request.method = "GET";
bncce36dca22015-04-21 22:11:2310893 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010894 request.traffic_annotation =
10895 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710896
Lily Houghton8c2f97d2018-01-22 05:06:5910897 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910898 ProxyResolutionService::CreateFixedFromPacResult(
10899 "SOCKS5 myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110900 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710901 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:3510902
danakj1fd259a02016-04-16 03:17:0910903 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610904 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:3510905
[email protected]e0c27be2009-07-15 13:09:3510906 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
10907 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:3710908 const char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:2310909 0x05, // Version
10910 0x01, // Command (CONNECT)
10911 0x00, // Reserved.
10912 0x03, // Address type (DOMAINNAME).
10913 0x0F, // Length of domain (15)
10914 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
10915 '.', 'o', 'r', 'g', 0x00, 0x50, // 16-bit port (80)
[email protected]f209dba2009-12-18 00:24:3710916 };
[email protected]e0c27be2009-07-15 13:09:3510917 const char kSOCKS5OkResponse[] =
10918 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
10919
10920 MockWrite data_writes[] = {
Avi Drissman4365a4782018-12-28 19:26:2410921 MockWrite(ASYNC, kSOCKS5GreetRequest, base::size(kSOCKS5GreetRequest)),
10922 MockWrite(ASYNC, kSOCKS5OkRequest, base::size(kSOCKS5OkRequest)),
10923 MockWrite("GET / HTTP/1.1\r\n"
10924 "Host: www.example.org\r\n"
10925 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:3510926
10927 MockRead data_reads[] = {
Avi Drissman4365a4782018-12-28 19:26:2410928 MockRead(ASYNC, kSOCKS5GreetResponse, base::size(kSOCKS5GreetResponse)),
10929 MockRead(ASYNC, kSOCKS5OkResponse, base::size(kSOCKS5OkResponse)),
10930 MockRead("HTTP/1.0 200 OK\r\n"),
10931 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
10932 MockRead("Payload"),
10933 MockRead(SYNCHRONOUS, OK)};
[email protected]e0c27be2009-07-15 13:09:3510934
Ryan Sleevib8d7ea02018-05-07 20:01:0110935 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710936 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:3510937
[email protected]49639fa2011-12-20 23:22:4110938 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:3510939
tfarina42834112016-09-22 13:38:2010940 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110941 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:3510942
10943 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110944 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3510945
bnc691fda62016-08-12 00:43:1610946 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210947 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:4710948 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:3510949
[email protected]029c83b62013-01-24 05:28:2010950 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1610951 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2010952 TestLoadTimingNotReusedWithPac(load_timing_info,
10953 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
10954
[email protected]e0c27be2009-07-15 13:09:3510955 std::string response_text;
bnc691fda62016-08-12 00:43:1610956 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0110957 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3510958 EXPECT_EQ("Payload", response_text);
10959}
10960
bncd16676a2016-07-20 16:23:0110961TEST_F(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:2710962 HttpRequestInfo request;
10963 request.method = "GET";
bncce36dca22015-04-21 22:11:2310964 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010965 request.traffic_annotation =
10966 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710967
Lily Houghton8c2f97d2018-01-22 05:06:5910968 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910969 ProxyResolutionService::CreateFixedFromPacResult(
10970 "SOCKS5 myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110971 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710972 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:3510973
danakj1fd259a02016-04-16 03:17:0910974 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610975 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:3510976
[email protected]e0c27be2009-07-15 13:09:3510977 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
10978 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:3710979 const unsigned char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:2310980 0x05, // Version
10981 0x01, // Command (CONNECT)
10982 0x00, // Reserved.
10983 0x03, // Address type (DOMAINNAME).
10984 0x0F, // Length of domain (15)
10985 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
10986 '.', 'o', 'r', 'g', 0x01, 0xBB, // 16-bit port (443)
[email protected]f209dba2009-12-18 00:24:3710987 };
10988
[email protected]e0c27be2009-07-15 13:09:3510989 const char kSOCKS5OkResponse[] =
10990 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
10991
10992 MockWrite data_writes[] = {
Avi Drissman4365a4782018-12-28 19:26:2410993 MockWrite(ASYNC, kSOCKS5GreetRequest, base::size(kSOCKS5GreetRequest)),
bncce36dca22015-04-21 22:11:2310994 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
Avi Drissman4365a4782018-12-28 19:26:2410995 base::size(kSOCKS5OkRequest)),
10996 MockWrite("GET / HTTP/1.1\r\n"
10997 "Host: www.example.org\r\n"
10998 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:3510999
11000 MockRead data_reads[] = {
Avi Drissman4365a4782018-12-28 19:26:2411001 MockRead(ASYNC, kSOCKS5GreetResponse, base::size(kSOCKS5GreetResponse)),
11002 MockRead(ASYNC, kSOCKS5OkResponse, base::size(kSOCKS5OkResponse)),
11003 MockRead("HTTP/1.0 200 OK\r\n"),
11004 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
11005 MockRead("Payload"),
11006 MockRead(SYNCHRONOUS, OK)};
[email protected]3cd17242009-06-23 02:59:0211007
Ryan Sleevib8d7ea02018-05-07 20:01:0111008 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0711009 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:0211010
[email protected]8ddf8322012-02-23 18:08:0611011 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0711012 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:0211013
[email protected]49639fa2011-12-20 23:22:4111014 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:0211015
tfarina42834112016-09-22 13:38:2011016 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111017 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:0211018
11019 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111020 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0211021
bnc691fda62016-08-12 00:43:1611022 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211023 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:4711024 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]3cd17242009-06-23 02:59:0211025
[email protected]029c83b62013-01-24 05:28:2011026 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1611027 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2011028 TestLoadTimingNotReusedWithPac(load_timing_info,
11029 CONNECT_TIMING_HAS_SSL_TIMES);
11030
[email protected]3cd17242009-06-23 02:59:0211031 std::string response_text;
bnc691fda62016-08-12 00:43:1611032 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0111033 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0211034 EXPECT_EQ("Payload", response_text);
11035}
11036
[email protected]448d4ca52012-03-04 04:12:2311037namespace {
11038
[email protected]04e5be32009-06-26 20:00:3111039// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:0611040
11041struct GroupNameTest {
11042 std::string proxy_server;
11043 std::string url;
11044 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:1811045 bool ssl;
[email protected]2d731a32010-04-29 01:04:0611046};
11047
danakj1fd259a02016-04-16 03:17:0911048std::unique_ptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]bb88e1d32013-05-03 23:11:0711049 SpdySessionDependencies* session_deps_) {
danakj1fd259a02016-04-16 03:17:0911050 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:0611051
bnc525e175a2016-06-20 12:36:4011052 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311053 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2111054 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnc7dc7e1b42015-07-28 14:43:1211055 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111056 http_server_properties->SetHttp2AlternativeService(
bncaa60ff402016-06-22 19:12:4211057 url::SchemeHostPort("https", "host.with.alternate", 443),
zhongyi3d4a55e72016-04-22 20:36:4611058 alternative_service, expiration);
[email protected]2d731a32010-04-29 01:04:0611059
11060 return session;
11061}
11062
mmenkee65e7af2015-10-13 17:16:4211063int GroupNameTransactionHelper(const std::string& url,
11064 HttpNetworkSession* session) {
[email protected]2d731a32010-04-29 01:04:0611065 HttpRequestInfo request;
11066 request.method = "GET";
11067 request.url = GURL(url);
Ramin Halavatib5e433e62018-02-07 07:41:1011068 request.traffic_annotation =
11069 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d731a32010-04-29 01:04:0611070
bnc691fda62016-08-12 00:43:1611071 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
[email protected]cb9bf6ca2011-01-28 13:15:2711072
[email protected]49639fa2011-12-20 23:22:4111073 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:0611074
11075 // We do not complete this request, the dtor will clean the transaction up.
tfarina42834112016-09-22 13:38:2011076 return trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]2d731a32010-04-29 01:04:0611077}
11078
[email protected]448d4ca52012-03-04 04:12:2311079} // namespace
11080
bncd16676a2016-07-20 16:23:0111081TEST_F(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:0611082 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:2311083 {
11084 "", // unused
11085 "http://www.example.org/direct",
11086 "www.example.org:80",
11087 false,
11088 },
11089 {
11090 "", // unused
11091 "http://[2001:1418:13:1::25]/direct",
11092 "[2001:1418:13:1::25]:80",
11093 false,
11094 },
[email protected]04e5be32009-06-26 20:00:3111095
bncce36dca22015-04-21 22:11:2311096 // SSL Tests
11097 {
11098 "", // unused
11099 "https://www.example.org/direct_ssl",
11100 "ssl/www.example.org:443",
11101 true,
11102 },
11103 {
11104 "", // unused
11105 "https://[2001:1418:13:1::25]/direct",
11106 "ssl/[2001:1418:13:1::25]:443",
11107 true,
11108 },
11109 {
11110 "", // unused
bncaa60ff402016-06-22 19:12:4211111 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:2311112 "ssl/host.with.alternate:443",
11113 true,
11114 },
[email protected]2d731a32010-04-29 01:04:0611115 };
[email protected]2ff8b312010-04-26 22:20:5411116
Avi Drissman4365a4782018-12-28 19:26:2411117 for (size_t i = 0; i < base::size(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5911118 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4911119 ProxyResolutionService::CreateFixed(tests[i].proxy_server,
11120 TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:0911121 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:4011122 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:0611123
mmenkee65e7af2015-10-13 17:16:4211124 HttpNetworkSessionPeer peer(session.get());
[email protected]ab739042011-04-07 15:22:2811125 CaptureGroupNameTransportSocketPool* transport_conn_pool =
bnc87dcefc2017-05-25 12:47:5811126 new CaptureGroupNameTransportSocketPool(nullptr, nullptr);
Jeremy Roman0579ed62017-08-29 15:56:1911127 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
[email protected]a42dbd142011-11-17 16:42:0211128 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
dchengc7eeda422015-12-26 03:56:4811129 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:0611130
11131 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:4211132 GroupNameTransactionHelper(tests[i].url, session.get()));
Matt Menke9d5e2c92019-02-05 01:42:2311133 EXPECT_EQ(tests[i].expected_group_name,
11134 transport_conn_pool->last_group_name_received());
11135 EXPECT_TRUE(transport_conn_pool->socket_requested());
[email protected]2d731a32010-04-29 01:04:0611136 }
[email protected]2d731a32010-04-29 01:04:0611137}
11138
bncd16676a2016-07-20 16:23:0111139TEST_F(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:0611140 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:2311141 {
Matt Menked1eb6d42018-01-17 04:54:0611142 "http_proxy", "http://www.example.org/http_proxy_normal",
11143 "http_proxy/www.example.org:80", false,
bncce36dca22015-04-21 22:11:2311144 },
[email protected]2d731a32010-04-29 01:04:0611145
bncce36dca22015-04-21 22:11:2311146 // SSL Tests
11147 {
Matt Menked1eb6d42018-01-17 04:54:0611148 "http_proxy", "https://www.example.org/http_connect_ssl",
11149 "http_proxy/ssl/www.example.org:443", true,
bncce36dca22015-04-21 22:11:2311150 },
[email protected]af3490e2010-10-16 21:02:2911151
bncce36dca22015-04-21 22:11:2311152 {
Matt Menked1eb6d42018-01-17 04:54:0611153 "http_proxy", "https://host.with.alternate/direct",
11154 "http_proxy/ssl/host.with.alternate:443", true,
bncce36dca22015-04-21 22:11:2311155 },
[email protected]45499252013-01-23 17:12:5611156
bncce36dca22015-04-21 22:11:2311157 {
Matt Menked1eb6d42018-01-17 04:54:0611158 "http_proxy", "ftp://ftp.google.com/http_proxy_normal",
11159 "http_proxy/ftp/ftp.google.com:21", false,
bncce36dca22015-04-21 22:11:2311160 },
[email protected]2d731a32010-04-29 01:04:0611161 };
11162
Avi Drissman4365a4782018-12-28 19:26:2411163 for (size_t i = 0; i < base::size(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5911164 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4911165 ProxyResolutionService::CreateFixed(tests[i].proxy_server,
11166 TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:0911167 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:4011168 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:0611169
mmenkee65e7af2015-10-13 17:16:4211170 HttpNetworkSessionPeer peer(session.get());
[email protected]2d731a32010-04-29 01:04:0611171
Matt Menkee8648fa2019-01-17 16:47:0711172 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
11173 HostPortPair("http_proxy", 80));
Matt Menke0754b5d02019-02-10 21:46:4311174 CaptureGroupNameTransportSocketPool* http_proxy_pool =
11175 new CaptureGroupNameTransportSocketPool(NULL, NULL);
Matt Menkedf126e0e2019-02-01 22:23:4711176 CaptureGroupNameTransportSocketPool* ssl_conn_pool =
11177 new CaptureGroupNameTransportSocketPool(NULL, NULL);
Jeremy Roman0579ed62017-08-29 15:56:1911178 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
aviadef3442016-10-03 18:50:3911179 mock_pool_manager->SetSocketPoolForHTTPProxy(
Matt Menkee8648fa2019-01-17 16:47:0711180 proxy_server, base::WrapUnique(http_proxy_pool));
aviadef3442016-10-03 18:50:3911181 mock_pool_manager->SetSocketPoolForSSLWithProxy(
Matt Menkee8648fa2019-01-17 16:47:0711182 proxy_server, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:4811183 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:0611184
11185 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:4211186 GroupNameTransactionHelper(tests[i].url, session.get()));
Matt Menkee8648fa2019-01-17 16:47:0711187 if (tests[i].ssl) {
[email protected]e60e47a2010-07-14 03:37:1811188 EXPECT_EQ(tests[i].expected_group_name,
11189 ssl_conn_pool->last_group_name_received());
Matt Menkee8648fa2019-01-17 16:47:0711190 } else {
[email protected]e60e47a2010-07-14 03:37:1811191 EXPECT_EQ(tests[i].expected_group_name,
11192 http_proxy_pool->last_group_name_received());
Matt Menkee8648fa2019-01-17 16:47:0711193 }
[email protected]2d731a32010-04-29 01:04:0611194 }
[email protected]2d731a32010-04-29 01:04:0611195}
11196
bncd16676a2016-07-20 16:23:0111197TEST_F(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:0611198 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:2311199 {
11200 "socks4://socks_proxy:1080",
11201 "http://www.example.org/socks4_direct",
11202 "socks4/www.example.org:80",
11203 false,
11204 },
11205 {
11206 "socks5://socks_proxy:1080",
11207 "http://www.example.org/socks5_direct",
11208 "socks5/www.example.org:80",
11209 false,
11210 },
[email protected]2d731a32010-04-29 01:04:0611211
bncce36dca22015-04-21 22:11:2311212 // SSL Tests
11213 {
11214 "socks4://socks_proxy:1080",
11215 "https://www.example.org/socks4_ssl",
11216 "socks4/ssl/www.example.org:443",
11217 true,
11218 },
11219 {
11220 "socks5://socks_proxy:1080",
11221 "https://www.example.org/socks5_ssl",
11222 "socks5/ssl/www.example.org:443",
11223 true,
11224 },
[email protected]af3490e2010-10-16 21:02:2911225
bncce36dca22015-04-21 22:11:2311226 {
11227 "socks4://socks_proxy:1080",
bncaa60ff402016-06-22 19:12:4211228 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:2311229 "socks4/ssl/host.with.alternate:443",
11230 true,
11231 },
[email protected]04e5be32009-06-26 20:00:3111232 };
11233
Avi Drissman4365a4782018-12-28 19:26:2411234 for (size_t i = 0; i < base::size(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5911235 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4911236 ProxyResolutionService::CreateFixed(tests[i].proxy_server,
11237 TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:0911238 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:4011239 SetupSessionForGroupNameTests(&session_deps_));
[email protected]8b114dd72011-03-25 05:33:0211240
mmenkee65e7af2015-10-13 17:16:4211241 HttpNetworkSessionPeer peer(session.get());
[email protected]04e5be32009-06-26 20:00:3111242
Matt Menkee8648fa2019-01-17 16:47:0711243 ProxyServer proxy_server(
11244 ProxyServer::FromURI(tests[i].proxy_server, ProxyServer::SCHEME_HTTP));
11245 ASSERT_TRUE(proxy_server.is_valid());
Matt Menke4b412da2019-01-25 19:31:1211246 CaptureGroupNameTransportSocketPool* socks_conn_pool =
11247 new CaptureGroupNameTransportSocketPool(NULL, NULL);
Jeremy Roman0579ed62017-08-29 15:56:1911248 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
Matt Menke4b412da2019-01-25 19:31:1211249 mock_pool_manager->SetSocketPoolForProxy(proxy_server,
11250 base::WrapUnique(socks_conn_pool));
dchengc7eeda422015-12-26 03:56:4811251 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]04e5be32009-06-26 20:00:3111252
bnc691fda62016-08-12 00:43:1611253 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]04e5be32009-06-26 20:00:3111254
[email protected]2d731a32010-04-29 01:04:0611255 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:4211256 GroupNameTransactionHelper(tests[i].url, session.get()));
Matt Menke628d624f2019-02-09 00:40:2411257 EXPECT_EQ(tests[i].expected_group_name,
11258 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:3111259 }
11260}
11261
bncd16676a2016-07-20 16:23:0111262TEST_F(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:2711263 HttpRequestInfo request;
11264 request.method = "GET";
bncce36dca22015-04-21 22:11:2311265 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011266 request.traffic_annotation =
11267 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2711268
Ramin Halavatica8d5252018-03-12 05:33:4911269 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
11270 "myproxy:70;foobar:80", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]b59ff372009-07-15 22:04:3211271
[email protected]69719062010-01-05 20:09:2111272 // This simulates failure resolving all hostnames; that means we will fail
11273 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:0711274 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:3211275
danakj1fd259a02016-04-16 03:17:0911276 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611277 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]9172a982009-06-06 00:30:2511278
[email protected]49639fa2011-12-20 23:22:4111279 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:2511280
tfarina42834112016-09-22 13:38:2011281 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111282 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9172a982009-06-06 00:30:2511283
[email protected]9172a982009-06-06 00:30:2511284 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111285 EXPECT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]9172a982009-06-06 00:30:2511286}
11287
Miriam Gershenson2a01b162018-03-22 22:54:4711288// LOAD_BYPASS_CACHE should trigger the host cache bypass.
11289TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh) {
[email protected]cb9bf6ca2011-01-28 13:15:2711290 // Issue a request, asking to bypass the cache(s).
maksim.sisov31452af2016-07-27 06:38:1011291 HttpRequestInfo request_info;
11292 request_info.method = "GET";
Miriam Gershenson2a01b162018-03-22 22:54:4711293 request_info.load_flags = LOAD_BYPASS_CACHE;
maksim.sisov31452af2016-07-27 06:38:1011294 request_info.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011295 request_info.traffic_annotation =
11296 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2711297
[email protected]a2c2fb92009-07-18 07:31:0411298 // Select a host resolver that does caching.
Jeremy Roman0579ed62017-08-29 15:56:1911299 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
[email protected]b59ff372009-07-15 22:04:3211300
danakj1fd259a02016-04-16 03:17:0911301 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611302 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3b9cca42009-06-16 01:08:2811303
bncce36dca22015-04-21 22:11:2311304 // Warm up the host cache so it has an entry for "www.example.org".
[email protected]3b9cca42009-06-16 01:08:2811305 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:2911306 TestCompletionCallback callback;
maksim.sisov31452af2016-07-27 06:38:1011307 std::unique_ptr<HostResolver::Request> request1;
[email protected]bb88e1d32013-05-03 23:11:0711308 int rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:2311309 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:1011310 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request1,
tfarina42834112016-09-22 13:38:2011311 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111312 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4711313 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111314 EXPECT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:2811315
11316 // Verify that it was added to host cache, by doing a subsequent async lookup
11317 // and confirming it completes synchronously.
maksim.sisov31452af2016-07-27 06:38:1011318 std::unique_ptr<HostResolver::Request> request2;
[email protected]bb88e1d32013-05-03 23:11:0711319 rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:2311320 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:1011321 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request2,
tfarina42834112016-09-22 13:38:2011322 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111323 ASSERT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:2811324
bncce36dca22015-04-21 22:11:2311325 // Inject a failure the next time that "www.example.org" is resolved. This way
[email protected]3b9cca42009-06-16 01:08:2811326 // we can tell if the next lookup hit the cache, or the "network".
11327 // (cache --> success, "network" --> failure).
bncce36dca22015-04-21 22:11:2311328 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.example.org");
[email protected]3b9cca42009-06-16 01:08:2811329
11330 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
11331 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:0611332 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
Ryan Sleevib8d7ea02018-05-07 20:01:0111333 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711334 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:2811335
[email protected]3b9cca42009-06-16 01:08:2811336 // Run the request.
tfarina42834112016-09-22 13:38:2011337 rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111338 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]49639fa2011-12-20 23:22:4111339 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:2811340
11341 // If we bypassed the cache, we would have gotten a failure while resolving
bncce36dca22015-04-21 22:11:2311342 // "www.example.org".
robpercival214763f2016-07-01 23:27:0111343 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]3b9cca42009-06-16 01:08:2811344}
11345
[email protected]0877e3d2009-10-17 22:29:5711346// Make sure we can handle an error when writing the request.
bncd16676a2016-07-20 16:23:0111347TEST_F(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:5711348 HttpRequestInfo request;
11349 request.method = "GET";
11350 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:1011351 request.traffic_annotation =
11352 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5711353
11354 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:0611355 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:5711356 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111357 StaticSocketDataProvider data(base::span<MockRead>(), write_failure);
[email protected]bb88e1d32013-05-03 23:11:0711358 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:0911359 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5711360
[email protected]49639fa2011-12-20 23:22:4111361 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5711362
bnc691fda62016-08-12 00:43:1611363 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5711364
tfarina42834112016-09-22 13:38:2011365 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111366 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5711367
11368 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111369 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:5911370
11371 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1611372 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5911373 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:5711374}
11375
zmo9528c9f42015-08-04 22:12:0811376// Check that a connection closed after the start of the headers finishes ok.
bncd16676a2016-07-20 16:23:0111377TEST_F(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:5711378 HttpRequestInfo request;
11379 request.method = "GET";
11380 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:1011381 request.traffic_annotation =
11382 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5711383
11384 MockRead data_reads[] = {
11385 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:0611386 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:5711387 };
11388
Ryan Sleevib8d7ea02018-05-07 20:01:0111389 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711390 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:0911391 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5711392
[email protected]49639fa2011-12-20 23:22:4111393 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5711394
bnc691fda62016-08-12 00:43:1611395 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5711396
tfarina42834112016-09-22 13:38:2011397 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111398 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5711399
11400 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111401 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:0811402
bnc691fda62016-08-12 00:43:1611403 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211404 ASSERT_TRUE(response);
zmo9528c9f42015-08-04 22:12:0811405
wezca1070932016-05-26 20:30:5211406 EXPECT_TRUE(response->headers);
zmo9528c9f42015-08-04 22:12:0811407 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
11408
11409 std::string response_data;
bnc691fda62016-08-12 00:43:1611410 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0111411 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:0811412 EXPECT_EQ("", response_data);
ttuttled9dbc652015-09-29 20:00:5911413
11414 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1611415 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5911416 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:5711417}
11418
11419// Make sure that a dropped connection while draining the body for auth
11420// restart does the right thing.
bncd16676a2016-07-20 16:23:0111421TEST_F(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:5711422 HttpRequestInfo request;
11423 request.method = "GET";
bncce36dca22015-04-21 22:11:2311424 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011425 request.traffic_annotation =
11426 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5711427
11428 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2311429 MockWrite(
11430 "GET / HTTP/1.1\r\n"
11431 "Host: www.example.org\r\n"
11432 "Connection: keep-alive\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:5711433 };
11434
11435 MockRead data_reads1[] = {
11436 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
11437 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
11438 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11439 MockRead("Content-Length: 14\r\n\r\n"),
11440 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:0611441 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:5711442 };
11443
Ryan Sleevib8d7ea02018-05-07 20:01:0111444 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:0711445 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:5711446
bnc691fda62016-08-12 00:43:1611447 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0877e3d2009-10-17 22:29:5711448 // be issuing -- the final header line contains the credentials.
11449 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:2311450 MockWrite(
11451 "GET / HTTP/1.1\r\n"
11452 "Host: www.example.org\r\n"
11453 "Connection: keep-alive\r\n"
11454 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:5711455 };
11456
11457 // Lastly, the server responds with the actual content.
11458 MockRead data_reads2[] = {
11459 MockRead("HTTP/1.1 200 OK\r\n"),
11460 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11461 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0611462 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:5711463 };
11464
Ryan Sleevib8d7ea02018-05-07 20:01:0111465 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:0711466 session_deps_.socket_factory->AddSocketDataProvider(&data2);
danakj1fd259a02016-04-16 03:17:0911467 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5711468
[email protected]49639fa2011-12-20 23:22:4111469 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:5711470
bnc691fda62016-08-12 00:43:1611471 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5011472
tfarina42834112016-09-22 13:38:2011473 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111474 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5711475
11476 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0111477 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:5711478
bnc691fda62016-08-12 00:43:1611479 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211480 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0411481 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:5711482
[email protected]49639fa2011-12-20 23:22:4111483 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:5711484
bnc691fda62016-08-12 00:43:1611485 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:0111486 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5711487
11488 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0111489 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:5711490
bnc691fda62016-08-12 00:43:1611491 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211492 ASSERT_TRUE(response);
11493 EXPECT_FALSE(response->auth_challenge);
[email protected]0877e3d2009-10-17 22:29:5711494 EXPECT_EQ(100, response->headers->GetContentLength());
11495}
11496
11497// Test HTTPS connections going through a proxy that sends extra data.
bncd16676a2016-07-20 16:23:0111498TEST_F(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
Ramin Halavatica8d5252018-03-12 05:33:4911499 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
11500 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5711501
11502 HttpRequestInfo request;
11503 request.method = "GET";
bncce36dca22015-04-21 22:11:2311504 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011505 request.traffic_annotation =
11506 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5711507
11508 MockRead proxy_reads[] = {
11509 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:0611510 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:5711511 };
11512
Ryan Sleevib8d7ea02018-05-07 20:01:0111513 StaticSocketDataProvider data(proxy_reads, base::span<MockWrite>());
[email protected]8ddf8322012-02-23 18:08:0611514 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:5711515
[email protected]bb88e1d32013-05-03 23:11:0711516 session_deps_.socket_factory->AddSocketDataProvider(&data);
11517 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:5711518
[email protected]49639fa2011-12-20 23:22:4111519 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5711520
[email protected]bb88e1d32013-05-03 23:11:0711521 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:5711522
danakj1fd259a02016-04-16 03:17:0911523 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611524 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5711525
tfarina42834112016-09-22 13:38:2011526 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111527 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5711528
11529 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111530 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]0877e3d2009-10-17 22:29:5711531}
11532
bncd16676a2016-07-20 16:23:0111533TEST_F(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:4611534 HttpRequestInfo request;
11535 request.method = "GET";
bncce36dca22015-04-21 22:11:2311536 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011537 request.traffic_annotation =
11538 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]9492e4a2010-02-24 00:58:4611539
danakj1fd259a02016-04-16 03:17:0911540 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611541 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2711542
[email protected]e22e1362009-11-23 21:31:1211543 MockRead data_reads[] = {
11544 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0611545 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:1211546 };
[email protected]9492e4a2010-02-24 00:58:4611547
Ryan Sleevib8d7ea02018-05-07 20:01:0111548 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711549 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:4611550
[email protected]49639fa2011-12-20 23:22:4111551 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:4611552
tfarina42834112016-09-22 13:38:2011553 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111554 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9492e4a2010-02-24 00:58:4611555
robpercival214763f2016-07-01 23:27:0111556 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]9492e4a2010-02-24 00:58:4611557
bnc691fda62016-08-12 00:43:1611558 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211559 ASSERT_TRUE(response);
[email protected]9492e4a2010-02-24 00:58:4611560
wezca1070932016-05-26 20:30:5211561 EXPECT_TRUE(response->headers);
[email protected]9492e4a2010-02-24 00:58:4611562 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
11563
11564 std::string response_data;
bnc691fda62016-08-12 00:43:1611565 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0111566 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]e22e1362009-11-23 21:31:1211567}
11568
bncd16676a2016-07-20 16:23:0111569TEST_F(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:1511570 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:5211571 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
avibf0746c2015-12-09 19:53:1411572 const uint64_t kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:2111573 UploadFileElementReader::ScopedOverridingContentLengthForTests
11574 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:3311575
danakj1fd259a02016-04-16 03:17:0911576 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:1911577 element_readers.push_back(std::make_unique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:1411578 base::ThreadTaskRunnerHandle::Get().get(), temp_file_path, 0,
ricea2deef682016-09-09 08:04:0711579 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:2211580 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:2711581
11582 HttpRequestInfo request;
11583 request.method = "POST";
bncce36dca22015-04-21 22:11:2311584 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:2711585 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1011586 request.traffic_annotation =
11587 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]329b68b2012-11-14 17:54:2711588
danakj1fd259a02016-04-16 03:17:0911589 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611590 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]95d88ffe2010-02-04 21:25:3311591
11592 MockRead data_reads[] = {
11593 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
11594 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611595 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:3311596 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111597 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711598 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:3311599
[email protected]49639fa2011-12-20 23:22:4111600 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:3311601
tfarina42834112016-09-22 13:38:2011602 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111603 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]95d88ffe2010-02-04 21:25:3311604
11605 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111606 EXPECT_THAT(rv, IsError(ERR_UPLOAD_FILE_CHANGED));
[email protected]95d88ffe2010-02-04 21:25:3311607
bnc691fda62016-08-12 00:43:1611608 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211609 ASSERT_TRUE(response);
[email protected]95d88ffe2010-02-04 21:25:3311610
maksim.sisove869bf52016-06-23 17:11:5211611 EXPECT_FALSE(response->headers);
[email protected]95d88ffe2010-02-04 21:25:3311612
[email protected]dd3aa792013-07-16 19:10:2311613 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:3311614}
11615
bncd16676a2016-07-20 16:23:0111616TEST_F(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:1511617 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:5211618 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:3611619 std::string temp_file_content("Unreadable file.");
lazyboy8df84fc2017-04-12 02:12:4811620 ASSERT_EQ(static_cast<int>(temp_file_content.length()),
11621 base::WriteFile(temp_file, temp_file_content.c_str(),
11622 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:1111623 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:3611624
danakj1fd259a02016-04-16 03:17:0911625 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:1911626 element_readers.push_back(std::make_unique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:1411627 base::ThreadTaskRunnerHandle::Get().get(), temp_file, 0,
ricea2deef682016-09-09 08:04:0711628 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:2211629 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:2711630
11631 HttpRequestInfo request;
11632 request.method = "POST";
bncce36dca22015-04-21 22:11:2311633 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:2711634 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1011635 request.traffic_annotation =
11636 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]329b68b2012-11-14 17:54:2711637
[email protected]999dd8c2013-11-12 06:45:5411638 // If we try to upload an unreadable file, the transaction should fail.
danakj1fd259a02016-04-16 03:17:0911639 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611640 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]6624b4622010-03-29 19:58:3611641
Ryan Sleevib8d7ea02018-05-07 20:01:0111642 StaticSocketDataProvider data;
[email protected]bb88e1d32013-05-03 23:11:0711643 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:3611644
[email protected]49639fa2011-12-20 23:22:4111645 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:3611646
tfarina42834112016-09-22 13:38:2011647 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111648 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6624b4622010-03-29 19:58:3611649
11650 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111651 EXPECT_THAT(rv, IsError(ERR_ACCESS_DENIED));
[email protected]6624b4622010-03-29 19:58:3611652
[email protected]dd3aa792013-07-16 19:10:2311653 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:3611654}
11655
bncd16676a2016-07-20 16:23:0111656TEST_F(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
[email protected]02cad5d2013-10-02 08:14:0311657 class FakeUploadElementReader : public UploadElementReader {
11658 public:
Chris Watkins7a41d3552017-12-01 02:13:2711659 FakeUploadElementReader() = default;
11660 ~FakeUploadElementReader() override = default;
[email protected]02cad5d2013-10-02 08:14:0311661
Matt Menkecc1d3a902018-02-05 18:27:3311662 CompletionOnceCallback TakeCallback() { return std::move(callback_); }
[email protected]02cad5d2013-10-02 08:14:0311663
11664 // UploadElementReader overrides:
Matt Menkecc1d3a902018-02-05 18:27:3311665 int Init(CompletionOnceCallback callback) override {
11666 callback_ = std::move(callback);
[email protected]02cad5d2013-10-02 08:14:0311667 return ERR_IO_PENDING;
11668 }
avibf0746c2015-12-09 19:53:1411669 uint64_t GetContentLength() const override { return 0; }
11670 uint64_t BytesRemaining() const override { return 0; }
dchengb03027d2014-10-21 12:00:2011671 int Read(IOBuffer* buf,
11672 int buf_length,
Matt Menkecc1d3a902018-02-05 18:27:3311673 CompletionOnceCallback callback) override {
[email protected]02cad5d2013-10-02 08:14:0311674 return ERR_FAILED;
11675 }
11676
11677 private:
Matt Menkecc1d3a902018-02-05 18:27:3311678 CompletionOnceCallback callback_;
[email protected]02cad5d2013-10-02 08:14:0311679 };
11680
11681 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
danakj1fd259a02016-04-16 03:17:0911682 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
11683 element_readers.push_back(base::WrapUnique(fake_reader));
olli.raula6df48b2a2015-11-26 07:40:2211684 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02cad5d2013-10-02 08:14:0311685
11686 HttpRequestInfo request;
11687 request.method = "POST";
bncce36dca22015-04-21 22:11:2311688 request.url = GURL("http://www.example.org/upload");
[email protected]02cad5d2013-10-02 08:14:0311689 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1011690 request.traffic_annotation =
11691 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02cad5d2013-10-02 08:14:0311692
danakj1fd259a02016-04-16 03:17:0911693 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5811694 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1911695 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]02cad5d2013-10-02 08:14:0311696
11697 StaticSocketDataProvider data;
11698 session_deps_.socket_factory->AddSocketDataProvider(&data);
11699
11700 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2011701 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111702 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
fdoray92e35a72016-06-10 15:54:5511703 base::RunLoop().RunUntilIdle();
[email protected]02cad5d2013-10-02 08:14:0311704
11705 // Transaction is pending on request body initialization.
Matt Menkecc1d3a902018-02-05 18:27:3311706 CompletionOnceCallback init_callback = fake_reader->TakeCallback();
11707 ASSERT_FALSE(init_callback.is_null());
[email protected]02cad5d2013-10-02 08:14:0311708
11709 // Return Init()'s result after the transaction gets destroyed.
11710 trans.reset();
Matt Menkecc1d3a902018-02-05 18:27:3311711 std::move(init_callback).Run(OK); // Should not crash.
[email protected]02cad5d2013-10-02 08:14:0311712}
11713
[email protected]aeefc9e82010-02-19 16:18:2711714// Tests that changes to Auth realms are treated like auth rejections.
bncd16676a2016-07-20 16:23:0111715TEST_F(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:2711716 HttpRequestInfo request;
11717 request.method = "GET";
bncce36dca22015-04-21 22:11:2311718 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011719 request.traffic_annotation =
11720 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]aeefc9e82010-02-19 16:18:2711721
11722 // First transaction will request a resource and receive a Basic challenge
11723 // with realm="first_realm".
11724 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2311725 MockWrite(
11726 "GET / HTTP/1.1\r\n"
11727 "Host: www.example.org\r\n"
11728 "Connection: keep-alive\r\n"
11729 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2711730 };
11731 MockRead data_reads1[] = {
11732 MockRead("HTTP/1.1 401 Unauthorized\r\n"
11733 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
11734 "\r\n"),
11735 };
11736
bnc691fda62016-08-12 00:43:1611737 // After calling trans.RestartWithAuth(), provide an Authentication header
[email protected]aeefc9e82010-02-19 16:18:2711738 // for first_realm. The server will reject and provide a challenge with
11739 // second_realm.
11740 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:2311741 MockWrite(
11742 "GET / HTTP/1.1\r\n"
11743 "Host: www.example.org\r\n"
11744 "Connection: keep-alive\r\n"
11745 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
11746 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2711747 };
11748 MockRead data_reads2[] = {
11749 MockRead("HTTP/1.1 401 Unauthorized\r\n"
11750 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
11751 "\r\n"),
11752 };
11753
11754 // This again fails, and goes back to first_realm. Make sure that the
11755 // entry is removed from cache.
11756 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:2311757 MockWrite(
11758 "GET / HTTP/1.1\r\n"
11759 "Host: www.example.org\r\n"
11760 "Connection: keep-alive\r\n"
11761 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
11762 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2711763 };
11764 MockRead data_reads3[] = {
11765 MockRead("HTTP/1.1 401 Unauthorized\r\n"
11766 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
11767 "\r\n"),
11768 };
11769
11770 // Try one last time (with the correct password) and get the resource.
11771 MockWrite data_writes4[] = {
bncce36dca22015-04-21 22:11:2311772 MockWrite(
11773 "GET / HTTP/1.1\r\n"
11774 "Host: www.example.org\r\n"
11775 "Connection: keep-alive\r\n"
11776 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
11777 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2711778 };
11779 MockRead data_reads4[] = {
11780 MockRead("HTTP/1.1 200 OK\r\n"
11781 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:5011782 "Content-Length: 5\r\n"
11783 "\r\n"
11784 "hello"),
[email protected]aeefc9e82010-02-19 16:18:2711785 };
11786
Ryan Sleevib8d7ea02018-05-07 20:01:0111787 StaticSocketDataProvider data1(data_reads1, data_writes1);
11788 StaticSocketDataProvider data2(data_reads2, data_writes2);
11789 StaticSocketDataProvider data3(data_reads3, data_writes3);
11790 StaticSocketDataProvider data4(data_reads4, data_writes4);
[email protected]bb88e1d32013-05-03 23:11:0711791 session_deps_.socket_factory->AddSocketDataProvider(&data1);
11792 session_deps_.socket_factory->AddSocketDataProvider(&data2);
11793 session_deps_.socket_factory->AddSocketDataProvider(&data3);
11794 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:2711795
[email protected]49639fa2011-12-20 23:22:4111796 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:2711797
danakj1fd259a02016-04-16 03:17:0911798 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611799 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5011800
[email protected]aeefc9e82010-02-19 16:18:2711801 // Issue the first request with Authorize headers. There should be a
11802 // password prompt for first_realm waiting to be filled in after the
11803 // transaction completes.
tfarina42834112016-09-22 13:38:2011804 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111805 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2711806 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0111807 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1611808 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211809 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0411810 const AuthChallengeInfo* challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5211811 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0411812 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4311813 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0411814 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1911815 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2711816
11817 // Issue the second request with an incorrect password. There should be a
11818 // password prompt for second_realm waiting to be filled in after the
11819 // transaction completes.
[email protected]49639fa2011-12-20 23:22:4111820 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:1611821 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBaz),
11822 callback2.callback());
robpercival214763f2016-07-01 23:27:0111823 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2711824 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0111825 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1611826 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211827 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0411828 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5211829 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0411830 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4311831 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0411832 EXPECT_EQ("second_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1911833 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2711834
11835 // Issue the third request with another incorrect password. There should be
11836 // a password prompt for first_realm waiting to be filled in. If the password
11837 // prompt is not present, it indicates that the HttpAuthCacheEntry for
11838 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:4111839 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:1611840 rv = trans.RestartWithAuth(AuthCredentials(kSecond, kFou),
11841 callback3.callback());
robpercival214763f2016-07-01 23:27:0111842 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2711843 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:0111844 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1611845 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211846 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0411847 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5211848 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0411849 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4311850 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0411851 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1911852 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2711853
11854 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:4111855 TestCompletionCallback callback4;
bnc691fda62016-08-12 00:43:1611856 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBar),
11857 callback4.callback());
robpercival214763f2016-07-01 23:27:0111858 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2711859 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:0111860 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1611861 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211862 ASSERT_TRUE(response);
11863 EXPECT_FALSE(response->auth_challenge);
[email protected]aeefc9e82010-02-19 16:18:2711864}
11865
Bence Béky230ac612017-08-30 19:17:0811866// Regression test for https://crbug.com/754395.
11867TEST_F(HttpNetworkTransactionTest, IgnoreAltSvcWithInvalidCert) {
11868 MockRead data_reads[] = {
11869 MockRead("HTTP/1.1 200 OK\r\n"),
11870 MockRead(kAlternativeServiceHttpHeader),
11871 MockRead("\r\n"),
11872 MockRead("hello world"),
11873 MockRead(SYNCHRONOUS, OK),
11874 };
11875
11876 HttpRequestInfo request;
11877 request.method = "GET";
11878 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011879 request.traffic_annotation =
11880 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Béky230ac612017-08-30 19:17:0811881
Ryan Sleevib8d7ea02018-05-07 20:01:0111882 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
Bence Béky230ac612017-08-30 19:17:0811883 session_deps_.socket_factory->AddSocketDataProvider(&data);
11884
11885 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911886 ssl.ssl_info.cert =
11887 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11888 ASSERT_TRUE(ssl.ssl_info.cert);
11889 ssl.ssl_info.cert_status = CERT_STATUS_COMMON_NAME_INVALID;
Bence Béky230ac612017-08-30 19:17:0811890 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11891
11892 TestCompletionCallback callback;
11893
11894 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11895 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11896
11897 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
11898 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11899
11900 url::SchemeHostPort test_server(request.url);
11901 HttpServerProperties* http_server_properties =
11902 session->http_server_properties();
11903 EXPECT_TRUE(
11904 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
11905
11906 EXPECT_THAT(callback.WaitForResult(), IsOk());
11907
11908 const HttpResponseInfo* response = trans.GetResponseInfo();
11909 ASSERT_TRUE(response);
11910 ASSERT_TRUE(response->headers);
11911 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11912 EXPECT_FALSE(response->was_fetched_via_spdy);
11913 EXPECT_FALSE(response->was_alpn_negotiated);
11914
11915 std::string response_data;
11916 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
11917 EXPECT_EQ("hello world", response_data);
11918
11919 EXPECT_TRUE(
11920 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
11921}
11922
bncd16676a2016-07-20 16:23:0111923TEST_F(HttpNetworkTransactionTest, HonorAlternativeServiceHeader) {
bncc958faa2015-07-31 18:14:5211924 MockRead data_reads[] = {
11925 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311926 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211927 MockRead("\r\n"),
11928 MockRead("hello world"),
11929 MockRead(SYNCHRONOUS, OK),
11930 };
11931
11932 HttpRequestInfo request;
11933 request.method = "GET";
bncb26024382016-06-29 02:39:4511934 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011935 request.traffic_annotation =
11936 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bncc958faa2015-07-31 18:14:5211937
Ryan Sleevib8d7ea02018-05-07 20:01:0111938 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:5211939 session_deps_.socket_factory->AddSocketDataProvider(&data);
11940
bncb26024382016-06-29 02:39:4511941 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911942 ssl.ssl_info.cert =
11943 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11944 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4511945 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11946
bncc958faa2015-07-31 18:14:5211947 TestCompletionCallback callback;
11948
danakj1fd259a02016-04-16 03:17:0911949 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611950 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5211951
tfarina42834112016-09-22 13:38:2011952 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111953 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5211954
bncb26024382016-06-29 02:39:4511955 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4011956 HttpServerProperties* http_server_properties =
11957 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3411958 EXPECT_TRUE(
11959 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5211960
robpercival214763f2016-07-01 23:27:0111961 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5211962
bnc691fda62016-08-12 00:43:1611963 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211964 ASSERT_TRUE(response);
11965 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5211966 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11967 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211968 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5211969
11970 std::string response_data;
bnc691fda62016-08-12 00:43:1611971 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5211972 EXPECT_EQ("hello world", response_data);
11973
zhongyic4de03032017-05-19 04:07:3411974 AlternativeServiceInfoVector alternative_service_info_vector =
11975 http_server_properties->GetAlternativeServiceInfos(test_server);
11976 ASSERT_EQ(1u, alternative_service_info_vector.size());
11977 AlternativeService alternative_service(kProtoHTTP2, "mail.example.org", 443);
11978 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5411979 alternative_service_info_vector[0].alternative_service());
bncc958faa2015-07-31 18:14:5211980}
11981
bnce3dd56f2016-06-01 10:37:1111982// Regression test for https://crbug.com/615497.
bncd16676a2016-07-20 16:23:0111983TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1111984 DoNotParseAlternativeServiceHeaderOnInsecureRequest) {
bnce3dd56f2016-06-01 10:37:1111985 MockRead data_reads[] = {
11986 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311987 MockRead(kAlternativeServiceHttpHeader),
bnce3dd56f2016-06-01 10:37:1111988 MockRead("\r\n"),
11989 MockRead("hello world"),
11990 MockRead(SYNCHRONOUS, OK),
11991 };
11992
11993 HttpRequestInfo request;
11994 request.method = "GET";
11995 request.url = GURL("http://www.example.org/");
11996 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1011997 request.traffic_annotation =
11998 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnce3dd56f2016-06-01 10:37:1111999
Ryan Sleevib8d7ea02018-05-07 20:01:0112000 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
bnce3dd56f2016-06-01 10:37:1112001 session_deps_.socket_factory->AddSocketDataProvider(&data);
12002
12003 TestCompletionCallback callback;
12004
12005 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1612006 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1112007
12008 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4012009 HttpServerProperties* http_server_properties =
12010 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3412011 EXPECT_TRUE(
12012 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1112013
tfarina42834112016-09-22 13:38:2012014 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112015 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12016 EXPECT_THAT(callback.WaitForResult(), IsOk());
bnce3dd56f2016-06-01 10:37:1112017
bnc691fda62016-08-12 00:43:1612018 const HttpResponseInfo* response = trans.GetResponseInfo();
bnce3dd56f2016-06-01 10:37:1112019 ASSERT_TRUE(response);
12020 ASSERT_TRUE(response->headers);
12021 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12022 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212023 EXPECT_FALSE(response->was_alpn_negotiated);
bnce3dd56f2016-06-01 10:37:1112024
12025 std::string response_data;
bnc691fda62016-08-12 00:43:1612026 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnce3dd56f2016-06-01 10:37:1112027 EXPECT_EQ("hello world", response_data);
12028
zhongyic4de03032017-05-19 04:07:3412029 EXPECT_TRUE(
12030 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1112031}
12032
bnca86731e2017-04-17 12:31:2812033// HTTP/2 Alternative Services should be disabled by default.
bnc8bef8da22016-05-30 01:28:2512034// TODO(bnc): Remove when https://crbug.com/615413 is fixed.
bncd16676a2016-07-20 16:23:0112035TEST_F(HttpNetworkTransactionTest,
bnc8bef8da22016-05-30 01:28:2512036 DisableHTTP2AlternativeServicesWithDifferentHost) {
bnca86731e2017-04-17 12:31:2812037 session_deps_.enable_http2_alternative_service = false;
bncb26024382016-06-29 02:39:4512038
bnc8bef8da22016-05-30 01:28:2512039 HttpRequestInfo request;
12040 request.method = "GET";
bncb26024382016-06-29 02:39:4512041 request.url = GURL("https://www.example.org/");
bnc8bef8da22016-05-30 01:28:2512042 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1012043 request.traffic_annotation =
12044 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8bef8da22016-05-30 01:28:2512045
12046 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
12047 StaticSocketDataProvider first_data;
12048 first_data.set_connect_data(mock_connect);
12049 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4512050 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612051 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512052 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
bnc8bef8da22016-05-30 01:28:2512053
12054 MockRead data_reads[] = {
12055 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
12056 MockRead(ASYNC, OK),
12057 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112058 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
bnc8bef8da22016-05-30 01:28:2512059 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
12060
12061 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12062
bnc525e175a2016-06-20 12:36:4012063 HttpServerProperties* http_server_properties =
bnc8bef8da22016-05-30 01:28:2512064 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2112065 AlternativeService alternative_service(kProtoHTTP2, "different.example.org",
12066 444);
bnc8bef8da22016-05-30 01:28:2512067 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112068 http_server_properties->SetHttp2AlternativeService(
bnc8bef8da22016-05-30 01:28:2512069 url::SchemeHostPort(request.url), alternative_service, expiration);
12070
bnc691fda62016-08-12 00:43:1612071 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc8bef8da22016-05-30 01:28:2512072 TestCompletionCallback callback;
12073
tfarina42834112016-09-22 13:38:2012074 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc8bef8da22016-05-30 01:28:2512075 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0112076 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc8bef8da22016-05-30 01:28:2512077}
12078
bnce3dd56f2016-06-01 10:37:1112079// Regression test for https://crbug.com/615497:
12080// Alternative Services should be disabled for http origin.
bncd16676a2016-07-20 16:23:0112081TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1112082 DisableAlternativeServicesForInsecureOrigin) {
bnce3dd56f2016-06-01 10:37:1112083 HttpRequestInfo request;
12084 request.method = "GET";
12085 request.url = GURL("http://www.example.org/");
12086 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1012087 request.traffic_annotation =
12088 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnce3dd56f2016-06-01 10:37:1112089
12090 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
12091 StaticSocketDataProvider first_data;
12092 first_data.set_connect_data(mock_connect);
12093 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
12094
12095 MockRead data_reads[] = {
12096 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
12097 MockRead(ASYNC, OK),
12098 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112099 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
bnce3dd56f2016-06-01 10:37:1112100 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
12101
12102 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12103
bnc525e175a2016-06-20 12:36:4012104 HttpServerProperties* http_server_properties =
bnce3dd56f2016-06-01 10:37:1112105 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2112106 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnce3dd56f2016-06-01 10:37:1112107 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112108 http_server_properties->SetHttp2AlternativeService(
bnce3dd56f2016-06-01 10:37:1112109 url::SchemeHostPort(request.url), alternative_service, expiration);
12110
bnc691fda62016-08-12 00:43:1612111 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1112112 TestCompletionCallback callback;
12113
tfarina42834112016-09-22 13:38:2012114 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnce3dd56f2016-06-01 10:37:1112115 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0112116 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnce3dd56f2016-06-01 10:37:1112117}
12118
bncd16676a2016-07-20 16:23:0112119TEST_F(HttpNetworkTransactionTest, ClearAlternativeServices) {
bnc4f575852015-10-14 18:35:0812120 // Set an alternative service for origin.
danakj1fd259a02016-04-16 03:17:0912121 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4012122 HttpServerProperties* http_server_properties =
12123 session->http_server_properties();
bncb26024382016-06-29 02:39:4512124 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc3472afd2016-11-17 15:27:2112125 AlternativeService alternative_service(kProtoQUIC, "", 80);
bnc4f575852015-10-14 18:35:0812126 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112127 http_server_properties->SetQuicAlternativeService(
12128 test_server, alternative_service, expiration,
12129 session->params().quic_supported_versions);
zhongyic4de03032017-05-19 04:07:3412130 EXPECT_EQ(
12131 1u,
12132 http_server_properties->GetAlternativeServiceInfos(test_server).size());
bnc4f575852015-10-14 18:35:0812133
12134 // Send a clear header.
12135 MockRead data_reads[] = {
12136 MockRead("HTTP/1.1 200 OK\r\n"),
12137 MockRead("Alt-Svc: clear\r\n"),
12138 MockRead("\r\n"),
12139 MockRead("hello world"),
12140 MockRead(SYNCHRONOUS, OK),
12141 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112142 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
bnc4f575852015-10-14 18:35:0812143 session_deps_.socket_factory->AddSocketDataProvider(&data);
12144
bncb26024382016-06-29 02:39:4512145 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4912146 ssl.ssl_info.cert =
12147 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
12148 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4512149 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12150
bnc4f575852015-10-14 18:35:0812151 HttpRequestInfo request;
12152 request.method = "GET";
bncb26024382016-06-29 02:39:4512153 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1012154 request.traffic_annotation =
12155 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc4f575852015-10-14 18:35:0812156
12157 TestCompletionCallback callback;
12158
bnc691fda62016-08-12 00:43:1612159 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc4f575852015-10-14 18:35:0812160
tfarina42834112016-09-22 13:38:2012161 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112162 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc4f575852015-10-14 18:35:0812163
bnc691fda62016-08-12 00:43:1612164 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212165 ASSERT_TRUE(response);
12166 ASSERT_TRUE(response->headers);
bnc4f575852015-10-14 18:35:0812167 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12168 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212169 EXPECT_FALSE(response->was_alpn_negotiated);
bnc4f575852015-10-14 18:35:0812170
12171 std::string response_data;
bnc691fda62016-08-12 00:43:1612172 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc4f575852015-10-14 18:35:0812173 EXPECT_EQ("hello world", response_data);
12174
zhongyic4de03032017-05-19 04:07:3412175 EXPECT_TRUE(
12176 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnc4f575852015-10-14 18:35:0812177}
12178
bncd16676a2016-07-20 16:23:0112179TEST_F(HttpNetworkTransactionTest, HonorMultipleAlternativeServiceHeaders) {
bncc958faa2015-07-31 18:14:5212180 MockRead data_reads[] = {
12181 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312182 MockRead("Alt-Svc: h2=\"www.example.com:443\","),
12183 MockRead("h2=\":1234\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:5212184 MockRead("hello world"),
12185 MockRead(SYNCHRONOUS, OK),
12186 };
12187
12188 HttpRequestInfo request;
12189 request.method = "GET";
bncb26024382016-06-29 02:39:4512190 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1012191 request.traffic_annotation =
12192 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bncc958faa2015-07-31 18:14:5212193
Ryan Sleevib8d7ea02018-05-07 20:01:0112194 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:5212195 session_deps_.socket_factory->AddSocketDataProvider(&data);
12196
bncb26024382016-06-29 02:39:4512197 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4912198 ssl.ssl_info.cert =
12199 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
12200 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4512201 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12202
bncc958faa2015-07-31 18:14:5212203 TestCompletionCallback callback;
12204
danakj1fd259a02016-04-16 03:17:0912205 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1612206 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5212207
tfarina42834112016-09-22 13:38:2012208 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112209 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5212210
bncb26024382016-06-29 02:39:4512211 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc525e175a2016-06-20 12:36:4012212 HttpServerProperties* http_server_properties =
12213 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3412214 EXPECT_TRUE(
12215 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5212216
robpercival214763f2016-07-01 23:27:0112217 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5212218
bnc691fda62016-08-12 00:43:1612219 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212220 ASSERT_TRUE(response);
12221 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5212222 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12223 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212224 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5212225
12226 std::string response_data;
bnc691fda62016-08-12 00:43:1612227 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5212228 EXPECT_EQ("hello world", response_data);
12229
zhongyic4de03032017-05-19 04:07:3412230 AlternativeServiceInfoVector alternative_service_info_vector =
12231 http_server_properties->GetAlternativeServiceInfos(test_server);
12232 ASSERT_EQ(2u, alternative_service_info_vector.size());
12233
12234 AlternativeService alternative_service(kProtoHTTP2, "www.example.com", 443);
12235 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5412236 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3412237 AlternativeService alternative_service_2(kProtoHTTP2, "www.example.org",
12238 1234);
12239 EXPECT_EQ(alternative_service_2,
zhongyi422ce352017-06-09 23:28:5412240 alternative_service_info_vector[1].alternative_service());
bncc958faa2015-07-31 18:14:5212241}
12242
bncd16676a2016-07-20 16:23:0112243TEST_F(HttpNetworkTransactionTest, IdentifyQuicBroken) {
zhongyi3d4a55e72016-04-22 20:36:4612244 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0212245 HostPortPair alternative("alternative.example.org", 443);
12246 std::string origin_url = "https://origin.example.org:443";
12247 std::string alternative_url = "https://alternative.example.org:443";
12248
12249 // Negotiate HTTP/1.1 with alternative.example.org.
12250 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612251 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0212252 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12253
12254 // HTTP/1.1 data for request.
12255 MockWrite http_writes[] = {
12256 MockWrite("GET / HTTP/1.1\r\n"
12257 "Host: alternative.example.org\r\n"
12258 "Connection: keep-alive\r\n\r\n"),
12259 };
12260
12261 MockRead http_reads[] = {
12262 MockRead("HTTP/1.1 200 OK\r\n"
12263 "Content-Type: text/html; charset=iso-8859-1\r\n"
12264 "Content-Length: 40\r\n\r\n"
12265 "first HTTP/1.1 response from alternative"),
12266 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112267 StaticSocketDataProvider http_data(http_reads, http_writes);
zhongyi48704c182015-12-07 07:52:0212268 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12269
12270 StaticSocketDataProvider data_refused;
12271 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
12272 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
12273
zhongyi3d4a55e72016-04-22 20:36:4612274 // Set up a QUIC alternative service for server.
danakj1fd259a02016-04-16 03:17:0912275 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4012276 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0212277 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2112278 AlternativeService alternative_service(kProtoQUIC, alternative);
zhongyi48704c182015-12-07 07:52:0212279 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112280 http_server_properties->SetQuicAlternativeService(
12281 server, alternative_service, expiration,
12282 HttpNetworkSession::Params().quic_supported_versions);
zhongyi48704c182015-12-07 07:52:0212283 // Mark the QUIC alternative service as broken.
12284 http_server_properties->MarkAlternativeServiceBroken(alternative_service);
12285
zhongyi48704c182015-12-07 07:52:0212286 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4612287 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0212288 request.method = "GET";
12289 request.url = GURL(origin_url);
Ramin Halavatib5e433e62018-02-07 07:41:1012290 request.traffic_annotation =
12291 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
12292
zhongyi48704c182015-12-07 07:52:0212293 TestCompletionCallback callback;
12294 NetErrorDetails details;
12295 EXPECT_FALSE(details.quic_broken);
12296
tfarina42834112016-09-22 13:38:2012297 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1612298 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0212299 EXPECT_TRUE(details.quic_broken);
12300}
12301
bncd16676a2016-07-20 16:23:0112302TEST_F(HttpNetworkTransactionTest, IdentifyQuicNotBroken) {
zhongyi3d4a55e72016-04-22 20:36:4612303 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0212304 HostPortPair alternative1("alternative1.example.org", 443);
12305 HostPortPair alternative2("alternative2.example.org", 443);
12306 std::string origin_url = "https://origin.example.org:443";
12307 std::string alternative_url1 = "https://alternative1.example.org:443";
12308 std::string alternative_url2 = "https://alternative2.example.org:443";
12309
12310 // Negotiate HTTP/1.1 with alternative1.example.org.
12311 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612312 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0212313 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12314
12315 // HTTP/1.1 data for request.
12316 MockWrite http_writes[] = {
12317 MockWrite("GET / HTTP/1.1\r\n"
12318 "Host: alternative1.example.org\r\n"
12319 "Connection: keep-alive\r\n\r\n"),
12320 };
12321
12322 MockRead http_reads[] = {
12323 MockRead("HTTP/1.1 200 OK\r\n"
12324 "Content-Type: text/html; charset=iso-8859-1\r\n"
12325 "Content-Length: 40\r\n\r\n"
12326 "first HTTP/1.1 response from alternative1"),
12327 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112328 StaticSocketDataProvider http_data(http_reads, http_writes);
zhongyi48704c182015-12-07 07:52:0212329 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12330
12331 StaticSocketDataProvider data_refused;
12332 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
12333 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
12334
danakj1fd259a02016-04-16 03:17:0912335 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4012336 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0212337 session->http_server_properties();
12338
zhongyi3d4a55e72016-04-22 20:36:4612339 // Set up two QUIC alternative services for server.
zhongyi48704c182015-12-07 07:52:0212340 AlternativeServiceInfoVector alternative_service_info_vector;
12341 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
12342
bnc3472afd2016-11-17 15:27:2112343 AlternativeService alternative_service1(kProtoQUIC, alternative1);
zhongyie537a002017-06-27 16:48:2112344 alternative_service_info_vector.push_back(
12345 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
12346 alternative_service1, expiration,
12347 session->params().quic_supported_versions));
bnc3472afd2016-11-17 15:27:2112348 AlternativeService alternative_service2(kProtoQUIC, alternative2);
zhongyie537a002017-06-27 16:48:2112349 alternative_service_info_vector.push_back(
12350 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
12351 alternative_service2, expiration,
12352 session->params().quic_supported_versions));
zhongyi48704c182015-12-07 07:52:0212353
12354 http_server_properties->SetAlternativeServices(
zhongyi3d4a55e72016-04-22 20:36:4612355 server, alternative_service_info_vector);
zhongyi48704c182015-12-07 07:52:0212356
12357 // Mark one of the QUIC alternative service as broken.
12358 http_server_properties->MarkAlternativeServiceBroken(alternative_service1);
zhongyic4de03032017-05-19 04:07:3412359 EXPECT_EQ(2u,
12360 http_server_properties->GetAlternativeServiceInfos(server).size());
zhongyi48704c182015-12-07 07:52:0212361
zhongyi48704c182015-12-07 07:52:0212362 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4612363 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0212364 request.method = "GET";
12365 request.url = GURL(origin_url);
Ramin Halavatib5e433e62018-02-07 07:41:1012366 request.traffic_annotation =
12367 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
12368
zhongyi48704c182015-12-07 07:52:0212369 TestCompletionCallback callback;
12370 NetErrorDetails details;
12371 EXPECT_FALSE(details.quic_broken);
12372
tfarina42834112016-09-22 13:38:2012373 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1612374 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0212375 EXPECT_FALSE(details.quic_broken);
12376}
12377
bncd16676a2016-07-20 16:23:0112378TEST_F(HttpNetworkTransactionTest, MarkBrokenAlternateProtocolAndFallback) {
[email protected]564b4912010-03-09 16:30:4212379 HttpRequestInfo request;
12380 request.method = "GET";
bncb26024382016-06-29 02:39:4512381 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1012382 request.traffic_annotation =
12383 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]564b4912010-03-09 16:30:4212384
[email protected]d973e99a2012-02-17 21:02:3612385 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:4212386 StaticSocketDataProvider first_data;
12387 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712388 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4512389 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612390 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512391 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]564b4912010-03-09 16:30:4212392
12393 MockRead data_reads[] = {
12394 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12395 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0612396 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:4212397 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112398 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712399 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:4212400
danakj1fd259a02016-04-16 03:17:0912401 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:4212402
bnc525e175a2016-06-20 12:36:4012403 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5312404 session->http_server_properties();
zhongyi3d4a55e72016-04-22 20:36:4612405 const url::SchemeHostPort server(request.url);
[email protected]3912662a32011-10-04 00:51:1112406 // Port must be < 1024, or the header will be ignored (since initial port was
12407 // port 80 (another restricted port).
zhongyie537a002017-06-27 16:48:2112408 // Port is ignored by MockConnect anyway.
12409 const AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12410 666);
bnc7dc7e1b42015-07-28 14:43:1212411 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112412 http_server_properties->SetHttp2AlternativeService(
12413 server, alternative_service, expiration);
[email protected]564b4912010-03-09 16:30:4212414
bnc691fda62016-08-12 00:43:1612415 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112416 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:4212417
tfarina42834112016-09-22 13:38:2012418 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112419 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12420 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]564b4912010-03-09 16:30:4212421
bnc691fda62016-08-12 00:43:1612422 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212423 ASSERT_TRUE(response);
12424 ASSERT_TRUE(response->headers);
[email protected]564b4912010-03-09 16:30:4212425 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12426
12427 std::string response_data;
bnc691fda62016-08-12 00:43:1612428 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]564b4912010-03-09 16:30:4212429 EXPECT_EQ("hello world", response_data);
12430
zhongyic4de03032017-05-19 04:07:3412431 const AlternativeServiceInfoVector alternative_service_info_vector =
12432 http_server_properties->GetAlternativeServiceInfos(server);
12433 ASSERT_EQ(1u, alternative_service_info_vector.size());
12434 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5412435 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3412436 EXPECT_TRUE(
12437 http_server_properties->IsAlternativeServiceBroken(alternative_service));
[email protected]564b4912010-03-09 16:30:4212438}
12439
bnc55ff9da2015-08-19 18:42:3512440// Ensure that we are not allowed to redirect traffic via an alternate protocol
12441// to an unrestricted (port >= 1024) when the original traffic was on a
12442// restricted port (port < 1024). Ensure that we can redirect in all other
12443// cases.
bncd16676a2016-07-20 16:23:0112444TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:1112445 HttpRequestInfo restricted_port_request;
12446 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4512447 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1112448 restricted_port_request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1012449 restricted_port_request.traffic_annotation =
12450 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1112451
[email protected]d973e99a2012-02-17 21:02:3612452 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1112453 StaticSocketDataProvider first_data;
12454 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712455 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1112456
12457 MockRead data_reads[] = {
12458 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12459 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0612460 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1112461 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112462 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712463 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4512464 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612465 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512466 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1112467
danakj1fd259a02016-04-16 03:17:0912468 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1112469
bnc525e175a2016-06-20 12:36:4012470 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5312471 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1112472 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2112473 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12474 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1212475 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112476 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4612477 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5012478 expiration);
[email protected]3912662a32011-10-04 00:51:1112479
bnc691fda62016-08-12 00:43:1612480 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112481 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1112482
tfarina42834112016-09-22 13:38:2012483 int rv = trans.Start(&restricted_port_request, callback.callback(),
12484 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112485 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1112486 // Invalid change to unrestricted port should fail.
robpercival214763f2016-07-01 23:27:0112487 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_REFUSED));
[email protected]c54c6962013-02-01 04:53:1912488}
[email protected]3912662a32011-10-04 00:51:1112489
bnc55ff9da2015-08-19 18:42:3512490// Ensure that we are allowed to redirect traffic via an alternate protocol to
12491// an unrestricted (port >= 1024) when the original traffic was on a restricted
12492// port (port < 1024) if we set |enable_user_alternate_protocol_ports|.
bncd16676a2016-07-20 16:23:0112493TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedPermitted) {
[email protected]bb88e1d32013-05-03 23:11:0712494 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:1912495
12496 HttpRequestInfo restricted_port_request;
12497 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4512498 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]c54c6962013-02-01 04:53:1912499 restricted_port_request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1012500 restricted_port_request.traffic_annotation =
12501 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]c54c6962013-02-01 04:53:1912502
12503 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
12504 StaticSocketDataProvider first_data;
12505 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712506 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:1912507
12508 MockRead data_reads[] = {
12509 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12510 MockRead("hello world"),
12511 MockRead(ASYNC, OK),
12512 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112513 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712514 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4512515 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612516 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512517 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]c54c6962013-02-01 04:53:1912518
danakj1fd259a02016-04-16 03:17:0912519 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:1912520
bnc525e175a2016-06-20 12:36:4012521 HttpServerProperties* http_server_properties =
[email protected]c54c6962013-02-01 04:53:1912522 session->http_server_properties();
12523 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2112524 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12525 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1212526 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112527 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4612528 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5012529 expiration);
[email protected]c54c6962013-02-01 04:53:1912530
bnc691fda62016-08-12 00:43:1612531 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]c54c6962013-02-01 04:53:1912532 TestCompletionCallback callback;
12533
tfarina42834112016-09-22 13:38:2012534 EXPECT_EQ(ERR_IO_PENDING,
12535 trans.Start(&restricted_port_request, callback.callback(),
12536 NetLogWithSource()));
[email protected]c54c6962013-02-01 04:53:1912537 // Change to unrestricted port should succeed.
robpercival214763f2016-07-01 23:27:0112538 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1112539}
12540
bnc55ff9da2015-08-19 18:42:3512541// Ensure that we are not allowed to redirect traffic via an alternate protocol
12542// to an unrestricted (port >= 1024) when the original traffic was on a
12543// restricted port (port < 1024). Ensure that we can redirect in all other
12544// cases.
bncd16676a2016-07-20 16:23:0112545TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:1112546 HttpRequestInfo restricted_port_request;
12547 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4512548 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1112549 restricted_port_request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1012550 restricted_port_request.traffic_annotation =
12551 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1112552
[email protected]d973e99a2012-02-17 21:02:3612553 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1112554 StaticSocketDataProvider first_data;
12555 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712556 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1112557
12558 MockRead data_reads[] = {
12559 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12560 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0612561 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1112562 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112563 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712564 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1112565
bncb26024382016-06-29 02:39:4512566 SSLSocketDataProvider ssl(ASYNC, OK);
12567 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12568
danakj1fd259a02016-04-16 03:17:0912569 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1112570
bnc525e175a2016-06-20 12:36:4012571 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5312572 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1112573 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2112574 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12575 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1212576 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112577 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4612578 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5012579 expiration);
[email protected]3912662a32011-10-04 00:51:1112580
bnc691fda62016-08-12 00:43:1612581 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112582 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1112583
tfarina42834112016-09-22 13:38:2012584 int rv = trans.Start(&restricted_port_request, callback.callback(),
12585 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112586 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1112587 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0112588 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1112589}
12590
bnc55ff9da2015-08-19 18:42:3512591// Ensure that we are not allowed to redirect traffic via an alternate protocol
12592// to an unrestricted (port >= 1024) when the original traffic was on a
12593// restricted port (port < 1024). Ensure that we can redirect in all other
12594// cases.
bncd16676a2016-07-20 16:23:0112595TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:1112596 HttpRequestInfo unrestricted_port_request;
12597 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4512598 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1112599 unrestricted_port_request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1012600 unrestricted_port_request.traffic_annotation =
12601 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1112602
[email protected]d973e99a2012-02-17 21:02:3612603 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1112604 StaticSocketDataProvider first_data;
12605 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712606 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1112607
12608 MockRead data_reads[] = {
12609 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12610 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0612611 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1112612 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112613 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712614 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4512615 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612616 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512617 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1112618
danakj1fd259a02016-04-16 03:17:0912619 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1112620
bnc525e175a2016-06-20 12:36:4012621 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5312622 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1112623 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2112624 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12625 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1212626 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112627 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4612628 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5012629 expiration);
[email protected]3912662a32011-10-04 00:51:1112630
bnc691fda62016-08-12 00:43:1612631 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112632 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1112633
bnc691fda62016-08-12 00:43:1612634 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2012635 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112636 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1112637 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0112638 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1112639}
12640
bnc55ff9da2015-08-19 18:42:3512641// Ensure that we are not allowed to redirect traffic via an alternate protocol
12642// to an unrestricted (port >= 1024) when the original traffic was on a
12643// restricted port (port < 1024). Ensure that we can redirect in all other
12644// cases.
bncd16676a2016-07-20 16:23:0112645TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:1112646 HttpRequestInfo unrestricted_port_request;
12647 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4512648 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1112649 unrestricted_port_request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1012650 unrestricted_port_request.traffic_annotation =
12651 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1112652
[email protected]d973e99a2012-02-17 21:02:3612653 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1112654 StaticSocketDataProvider first_data;
12655 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712656 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1112657
12658 MockRead data_reads[] = {
12659 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12660 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0612661 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1112662 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112663 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712664 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1112665
bncb26024382016-06-29 02:39:4512666 SSLSocketDataProvider ssl(ASYNC, OK);
12667 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12668
danakj1fd259a02016-04-16 03:17:0912669 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1112670
bnc525e175a2016-06-20 12:36:4012671 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5312672 session->http_server_properties();
bnc0bbb02622015-07-23 10:06:2212673 const int kUnrestrictedAlternatePort = 1025;
bnc3472afd2016-11-17 15:27:2112674 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12675 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1212676 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112677 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4612678 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5012679 expiration);
[email protected]3912662a32011-10-04 00:51:1112680
bnc691fda62016-08-12 00:43:1612681 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112682 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1112683
bnc691fda62016-08-12 00:43:1612684 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2012685 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112686 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1112687 // Valid change to an unrestricted port should pass.
robpercival214763f2016-07-01 23:27:0112688 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1112689}
12690
bnc55ff9da2015-08-19 18:42:3512691// Ensure that we are not allowed to redirect traffic via an alternate protocol
Xida Chen9bfe0b62018-04-24 19:52:2112692// to an unsafe port, and that we resume the second HttpStreamFactory::Job once
12693// the alternate protocol request fails.
bncd16676a2016-07-20 16:23:0112694TEST_F(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:0212695 HttpRequestInfo request;
12696 request.method = "GET";
bncce36dca22015-04-21 22:11:2312697 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1012698 request.traffic_annotation =
12699 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]eb6234e2012-01-19 01:50:0212700
12701 // The alternate protocol request will error out before we attempt to connect,
12702 // so only the standard HTTP request will try to connect.
12703 MockRead data_reads[] = {
12704 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12705 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0612706 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:0212707 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112708 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712709 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:0212710
danakj1fd259a02016-04-16 03:17:0912711 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:0212712
bnc525e175a2016-06-20 12:36:4012713 HttpServerProperties* http_server_properties =
[email protected]eb6234e2012-01-19 01:50:0212714 session->http_server_properties();
12715 const int kUnsafePort = 7;
bnc3472afd2016-11-17 15:27:2112716 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12717 kUnsafePort);
bnc7dc7e1b42015-07-28 14:43:1212718 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112719 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4612720 url::SchemeHostPort(request.url), alternative_service, expiration);
[email protected]eb6234e2012-01-19 01:50:0212721
bnc691fda62016-08-12 00:43:1612722 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]eb6234e2012-01-19 01:50:0212723 TestCompletionCallback callback;
12724
tfarina42834112016-09-22 13:38:2012725 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112726 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]eb6234e2012-01-19 01:50:0212727 // The HTTP request should succeed.
robpercival214763f2016-07-01 23:27:0112728 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb6234e2012-01-19 01:50:0212729
bnc691fda62016-08-12 00:43:1612730 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212731 ASSERT_TRUE(response);
12732 ASSERT_TRUE(response->headers);
[email protected]eb6234e2012-01-19 01:50:0212733 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12734
12735 std::string response_data;
bnc691fda62016-08-12 00:43:1612736 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]eb6234e2012-01-19 01:50:0212737 EXPECT_EQ("hello world", response_data);
12738}
12739
bncd16676a2016-07-20 16:23:0112740TEST_F(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]2ff8b312010-04-26 22:20:5412741 HttpRequestInfo request;
12742 request.method = "GET";
bncb26024382016-06-29 02:39:4512743 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1012744 request.traffic_annotation =
12745 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2ff8b312010-04-26 22:20:5412746
12747 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212748 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312749 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212750 MockRead("\r\n"),
12751 MockRead("hello world"),
12752 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
12753 MockRead(ASYNC, OK)};
[email protected]2ff8b312010-04-26 22:20:5412754
Ryan Sleevib8d7ea02018-05-07 20:01:0112755 StaticSocketDataProvider first_transaction(data_reads,
12756 base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712757 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4512758 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612759 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512760 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5412761
bnc032658ba2016-09-26 18:17:1512762 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5412763
Ryan Hamilton0239aac2018-05-19 00:03:1312764 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4512765 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4112766 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5412767
Ryan Hamilton0239aac2018-05-19 00:03:1312768 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
12769 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5412770 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4112771 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5412772 };
12773
Ryan Sleevib8d7ea02018-05-07 20:01:0112774 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0712775 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5412776
[email protected]d973e99a2012-02-17 21:02:3612777 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0112778 StaticSocketDataProvider hanging_non_alternate_protocol_socket;
[email protected]2d6728692011-03-12 01:39:5512779 hanging_non_alternate_protocol_socket.set_connect_data(
12780 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0712781 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5512782 &hanging_non_alternate_protocol_socket);
12783
[email protected]49639fa2011-12-20 23:22:4112784 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5412785
danakj1fd259a02016-04-16 03:17:0912786 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5812787 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1912788 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5412789
tfarina42834112016-09-22 13:38:2012790 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112791 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12792 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412793
12794 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212795 ASSERT_TRUE(response);
12796 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5412797 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12798
12799 std::string response_data;
robpercival214763f2016-07-01 23:27:0112800 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412801 EXPECT_EQ("hello world", response_data);
12802
bnc87dcefc2017-05-25 12:47:5812803 trans =
Jeremy Roman0579ed62017-08-29 15:56:1912804 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5412805
tfarina42834112016-09-22 13:38:2012806 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112807 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12808 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412809
12810 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212811 ASSERT_TRUE(response);
12812 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212813 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5312814 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212815 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5412816
robpercival214763f2016-07-01 23:27:0112817 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412818 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:5412819}
12820
bncd16676a2016-07-20 16:23:0112821TEST_F(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]2d6728692011-03-12 01:39:5512822 HttpRequestInfo request;
12823 request.method = "GET";
bncb26024382016-06-29 02:39:4512824 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1012825 request.traffic_annotation =
12826 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d6728692011-03-12 01:39:5512827
bncb26024382016-06-29 02:39:4512828 // First transaction receives Alt-Svc header over HTTP/1.1.
[email protected]2d6728692011-03-12 01:39:5512829 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212830 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312831 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212832 MockRead("\r\n"),
12833 MockRead("hello world"),
12834 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
12835 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5512836 };
12837
Ryan Sleevib8d7ea02018-05-07 20:01:0112838 StaticSocketDataProvider http11_data(data_reads, base::span<MockWrite>());
bncb26024382016-06-29 02:39:4512839 session_deps_.socket_factory->AddSocketDataProvider(&http11_data);
[email protected]2d6728692011-03-12 01:39:5512840
bncb26024382016-06-29 02:39:4512841 SSLSocketDataProvider ssl_http11(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4912842 ssl_http11.ssl_info.cert =
12843 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
12844 ASSERT_TRUE(ssl_http11.ssl_info.cert);
bncb26024382016-06-29 02:39:4512845 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
12846
12847 // Second transaction starts an alternative and a non-alternative Job.
12848 // Both sockets hang.
[email protected]d973e99a2012-02-17 21:02:3612849 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0112850 StaticSocketDataProvider hanging_socket1;
mmenkecc2298e2015-12-07 18:20:1812851 hanging_socket1.set_connect_data(never_finishing_connect);
mmenkecc2298e2015-12-07 18:20:1812852 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket1);
12853
Ryan Sleevib8d7ea02018-05-07 20:01:0112854 StaticSocketDataProvider hanging_socket2;
mmenkecc2298e2015-12-07 18:20:1812855 hanging_socket2.set_connect_data(never_finishing_connect);
12856 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket2);
[email protected]2d6728692011-03-12 01:39:5512857
bncb26024382016-06-29 02:39:4512858 // Third transaction starts an alternative and a non-alternative job.
12859 // The non-alternative job hangs, but the alternative one succeeds.
12860 // The second transaction, still pending, binds to this socket.
Ryan Hamilton0239aac2018-05-19 00:03:1312861 spdy::SpdySerializedFrame req1(
bncb26024382016-06-29 02:39:4512862 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1312863 spdy::SpdySerializedFrame req2(
bncb26024382016-06-29 02:39:4512864 spdy_util_.ConstructSpdyGet("https://www.example.org/", 3, LOWEST));
[email protected]2d6728692011-03-12 01:39:5512865 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4112866 CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
[email protected]2d6728692011-03-12 01:39:5512867 };
Ryan Hamilton0239aac2018-05-19 00:03:1312868 spdy::SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
12869 spdy::SpdySerializedFrame data1(spdy_util_.ConstructSpdyDataFrame(1, true));
12870 spdy::SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
12871 spdy::SpdySerializedFrame data2(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]2d6728692011-03-12 01:39:5512872 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4112873 CreateMockRead(resp1, 2), CreateMockRead(data1, 3),
12874 CreateMockRead(resp2, 4), CreateMockRead(data2, 5),
rch8e6c6c42015-05-01 14:05:1312875 MockRead(ASYNC, 0, 6),
[email protected]2d6728692011-03-12 01:39:5512876 };
12877
Ryan Sleevib8d7ea02018-05-07 20:01:0112878 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0712879 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:5512880
bnc032658ba2016-09-26 18:17:1512881 AddSSLSocketData();
bncb26024382016-06-29 02:39:4512882
Ryan Sleevib8d7ea02018-05-07 20:01:0112883 StaticSocketDataProvider hanging_socket3;
mmenkecc2298e2015-12-07 18:20:1812884 hanging_socket3.set_connect_data(never_finishing_connect);
12885 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket3);
[email protected]2d6728692011-03-12 01:39:5512886
danakj1fd259a02016-04-16 03:17:0912887 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:4112888 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:5012889 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5512890
tfarina42834112016-09-22 13:38:2012891 int rv = trans1.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112892 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12893 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512894
12895 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5212896 ASSERT_TRUE(response);
12897 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5512898 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12899
12900 std::string response_data;
robpercival214763f2016-07-01 23:27:0112901 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512902 EXPECT_EQ("hello world", response_data);
12903
[email protected]49639fa2011-12-20 23:22:4112904 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:5012905 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2012906 rv = trans2.Start(&request, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112907 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5512908
[email protected]49639fa2011-12-20 23:22:4112909 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:5012910 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2012911 rv = trans3.Start(&request, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112912 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5512913
robpercival214763f2016-07-01 23:27:0112914 EXPECT_THAT(callback2.WaitForResult(), IsOk());
12915 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512916
12917 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5212918 ASSERT_TRUE(response);
12919 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212920 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5512921 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212922 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0112923 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512924 EXPECT_EQ("hello!", response_data);
12925
12926 response = trans3.GetResponseInfo();
wezca1070932016-05-26 20:30:5212927 ASSERT_TRUE(response);
12928 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212929 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5512930 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212931 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0112932 ASSERT_THAT(ReadTransaction(&trans3, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512933 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:5512934}
12935
bncd16676a2016-07-20 16:23:0112936TEST_F(HttpNetworkTransactionTest, StallAlternativeServiceForNpnSpdy) {
Bence Békybcae37092018-06-12 04:18:5312937 session_deps_.host_resolver->set_synchronous_mode(true);
12938
[email protected]2d6728692011-03-12 01:39:5512939 HttpRequestInfo request;
12940 request.method = "GET";
bncb26024382016-06-29 02:39:4512941 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1012942 request.traffic_annotation =
12943 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d6728692011-03-12 01:39:5512944
12945 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212946 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312947 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212948 MockRead("\r\n"),
12949 MockRead("hello world"),
12950 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
12951 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5512952 };
12953
Ryan Sleevib8d7ea02018-05-07 20:01:0112954 StaticSocketDataProvider first_transaction(data_reads,
12955 base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712956 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:5512957
[email protected]8ddf8322012-02-23 18:08:0612958 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4912959 ssl.ssl_info.cert =
12960 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
12961 ASSERT_TRUE(ssl.ssl_info.cert);
[email protected]bb88e1d32013-05-03 23:11:0712962 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5512963
[email protected]d973e99a2012-02-17 21:02:3612964 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0112965 StaticSocketDataProvider hanging_alternate_protocol_socket;
[email protected]2d6728692011-03-12 01:39:5512966 hanging_alternate_protocol_socket.set_connect_data(
12967 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0712968 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5512969 &hanging_alternate_protocol_socket);
12970
bncb26024382016-06-29 02:39:4512971 // 2nd request is just a copy of the first one, over HTTP/1.1 again.
Ryan Sleevib8d7ea02018-05-07 20:01:0112972 StaticSocketDataProvider second_transaction(data_reads,
12973 base::span<MockWrite>());
mmenkecc2298e2015-12-07 18:20:1812974 session_deps_.socket_factory->AddSocketDataProvider(&second_transaction);
bncb26024382016-06-29 02:39:4512975 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5512976
[email protected]49639fa2011-12-20 23:22:4112977 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:5512978
danakj1fd259a02016-04-16 03:17:0912979 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5812980 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1912981 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5512982
tfarina42834112016-09-22 13:38:2012983 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112984 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12985 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512986
12987 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212988 ASSERT_TRUE(response);
12989 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5512990 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12991
12992 std::string response_data;
robpercival214763f2016-07-01 23:27:0112993 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512994 EXPECT_EQ("hello world", response_data);
12995
bnc87dcefc2017-05-25 12:47:5812996 trans =
Jeremy Roman0579ed62017-08-29 15:56:1912997 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5512998
tfarina42834112016-09-22 13:38:2012999 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113000 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13001 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5513002
13003 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5213004 ASSERT_TRUE(response);
13005 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5513006 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13007 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213008 EXPECT_FALSE(response->was_alpn_negotiated);
[email protected]2d6728692011-03-12 01:39:5513009
robpercival214763f2016-07-01 23:27:0113010 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5513011 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:5513012}
13013
bnc2e884782016-08-11 19:45:1913014// Test that proxy is resolved using the origin url,
13015// regardless of the alternative server.
13016TEST_F(HttpNetworkTransactionTest, UseOriginNotAlternativeForProxy) {
13017 // Configure proxy to bypass www.example.org, which is the origin URL.
13018 ProxyConfig proxy_config;
13019 proxy_config.proxy_rules().ParseFromString("myproxy:70");
13020 proxy_config.proxy_rules().bypass_rules.AddRuleFromString("www.example.org");
Ramin Halavatica8d5252018-03-12 05:33:4913021 auto proxy_config_service = std::make_unique<ProxyConfigServiceFixed>(
13022 ProxyConfigWithAnnotation(proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS));
bnc2e884782016-08-11 19:45:1913023
13024 CapturingProxyResolver capturing_proxy_resolver;
Jeremy Roman0579ed62017-08-29 15:56:1913025 auto proxy_resolver_factory = std::make_unique<CapturingProxyResolverFactory>(
bnc2e884782016-08-11 19:45:1913026 &capturing_proxy_resolver);
13027
13028 TestNetLog net_log;
13029
Bence Béky53a5aef2018-03-29 21:54:1213030 session_deps_.proxy_resolution_service =
13031 std::make_unique<ProxyResolutionService>(
13032 std::move(proxy_config_service), std::move(proxy_resolver_factory),
13033 &net_log);
bnc2e884782016-08-11 19:45:1913034
13035 session_deps_.net_log = &net_log;
13036
13037 // Configure alternative service with a hostname that is not bypassed by the
13038 // proxy.
13039 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13040 HttpServerProperties* http_server_properties =
13041 session->http_server_properties();
13042 url::SchemeHostPort server("https", "www.example.org", 443);
13043 HostPortPair alternative("www.example.com", 443);
bnc3472afd2016-11-17 15:27:2113044 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc2e884782016-08-11 19:45:1913045 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2113046 http_server_properties->SetHttp2AlternativeService(
13047 server, alternative_service, expiration);
bnc2e884782016-08-11 19:45:1913048
13049 // Non-alternative job should hang.
13050 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0113051 StaticSocketDataProvider hanging_alternate_protocol_socket;
bnc2e884782016-08-11 19:45:1913052 hanging_alternate_protocol_socket.set_connect_data(never_finishing_connect);
13053 session_deps_.socket_factory->AddSocketDataProvider(
13054 &hanging_alternate_protocol_socket);
13055
bnc032658ba2016-09-26 18:17:1513056 AddSSLSocketData();
bnc2e884782016-08-11 19:45:1913057
13058 HttpRequestInfo request;
13059 request.method = "GET";
13060 request.url = GURL("https://www.example.org/");
13061 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1013062 request.traffic_annotation =
13063 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc2e884782016-08-11 19:45:1913064
Ryan Hamilton0239aac2018-05-19 00:03:1313065 spdy::SpdySerializedFrame req(
bnc2e884782016-08-11 19:45:1913066 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
13067
13068 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
13069
Ryan Hamilton0239aac2018-05-19 00:03:1313070 spdy::SpdySerializedFrame resp(
13071 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
13072 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
bnc2e884782016-08-11 19:45:1913073 MockRead spdy_reads[] = {
13074 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
13075 };
13076
Ryan Sleevib8d7ea02018-05-07 20:01:0113077 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
bnc2e884782016-08-11 19:45:1913078 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
13079
13080 TestCompletionCallback callback;
13081
13082 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
13083
tfarina42834112016-09-22 13:38:2013084 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc2e884782016-08-11 19:45:1913085 EXPECT_THAT(callback.GetResult(rv), IsOk());
13086
13087 const HttpResponseInfo* response = trans.GetResponseInfo();
13088 ASSERT_TRUE(response);
13089 ASSERT_TRUE(response->headers);
13090 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
13091 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213092 EXPECT_TRUE(response->was_alpn_negotiated);
bnc2e884782016-08-11 19:45:1913093
13094 std::string response_data;
13095 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
13096 EXPECT_EQ("hello!", response_data);
13097
13098 // Origin host bypasses proxy, no resolution should have happened.
13099 ASSERT_TRUE(capturing_proxy_resolver.resolved().empty());
13100}
13101
bncd16676a2016-07-20 16:23:0113102TEST_F(HttpNetworkTransactionTest, UseAlternativeServiceForTunneledNpnSpdy) {
[email protected]631f1322010-04-30 17:59:1113103 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:4213104 proxy_config.set_auto_detect(true);
13105 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:1113106
sammc5dd160c2015-04-02 02:43:1313107 CapturingProxyResolver capturing_proxy_resolver;
Ramin Halavatica8d5252018-03-12 05:33:4913108 session_deps_.proxy_resolution_service =
13109 std::make_unique<ProxyResolutionService>(
13110 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
13111 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
13112 std::make_unique<CapturingProxyResolverFactory>(
13113 &capturing_proxy_resolver),
13114 nullptr);
vishal.b62985ca92015-04-17 08:45:5113115 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0713116 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:1113117
13118 HttpRequestInfo request;
13119 request.method = "GET";
bncb26024382016-06-29 02:39:4513120 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1013121 request.traffic_annotation =
13122 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]631f1322010-04-30 17:59:1113123
13124 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5213125 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4313126 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5213127 MockRead("\r\n"),
13128 MockRead("hello world"),
13129 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
13130 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:1113131 };
13132
Ryan Sleevib8d7ea02018-05-07 20:01:0113133 StaticSocketDataProvider first_transaction(data_reads,
13134 base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0713135 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4513136 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613137 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4513138 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]631f1322010-04-30 17:59:1113139
bnc032658ba2016-09-26 18:17:1513140 AddSSLSocketData();
[email protected]631f1322010-04-30 17:59:1113141
Ryan Hamilton0239aac2018-05-19 00:03:1313142 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4513143 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
[email protected]631f1322010-04-30 17:59:1113144 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1313145 MockWrite(ASYNC, 0,
bnc8bef8da22016-05-30 01:28:2513146 "CONNECT www.example.org:443 HTTP/1.1\r\n"
13147 "Host: www.example.org:443\r\n"
rch8e6c6c42015-05-01 14:05:1313148 "Proxy-Connection: keep-alive\r\n\r\n"),
bncdf80d44fd2016-07-15 20:27:4113149 CreateMockWrite(req, 2),
[email protected]631f1322010-04-30 17:59:1113150 };
13151
[email protected]d911f1b2010-05-05 22:39:4213152 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
13153
Ryan Hamilton0239aac2018-05-19 00:03:1313154 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
13155 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]631f1322010-04-30 17:59:1113156 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113157 MockRead(ASYNC, 1, kCONNECTResponse), CreateMockRead(resp, 3),
13158 CreateMockRead(data, 4), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5),
[email protected]631f1322010-04-30 17:59:1113159 };
13160
Ryan Sleevib8d7ea02018-05-07 20:01:0113161 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0713162 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:1113163
[email protected]d973e99a2012-02-17 21:02:3613164 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0113165 StaticSocketDataProvider hanging_non_alternate_protocol_socket;
[email protected]2d6728692011-03-12 01:39:5513166 hanging_non_alternate_protocol_socket.set_connect_data(
13167 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0713168 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5513169 &hanging_non_alternate_protocol_socket);
13170
[email protected]49639fa2011-12-20 23:22:4113171 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:1113172
danakj1fd259a02016-04-16 03:17:0913173 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5813174 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1913175 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1113176
tfarina42834112016-09-22 13:38:2013177 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea2dcd3bf2016-08-16 21:49:4113178 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13179 EXPECT_THAT(callback.WaitForResult(), IsOk());
13180
13181 const HttpResponseInfo* response = trans->GetResponseInfo();
13182 ASSERT_TRUE(response);
13183 ASSERT_TRUE(response->headers);
13184 EXPECT_EQ("HTTP/0.9 200 OK", response->headers->GetStatusLine());
13185 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213186 EXPECT_TRUE(response->was_alpn_negotiated);
mmenkea2dcd3bf2016-08-16 21:49:4113187
13188 std::string response_data;
13189 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
13190 EXPECT_EQ("hello world", response_data);
[email protected]631f1322010-04-30 17:59:1113191
bnc87dcefc2017-05-25 12:47:5813192 trans =
Jeremy Roman0579ed62017-08-29 15:56:1913193 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1113194
tfarina42834112016-09-22 13:38:2013195 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113196 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13197 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]631f1322010-04-30 17:59:1113198
mmenkea2dcd3bf2016-08-16 21:49:4113199 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5213200 ASSERT_TRUE(response);
13201 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213202 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5313203 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213204 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]631f1322010-04-30 17:59:1113205
robpercival214763f2016-07-01 23:27:0113206 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]631f1322010-04-30 17:59:1113207 EXPECT_EQ("hello!", response_data);
bncb26024382016-06-29 02:39:4513208 ASSERT_EQ(2u, capturing_proxy_resolver.resolved().size());
13209 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1313210 capturing_proxy_resolver.resolved()[0].spec());
bncce36dca22015-04-21 22:11:2313211 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1313212 capturing_proxy_resolver.resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:1113213
[email protected]029c83b62013-01-24 05:28:2013214 LoadTimingInfo load_timing_info;
13215 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
13216 TestLoadTimingNotReusedWithPac(load_timing_info,
13217 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:1113218}
[email protected]631f1322010-04-30 17:59:1113219
bncd16676a2016-07-20 16:23:0113220TEST_F(HttpNetworkTransactionTest,
bnc1c196c6e2016-05-28 13:51:4813221 UseAlternativeServiceForNpnSpdyWithExistingSpdySession) {
[email protected]2ff8b312010-04-26 22:20:5413222 HttpRequestInfo request;
13223 request.method = "GET";
bncb26024382016-06-29 02:39:4513224 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1013225 request.traffic_annotation =
13226 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2ff8b312010-04-26 22:20:5413227
13228 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5213229 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4313230 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5213231 MockRead("\r\n"),
13232 MockRead("hello world"),
13233 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:5413234 };
13235
Ryan Sleevib8d7ea02018-05-07 20:01:0113236 StaticSocketDataProvider first_transaction(data_reads,
13237 base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0713238 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4513239 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613240 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4513241 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5413242
bnc032658ba2016-09-26 18:17:1513243 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5413244
Ryan Hamilton0239aac2018-05-19 00:03:1313245 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4513246 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4113247 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5413248
Ryan Hamilton0239aac2018-05-19 00:03:1313249 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
13250 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5413251 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113252 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5413253 };
13254
Ryan Sleevib8d7ea02018-05-07 20:01:0113255 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0713256 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5413257
[email protected]83039bb2011-12-09 18:43:5513258 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5413259
danakj1fd259a02016-04-16 03:17:0913260 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:5413261
bnc87dcefc2017-05-25 12:47:5813262 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1913263 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5413264
tfarina42834112016-09-22 13:38:2013265 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113266 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13267 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5413268
13269 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5213270 ASSERT_TRUE(response);
13271 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5413272 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13273
13274 std::string response_data;
robpercival214763f2016-07-01 23:27:0113275 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5413276 EXPECT_EQ("hello world", response_data);
13277
13278 // Set up an initial SpdySession in the pool to reuse.
bnc8bef8da22016-05-30 01:28:2513279 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4013280 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
Matt Menke2436b2f2018-12-11 18:07:1113281 PRIVACY_MODE_DISABLED,
13282 SpdySessionKey::IsProxySession::kFalse, SocketTag());
[email protected]795cbf82013-07-22 09:37:2713283 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:5213284 CreateSpdySession(session.get(), key, NetLogWithSource());
[email protected]02b0c342010-09-25 21:09:3813285
bnc87dcefc2017-05-25 12:47:5813286 trans =
Jeremy Roman0579ed62017-08-29 15:56:1913287 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5413288
tfarina42834112016-09-22 13:38:2013289 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113290 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13291 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5413292
13293 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5213294 ASSERT_TRUE(response);
13295 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213296 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5313297 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213298 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5413299
robpercival214763f2016-07-01 23:27:0113300 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5413301 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:4213302}
13303
[email protected]044de0642010-06-17 10:42:1513304// GenerateAuthToken is a mighty big test.
13305// It tests all permutation of GenerateAuthToken behavior:
13306// - Synchronous and Asynchronous completion.
13307// - OK or error on completion.
13308// - Direct connection, non-authenticating proxy, and authenticating proxy.
13309// - HTTP or HTTPS backend (to include proxy tunneling).
13310// - Non-authenticating and authenticating backend.
13311//
[email protected]fe3b7dc2012-02-03 19:52:0913312// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:1513313// problems generating an auth token for an authenticating proxy, we don't
13314// need to test all permutations of the backend server).
13315//
13316// The test proceeds by going over each of the configuration cases, and
13317// potentially running up to three rounds in each of the tests. The TestConfig
13318// specifies both the configuration for the test as well as the expectations
13319// for the results.
bncd16676a2016-07-20 16:23:0113320TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:5013321 static const char kServer[] = "http://www.example.com";
13322 static const char kSecureServer[] = "https://www.example.com";
13323 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:1513324
13325 enum AuthTiming {
13326 AUTH_NONE,
13327 AUTH_SYNC,
13328 AUTH_ASYNC,
13329 };
13330
13331 const MockWrite kGet(
13332 "GET / HTTP/1.1\r\n"
13333 "Host: www.example.com\r\n"
13334 "Connection: keep-alive\r\n\r\n");
13335 const MockWrite kGetProxy(
13336 "GET http://www.example.com/ HTTP/1.1\r\n"
13337 "Host: www.example.com\r\n"
13338 "Proxy-Connection: keep-alive\r\n\r\n");
13339 const MockWrite kGetAuth(
13340 "GET / HTTP/1.1\r\n"
13341 "Host: www.example.com\r\n"
13342 "Connection: keep-alive\r\n"
13343 "Authorization: auth_token\r\n\r\n");
13344 const MockWrite kGetProxyAuth(
13345 "GET http://www.example.com/ HTTP/1.1\r\n"
13346 "Host: www.example.com\r\n"
13347 "Proxy-Connection: keep-alive\r\n"
13348 "Proxy-Authorization: auth_token\r\n\r\n");
13349 const MockWrite kGetAuthThroughProxy(
13350 "GET http://www.example.com/ HTTP/1.1\r\n"
13351 "Host: www.example.com\r\n"
13352 "Proxy-Connection: keep-alive\r\n"
13353 "Authorization: auth_token\r\n\r\n");
13354 const MockWrite kGetAuthWithProxyAuth(
13355 "GET http://www.example.com/ HTTP/1.1\r\n"
13356 "Host: www.example.com\r\n"
13357 "Proxy-Connection: keep-alive\r\n"
13358 "Proxy-Authorization: auth_token\r\n"
13359 "Authorization: auth_token\r\n\r\n");
13360 const MockWrite kConnect(
13361 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1713362 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1513363 "Proxy-Connection: keep-alive\r\n\r\n");
13364 const MockWrite kConnectProxyAuth(
13365 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1713366 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1513367 "Proxy-Connection: keep-alive\r\n"
13368 "Proxy-Authorization: auth_token\r\n\r\n");
13369
13370 const MockRead kSuccess(
13371 "HTTP/1.1 200 OK\r\n"
13372 "Content-Type: text/html; charset=iso-8859-1\r\n"
13373 "Content-Length: 3\r\n\r\n"
13374 "Yes");
13375 const MockRead kFailure(
13376 "Should not be called.");
13377 const MockRead kServerChallenge(
13378 "HTTP/1.1 401 Unauthorized\r\n"
13379 "WWW-Authenticate: Mock realm=server\r\n"
13380 "Content-Type: text/html; charset=iso-8859-1\r\n"
13381 "Content-Length: 14\r\n\r\n"
13382 "Unauthorized\r\n");
13383 const MockRead kProxyChallenge(
13384 "HTTP/1.1 407 Unauthorized\r\n"
13385 "Proxy-Authenticate: Mock realm=proxy\r\n"
13386 "Proxy-Connection: close\r\n"
13387 "Content-Type: text/html; charset=iso-8859-1\r\n"
13388 "Content-Length: 14\r\n\r\n"
13389 "Unauthorized\r\n");
13390 const MockRead kProxyConnected(
13391 "HTTP/1.1 200 Connection Established\r\n\r\n");
13392
13393 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
13394 // no constructors, but the C++ compiler on Windows warns about
13395 // unspecified data in compound literals. So, moved to using constructors,
13396 // and TestRound's created with the default constructor should not be used.
13397 struct TestRound {
13398 TestRound()
13399 : expected_rv(ERR_UNEXPECTED),
13400 extra_write(NULL),
13401 extra_read(NULL) {
13402 }
13403 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
13404 int expected_rv_arg)
13405 : write(write_arg),
13406 read(read_arg),
13407 expected_rv(expected_rv_arg),
13408 extra_write(NULL),
13409 extra_read(NULL) {
13410 }
13411 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
13412 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:0113413 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:1513414 : write(write_arg),
13415 read(read_arg),
13416 expected_rv(expected_rv_arg),
13417 extra_write(extra_write_arg),
13418 extra_read(extra_read_arg) {
13419 }
13420 MockWrite write;
13421 MockRead read;
13422 int expected_rv;
13423 const MockWrite* extra_write;
13424 const MockRead* extra_read;
13425 };
13426
13427 static const int kNoSSL = 500;
13428
13429 struct TestConfig {
asanka463ca4262016-11-16 02:34:3113430 int line_number;
thestig9d3bb0c2015-01-24 00:49:5113431 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:1513432 AuthTiming proxy_auth_timing;
asanka463ca4262016-11-16 02:34:3113433 int first_generate_proxy_token_rv;
thestig9d3bb0c2015-01-24 00:49:5113434 const char* const server_url;
[email protected]044de0642010-06-17 10:42:1513435 AuthTiming server_auth_timing;
asanka463ca4262016-11-16 02:34:3113436 int first_generate_server_token_rv;
[email protected]044de0642010-06-17 10:42:1513437 int num_auth_rounds;
13438 int first_ssl_round;
asankae2257db2016-10-11 22:03:1613439 TestRound rounds[4];
[email protected]044de0642010-06-17 10:42:1513440 } test_configs[] = {
asankac93076192016-10-03 15:46:0213441 // Non-authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3113442 {__LINE__,
13443 nullptr,
asankac93076192016-10-03 15:46:0213444 AUTH_NONE,
13445 OK,
13446 kServer,
13447 AUTH_NONE,
13448 OK,
13449 1,
13450 kNoSSL,
13451 {TestRound(kGet, kSuccess, OK)}},
13452 // Authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3113453 {__LINE__,
13454 nullptr,
asankac93076192016-10-03 15:46:0213455 AUTH_NONE,
13456 OK,
13457 kServer,
13458 AUTH_SYNC,
13459 OK,
13460 2,
13461 kNoSSL,
13462 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513463 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113464 {__LINE__,
13465 nullptr,
asankac93076192016-10-03 15:46:0213466 AUTH_NONE,
13467 OK,
13468 kServer,
13469 AUTH_SYNC,
13470 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1613471 3,
13472 kNoSSL,
13473 {TestRound(kGet, kServerChallenge, OK),
13474 TestRound(kGet, kServerChallenge, OK),
13475 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113476 {__LINE__,
13477 nullptr,
asankae2257db2016-10-11 22:03:1613478 AUTH_NONE,
13479 OK,
13480 kServer,
13481 AUTH_SYNC,
13482 ERR_UNSUPPORTED_AUTH_SCHEME,
13483 2,
13484 kNoSSL,
13485 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113486 {__LINE__,
13487 nullptr,
asankae2257db2016-10-11 22:03:1613488 AUTH_NONE,
13489 OK,
13490 kServer,
13491 AUTH_SYNC,
13492 ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS,
13493 2,
13494 kNoSSL,
13495 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113496 {__LINE__,
13497 kProxy,
asankae2257db2016-10-11 22:03:1613498 AUTH_SYNC,
13499 ERR_FAILED,
13500 kServer,
13501 AUTH_NONE,
13502 OK,
13503 2,
13504 kNoSSL,
13505 {TestRound(kGetProxy, kProxyChallenge, OK),
13506 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3113507 {__LINE__,
13508 kProxy,
asankae2257db2016-10-11 22:03:1613509 AUTH_ASYNC,
13510 ERR_FAILED,
13511 kServer,
13512 AUTH_NONE,
13513 OK,
13514 2,
13515 kNoSSL,
13516 {TestRound(kGetProxy, kProxyChallenge, OK),
13517 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3113518 {__LINE__,
13519 nullptr,
asankae2257db2016-10-11 22:03:1613520 AUTH_NONE,
13521 OK,
13522 kServer,
13523 AUTH_SYNC,
13524 ERR_FAILED,
asankac93076192016-10-03 15:46:0213525 2,
13526 kNoSSL,
13527 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613528 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3113529 {__LINE__,
13530 nullptr,
asankae2257db2016-10-11 22:03:1613531 AUTH_NONE,
13532 OK,
13533 kServer,
13534 AUTH_ASYNC,
13535 ERR_FAILED,
13536 2,
13537 kNoSSL,
13538 {TestRound(kGet, kServerChallenge, OK),
13539 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3113540 {__LINE__,
13541 nullptr,
asankac93076192016-10-03 15:46:0213542 AUTH_NONE,
13543 OK,
13544 kServer,
13545 AUTH_ASYNC,
13546 OK,
13547 2,
13548 kNoSSL,
13549 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513550 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113551 {__LINE__,
13552 nullptr,
asankac93076192016-10-03 15:46:0213553 AUTH_NONE,
13554 OK,
13555 kServer,
13556 AUTH_ASYNC,
13557 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1613558 3,
asankac93076192016-10-03 15:46:0213559 kNoSSL,
13560 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613561 // The second round uses a HttpAuthHandlerMock that always succeeds.
13562 TestRound(kGet, kServerChallenge, OK),
13563 TestRound(kGetAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213564 // Non-authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3113565 {__LINE__,
13566 kProxy,
asankac93076192016-10-03 15:46:0213567 AUTH_NONE,
13568 OK,
13569 kServer,
13570 AUTH_NONE,
13571 OK,
13572 1,
13573 kNoSSL,
13574 {TestRound(kGetProxy, kSuccess, OK)}},
13575 // Authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3113576 {__LINE__,
13577 kProxy,
asankac93076192016-10-03 15:46:0213578 AUTH_NONE,
13579 OK,
13580 kServer,
13581 AUTH_SYNC,
13582 OK,
13583 2,
13584 kNoSSL,
13585 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513586 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113587 {__LINE__,
13588 kProxy,
asankac93076192016-10-03 15:46:0213589 AUTH_NONE,
13590 OK,
13591 kServer,
13592 AUTH_SYNC,
13593 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1613594 3,
asankac93076192016-10-03 15:46:0213595 kNoSSL,
13596 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613597 TestRound(kGetProxy, kServerChallenge, OK),
13598 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113599 {__LINE__,
13600 kProxy,
asankac93076192016-10-03 15:46:0213601 AUTH_NONE,
13602 OK,
13603 kServer,
13604 AUTH_ASYNC,
13605 OK,
13606 2,
13607 kNoSSL,
13608 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513609 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113610 {__LINE__,
13611 kProxy,
asankac93076192016-10-03 15:46:0213612 AUTH_NONE,
13613 OK,
13614 kServer,
13615 AUTH_ASYNC,
13616 ERR_INVALID_AUTH_CREDENTIALS,
13617 2,
13618 kNoSSL,
13619 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613620 TestRound(kGetProxy, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213621 // Non-authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3113622 {__LINE__,
13623 kProxy,
asankac93076192016-10-03 15:46:0213624 AUTH_SYNC,
13625 OK,
13626 kServer,
13627 AUTH_NONE,
13628 OK,
13629 2,
13630 kNoSSL,
13631 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513632 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113633 {__LINE__,
13634 kProxy,
asankac93076192016-10-03 15:46:0213635 AUTH_SYNC,
13636 ERR_INVALID_AUTH_CREDENTIALS,
13637 kServer,
13638 AUTH_NONE,
13639 OK,
13640 2,
13641 kNoSSL,
13642 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1613643 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113644 {__LINE__,
13645 kProxy,
asankac93076192016-10-03 15:46:0213646 AUTH_ASYNC,
13647 OK,
13648 kServer,
13649 AUTH_NONE,
13650 OK,
13651 2,
13652 kNoSSL,
13653 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513654 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113655 {__LINE__,
13656 kProxy,
asankac93076192016-10-03 15:46:0213657 AUTH_ASYNC,
13658 ERR_INVALID_AUTH_CREDENTIALS,
13659 kServer,
13660 AUTH_NONE,
13661 OK,
13662 2,
13663 kNoSSL,
13664 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1613665 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113666 {__LINE__,
13667 kProxy,
13668 AUTH_ASYNC,
13669 ERR_INVALID_AUTH_CREDENTIALS,
13670 kServer,
13671 AUTH_NONE,
13672 OK,
13673 3,
13674 kNoSSL,
13675 {TestRound(kGetProxy, kProxyChallenge, OK),
13676 TestRound(kGetProxy, kProxyChallenge, OK),
13677 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213678 // Authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3113679 {__LINE__,
13680 kProxy,
asankac93076192016-10-03 15:46:0213681 AUTH_SYNC,
13682 OK,
13683 kServer,
13684 AUTH_SYNC,
13685 OK,
13686 3,
13687 kNoSSL,
13688 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513689 TestRound(kGetProxyAuth, kServerChallenge, OK),
13690 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113691 {__LINE__,
13692 kProxy,
asankac93076192016-10-03 15:46:0213693 AUTH_SYNC,
13694 OK,
13695 kServer,
13696 AUTH_SYNC,
13697 ERR_INVALID_AUTH_CREDENTIALS,
13698 3,
13699 kNoSSL,
13700 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513701 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613702 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113703 {__LINE__,
13704 kProxy,
asankac93076192016-10-03 15:46:0213705 AUTH_ASYNC,
13706 OK,
13707 kServer,
13708 AUTH_SYNC,
13709 OK,
13710 3,
13711 kNoSSL,
13712 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513713 TestRound(kGetProxyAuth, kServerChallenge, OK),
13714 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113715 {__LINE__,
13716 kProxy,
asankac93076192016-10-03 15:46:0213717 AUTH_ASYNC,
13718 OK,
13719 kServer,
13720 AUTH_SYNC,
13721 ERR_INVALID_AUTH_CREDENTIALS,
13722 3,
13723 kNoSSL,
13724 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513725 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613726 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113727 {__LINE__,
13728 kProxy,
asankac93076192016-10-03 15:46:0213729 AUTH_SYNC,
13730 OK,
13731 kServer,
13732 AUTH_ASYNC,
13733 OK,
13734 3,
13735 kNoSSL,
13736 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513737 TestRound(kGetProxyAuth, kServerChallenge, OK),
13738 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113739 {__LINE__,
13740 kProxy,
13741 AUTH_SYNC,
13742 ERR_INVALID_AUTH_CREDENTIALS,
13743 kServer,
13744 AUTH_ASYNC,
13745 OK,
13746 4,
13747 kNoSSL,
13748 {TestRound(kGetProxy, kProxyChallenge, OK),
13749 TestRound(kGetProxy, kProxyChallenge, OK),
13750 TestRound(kGetProxyAuth, kServerChallenge, OK),
13751 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
13752 {__LINE__,
13753 kProxy,
asankac93076192016-10-03 15:46:0213754 AUTH_SYNC,
13755 OK,
13756 kServer,
13757 AUTH_ASYNC,
13758 ERR_INVALID_AUTH_CREDENTIALS,
13759 3,
13760 kNoSSL,
13761 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513762 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613763 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113764 {__LINE__,
13765 kProxy,
asankac93076192016-10-03 15:46:0213766 AUTH_ASYNC,
13767 OK,
13768 kServer,
13769 AUTH_ASYNC,
13770 OK,
13771 3,
13772 kNoSSL,
13773 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513774 TestRound(kGetProxyAuth, kServerChallenge, OK),
13775 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113776 {__LINE__,
13777 kProxy,
asankac93076192016-10-03 15:46:0213778 AUTH_ASYNC,
13779 OK,
13780 kServer,
13781 AUTH_ASYNC,
13782 ERR_INVALID_AUTH_CREDENTIALS,
13783 3,
13784 kNoSSL,
13785 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513786 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613787 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113788 {__LINE__,
13789 kProxy,
13790 AUTH_ASYNC,
13791 ERR_INVALID_AUTH_CREDENTIALS,
13792 kServer,
13793 AUTH_ASYNC,
13794 ERR_INVALID_AUTH_CREDENTIALS,
13795 4,
13796 kNoSSL,
13797 {TestRound(kGetProxy, kProxyChallenge, OK),
13798 TestRound(kGetProxy, kProxyChallenge, OK),
13799 TestRound(kGetProxyAuth, kServerChallenge, OK),
13800 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213801 // Non-authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3113802 {__LINE__,
13803 nullptr,
asankac93076192016-10-03 15:46:0213804 AUTH_NONE,
13805 OK,
13806 kSecureServer,
13807 AUTH_NONE,
13808 OK,
13809 1,
13810 0,
13811 {TestRound(kGet, kSuccess, OK)}},
13812 // Authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3113813 {__LINE__,
13814 nullptr,
asankac93076192016-10-03 15:46:0213815 AUTH_NONE,
13816 OK,
13817 kSecureServer,
13818 AUTH_SYNC,
13819 OK,
13820 2,
13821 0,
13822 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513823 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113824 {__LINE__,
13825 nullptr,
asankac93076192016-10-03 15:46:0213826 AUTH_NONE,
13827 OK,
13828 kSecureServer,
13829 AUTH_SYNC,
13830 ERR_INVALID_AUTH_CREDENTIALS,
13831 2,
13832 0,
asankae2257db2016-10-11 22:03:1613833 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113834 {__LINE__,
13835 nullptr,
asankac93076192016-10-03 15:46:0213836 AUTH_NONE,
13837 OK,
13838 kSecureServer,
13839 AUTH_ASYNC,
13840 OK,
13841 2,
13842 0,
13843 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513844 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113845 {__LINE__,
13846 nullptr,
asankac93076192016-10-03 15:46:0213847 AUTH_NONE,
13848 OK,
13849 kSecureServer,
13850 AUTH_ASYNC,
13851 ERR_INVALID_AUTH_CREDENTIALS,
13852 2,
13853 0,
asankae2257db2016-10-11 22:03:1613854 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213855 // Non-authenticating HTTPS server with a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3113856 {__LINE__,
13857 kProxy,
asankac93076192016-10-03 15:46:0213858 AUTH_NONE,
13859 OK,
13860 kSecureServer,
13861 AUTH_NONE,
13862 OK,
13863 1,
13864 0,
13865 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
13866 // Authenticating HTTPS server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3113867 {__LINE__,
13868 kProxy,
asankac93076192016-10-03 15:46:0213869 AUTH_NONE,
13870 OK,
13871 kSecureServer,
13872 AUTH_SYNC,
13873 OK,
13874 2,
13875 0,
13876 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513877 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113878 {__LINE__,
13879 kProxy,
asankac93076192016-10-03 15:46:0213880 AUTH_NONE,
13881 OK,
13882 kSecureServer,
13883 AUTH_SYNC,
13884 ERR_INVALID_AUTH_CREDENTIALS,
13885 2,
13886 0,
13887 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1613888 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113889 {__LINE__,
13890 kProxy,
asankac93076192016-10-03 15:46:0213891 AUTH_NONE,
13892 OK,
13893 kSecureServer,
13894 AUTH_ASYNC,
13895 OK,
13896 2,
13897 0,
13898 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513899 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113900 {__LINE__,
13901 kProxy,
asankac93076192016-10-03 15:46:0213902 AUTH_NONE,
13903 OK,
13904 kSecureServer,
13905 AUTH_ASYNC,
13906 ERR_INVALID_AUTH_CREDENTIALS,
13907 2,
13908 0,
13909 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1613910 TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213911 // Non-Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3113912 {__LINE__,
13913 kProxy,
asankac93076192016-10-03 15:46:0213914 AUTH_SYNC,
13915 OK,
13916 kSecureServer,
13917 AUTH_NONE,
13918 OK,
13919 2,
13920 1,
13921 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513922 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113923 {__LINE__,
13924 kProxy,
asankac93076192016-10-03 15:46:0213925 AUTH_SYNC,
13926 ERR_INVALID_AUTH_CREDENTIALS,
13927 kSecureServer,
13928 AUTH_NONE,
13929 OK,
13930 2,
13931 kNoSSL,
13932 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1613933 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113934 {__LINE__,
13935 kProxy,
asankae2257db2016-10-11 22:03:1613936 AUTH_SYNC,
13937 ERR_UNSUPPORTED_AUTH_SCHEME,
13938 kSecureServer,
13939 AUTH_NONE,
13940 OK,
13941 2,
13942 kNoSSL,
13943 {TestRound(kConnect, kProxyChallenge, OK),
13944 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113945 {__LINE__,
13946 kProxy,
asankae2257db2016-10-11 22:03:1613947 AUTH_SYNC,
13948 ERR_UNEXPECTED,
13949 kSecureServer,
13950 AUTH_NONE,
13951 OK,
13952 2,
13953 kNoSSL,
13954 {TestRound(kConnect, kProxyChallenge, OK),
13955 TestRound(kConnect, kProxyConnected, ERR_UNEXPECTED)}},
asanka463ca4262016-11-16 02:34:3113956 {__LINE__,
13957 kProxy,
asankac93076192016-10-03 15:46:0213958 AUTH_ASYNC,
13959 OK,
13960 kSecureServer,
13961 AUTH_NONE,
13962 OK,
13963 2,
13964 1,
13965 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513966 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113967 {__LINE__,
13968 kProxy,
asankac93076192016-10-03 15:46:0213969 AUTH_ASYNC,
13970 ERR_INVALID_AUTH_CREDENTIALS,
13971 kSecureServer,
13972 AUTH_NONE,
13973 OK,
13974 2,
13975 kNoSSL,
13976 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1613977 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asankac93076192016-10-03 15:46:0213978 // Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3113979 {__LINE__,
13980 kProxy,
asankac93076192016-10-03 15:46:0213981 AUTH_SYNC,
13982 OK,
13983 kSecureServer,
13984 AUTH_SYNC,
13985 OK,
13986 3,
13987 1,
13988 {TestRound(kConnect, kProxyChallenge, OK),
13989 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13990 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513991 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113992 {__LINE__,
13993 kProxy,
asankac93076192016-10-03 15:46:0213994 AUTH_SYNC,
13995 OK,
13996 kSecureServer,
13997 AUTH_SYNC,
13998 ERR_INVALID_AUTH_CREDENTIALS,
13999 3,
14000 1,
14001 {TestRound(kConnect, kProxyChallenge, OK),
14002 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14003 &kServerChallenge),
asankae2257db2016-10-11 22:03:1614004 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114005 {__LINE__,
14006 kProxy,
asankac93076192016-10-03 15:46:0214007 AUTH_ASYNC,
14008 OK,
14009 kSecureServer,
14010 AUTH_SYNC,
14011 OK,
14012 3,
14013 1,
14014 {TestRound(kConnect, kProxyChallenge, OK),
14015 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14016 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1514017 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114018 {__LINE__,
14019 kProxy,
asankac93076192016-10-03 15:46:0214020 AUTH_ASYNC,
14021 OK,
14022 kSecureServer,
14023 AUTH_SYNC,
14024 ERR_INVALID_AUTH_CREDENTIALS,
14025 3,
14026 1,
14027 {TestRound(kConnect, kProxyChallenge, OK),
14028 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14029 &kServerChallenge),
asankae2257db2016-10-11 22:03:1614030 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114031 {__LINE__,
14032 kProxy,
asankac93076192016-10-03 15:46:0214033 AUTH_SYNC,
14034 OK,
14035 kSecureServer,
14036 AUTH_ASYNC,
14037 OK,
14038 3,
14039 1,
14040 {TestRound(kConnect, kProxyChallenge, OK),
14041 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14042 &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_SYNC,
14047 OK,
14048 kSecureServer,
14049 AUTH_ASYNC,
14050 ERR_INVALID_AUTH_CREDENTIALS,
14051 3,
14052 1,
14053 {TestRound(kConnect, kProxyChallenge, OK),
14054 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14055 &kServerChallenge),
asankae2257db2016-10-11 22:03:1614056 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114057 {__LINE__,
14058 kProxy,
asankac93076192016-10-03 15:46:0214059 AUTH_ASYNC,
14060 OK,
14061 kSecureServer,
14062 AUTH_ASYNC,
14063 OK,
14064 3,
14065 1,
14066 {TestRound(kConnect, kProxyChallenge, OK),
14067 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14068 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1514069 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114070 {__LINE__,
14071 kProxy,
asankac93076192016-10-03 15:46:0214072 AUTH_ASYNC,
14073 OK,
14074 kSecureServer,
14075 AUTH_ASYNC,
14076 ERR_INVALID_AUTH_CREDENTIALS,
14077 3,
14078 1,
14079 {TestRound(kConnect, kProxyChallenge, OK),
14080 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14081 &kServerChallenge),
asankae2257db2016-10-11 22:03:1614082 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114083 {__LINE__,
14084 kProxy,
14085 AUTH_ASYNC,
14086 ERR_INVALID_AUTH_CREDENTIALS,
14087 kSecureServer,
14088 AUTH_ASYNC,
14089 ERR_INVALID_AUTH_CREDENTIALS,
14090 4,
14091 2,
14092 {TestRound(kConnect, kProxyChallenge, OK),
14093 TestRound(kConnect, kProxyChallenge, OK),
14094 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14095 &kServerChallenge),
14096 TestRound(kGet, kSuccess, OK)}},
[email protected]044de0642010-06-17 10:42:1514097 };
14098
asanka463ca4262016-11-16 02:34:3114099 for (const auto& test_config : test_configs) {
14100 SCOPED_TRACE(::testing::Message() << "Test config at "
14101 << test_config.line_number);
[email protected]2d01c262011-08-11 23:07:0814102 HttpAuthHandlerMock::Factory* auth_factory(
14103 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0714104 session_deps_.http_auth_handler_factory.reset(auth_factory);
asanka5ffd5d72016-03-23 16:20:4914105 SSLInfo empty_ssl_info;
[email protected]65d34382010-07-01 18:12:2614106
14107 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:1514108 if (test_config.proxy_auth_timing != AUTH_NONE) {
asanka463ca4262016-11-16 02:34:3114109 for (int n = 0; n < 3; n++) {
[email protected]2d01c262011-08-11 23:07:0814110 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
14111 std::string auth_challenge = "Mock realm=proxy";
14112 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:2414113 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
14114 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:0814115 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
tfarina42834112016-09-22 13:38:2014116 empty_ssl_info, origin,
14117 NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0814118 auth_handler->SetGenerateExpectation(
14119 test_config.proxy_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3114120 n == 0 ? test_config.first_generate_proxy_token_rv : OK);
[email protected]2d01c262011-08-11 23:07:0814121 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
14122 }
[email protected]044de0642010-06-17 10:42:1514123 }
14124 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:0014125 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:1514126 std::string auth_challenge = "Mock realm=server";
14127 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:2414128 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
14129 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:1514130 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2014131 empty_ssl_info, origin,
14132 NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1514133 auth_handler->SetGenerateExpectation(
14134 test_config.server_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3114135 test_config.first_generate_server_token_rv);
[email protected]2d01c262011-08-11 23:07:0814136 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
asankae2257db2016-10-11 22:03:1614137
14138 // The second handler always succeeds. It should only be used where there
14139 // are multiple auth sessions for server auth in the same network
14140 // transaction using the same auth scheme.
14141 std::unique_ptr<HttpAuthHandlerMock> second_handler =
Jeremy Roman0579ed62017-08-29 15:56:1914142 std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:1614143 second_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
14144 empty_ssl_info, origin,
14145 NetLogWithSource());
14146 second_handler->SetGenerateExpectation(true, OK);
14147 auth_factory->AddMockHandler(second_handler.release(),
14148 HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:1514149 }
14150 if (test_config.proxy_url) {
Lily Houghton8c2f97d2018-01-22 05:06:5914151 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4914152 ProxyResolutionService::CreateFixed(test_config.proxy_url,
14153 TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]044de0642010-06-17 10:42:1514154 } else {
Bence Béky53a5aef2018-03-29 21:54:1214155 session_deps_.proxy_resolution_service =
14156 ProxyResolutionService::CreateDirect();
[email protected]044de0642010-06-17 10:42:1514157 }
14158
14159 HttpRequestInfo request;
14160 request.method = "GET";
14161 request.url = GURL(test_config.server_url);
Ramin Halavatib5e433e62018-02-07 07:41:1014162 request.traffic_annotation =
14163 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]044de0642010-06-17 10:42:1514164
danakj1fd259a02016-04-16 03:17:0914165 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]044de0642010-06-17 10:42:1514166
rchcb68dc62015-05-21 04:45:3614167 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
14168
14169 std::vector<std::vector<MockRead>> mock_reads(1);
14170 std::vector<std::vector<MockWrite>> mock_writes(1);
[email protected]044de0642010-06-17 10:42:1514171 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2214172 SCOPED_TRACE(round);
[email protected]044de0642010-06-17 10:42:1514173 const TestRound& read_write_round = test_config.rounds[round];
14174
14175 // Set up expected reads and writes.
rchcb68dc62015-05-21 04:45:3614176 mock_reads.back().push_back(read_write_round.read);
14177 mock_writes.back().push_back(read_write_round.write);
14178
14179 // kProxyChallenge uses Proxy-Connection: close which means that the
14180 // socket is closed and a new one will be created for the next request.
mmenkee71e15332015-10-07 16:39:5414181 if (read_write_round.read.data == kProxyChallenge.data) {
rchcb68dc62015-05-21 04:45:3614182 mock_reads.push_back(std::vector<MockRead>());
14183 mock_writes.push_back(std::vector<MockWrite>());
[email protected]044de0642010-06-17 10:42:1514184 }
14185
rchcb68dc62015-05-21 04:45:3614186 if (read_write_round.extra_read) {
14187 mock_reads.back().push_back(*read_write_round.extra_read);
[email protected]044de0642010-06-17 10:42:1514188 }
rchcb68dc62015-05-21 04:45:3614189 if (read_write_round.extra_write) {
14190 mock_writes.back().push_back(*read_write_round.extra_write);
14191 }
[email protected]044de0642010-06-17 10:42:1514192
14193 // Add an SSL sequence if necessary.
[email protected]044de0642010-06-17 10:42:1514194 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0714195 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1514196 &ssl_socket_data_provider);
rchcb68dc62015-05-21 04:45:3614197 }
[email protected]044de0642010-06-17 10:42:1514198
danakj1fd259a02016-04-16 03:17:0914199 std::vector<std::unique_ptr<StaticSocketDataProvider>> data_providers;
rchcb68dc62015-05-21 04:45:3614200 for (size_t i = 0; i < mock_reads.size(); ++i) {
Jeremy Roman0579ed62017-08-29 15:56:1914201 data_providers.push_back(std::make_unique<StaticSocketDataProvider>(
Ryan Sleevib8d7ea02018-05-07 20:01:0114202 mock_reads[i], mock_writes[i]));
rchcb68dc62015-05-21 04:45:3614203 session_deps_.socket_factory->AddSocketDataProvider(
olli.raula525048c2015-12-10 07:38:3214204 data_providers.back().get());
rchcb68dc62015-05-21 04:45:3614205 }
14206
mmenkecc2298e2015-12-07 18:20:1814207 // Transaction must be created after DataProviders, so it's destroyed before
14208 // they are as well.
14209 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
14210
rchcb68dc62015-05-21 04:45:3614211 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2214212 SCOPED_TRACE(round);
rchcb68dc62015-05-21 04:45:3614213 const TestRound& read_write_round = test_config.rounds[round];
[email protected]044de0642010-06-17 10:42:1514214 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4114215 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1514216 int rv;
14217 if (round == 0) {
tfarina42834112016-09-22 13:38:2014218 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1514219 } else {
[email protected]49639fa2011-12-20 23:22:4114220 rv = trans.RestartWithAuth(
14221 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1514222 }
14223 if (rv == ERR_IO_PENDING)
14224 rv = callback.WaitForResult();
14225
14226 // Compare results with expected data.
asankae2257db2016-10-11 22:03:1614227 EXPECT_THAT(rv, IsError(read_write_round.expected_rv));
[email protected]0b0bf032010-09-21 18:08:5014228 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttlec0c828492015-05-15 01:25:5514229 if (read_write_round.expected_rv != OK) {
[email protected]044de0642010-06-17 10:42:1514230 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
14231 continue;
14232 }
14233 if (round + 1 < test_config.num_auth_rounds) {
wezca1070932016-05-26 20:30:5214234 EXPECT_TRUE(response->auth_challenge);
[email protected]044de0642010-06-17 10:42:1514235 } else {
wezca1070932016-05-26 20:30:5214236 EXPECT_FALSE(response->auth_challenge);
asankae2257db2016-10-11 22:03:1614237 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]044de0642010-06-17 10:42:1514238 }
14239 }
[email protected]e5ae96a2010-04-14 20:12:4514240 }
14241}
14242
bncd16676a2016-07-20 16:23:0114243TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1414244 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1414245 HttpAuthHandlerMock::Factory* auth_factory(
14246 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0714247 session_deps_.http_auth_handler_factory.reset(auth_factory);
Bence Béky53a5aef2018-03-29 21:54:1214248 session_deps_.proxy_resolution_service =
14249 ProxyResolutionService::CreateDirect();
[email protected]bb88e1d32013-05-03 23:11:0714250 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
[email protected]c871bce92010-07-15 21:51:1414251
14252 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
14253 auth_handler->set_connection_based(true);
14254 std::string auth_challenge = "Mock realm=server";
14255 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2414256 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
14257 auth_challenge.end());
asanka5ffd5d72016-03-23 16:20:4914258 SSLInfo empty_ssl_info;
[email protected]c871bce92010-07-15 21:51:1414259 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2014260 empty_ssl_info, origin, NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0814261 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1414262
[email protected]c871bce92010-07-15 21:51:1414263 int rv = OK;
14264 const HttpResponseInfo* response = NULL;
14265 HttpRequestInfo request;
14266 request.method = "GET";
14267 request.url = origin;
Ramin Halavatib5e433e62018-02-07 07:41:1014268 request.traffic_annotation =
14269 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2714270
danakj1fd259a02016-04-16 03:17:0914271 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1014272
14273 // Use a TCP Socket Pool with only one connection per group. This is used
14274 // to validate that the TCP socket is not released to the pool between
14275 // each round of multi-round authentication.
mmenkee65e7af2015-10-13 17:16:4214276 HttpNetworkSessionPeer session_peer(session.get());
[email protected]ab739042011-04-07 15:22:2814277 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:1014278 50, // Max sockets for pool
14279 1, // Max sockets per group
Matt Menkecb77b5402019-01-28 17:11:2314280 session_deps_.socket_factory.get(), session_deps_.host_resolver.get(),
Matt Menke1751ba72019-02-09 02:23:4614281 nullptr /* proxy_delegate */, session_deps_.cert_verifier.get(),
14282 session_deps_.channel_id_service.get(),
Matt Menkecb77b5402019-01-28 17:11:2314283 session_deps_.transport_security_state.get(),
14284 session_deps_.cert_transparency_verifier.get(),
14285 session_deps_.ct_policy_enforcer.get(),
Matt Menkec94d97b2019-02-01 19:28:2814286 nullptr /* ssl_client_session_cache */,
Daniel McArdleda3fa942019-02-15 16:41:2114287 nullptr /* ssl_client_session_cache_privacy_mode */,
Matt Menkefa9574f2019-01-28 18:55:2714288 session_deps_.ssl_config_service.get(),
Matt Menkecb77b5402019-01-28 17:11:2314289 nullptr /* socket_performance_watcher_factory */,
14290 nullptr /* network_quality_estimator */, session_deps_.net_log);
Jeremy Roman0579ed62017-08-29 15:56:1914291 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
[email protected]a42dbd142011-11-17 16:42:0214292 mock_pool_manager->SetTransportSocketPool(transport_pool);
dchengc7eeda422015-12-26 03:56:4814293 session_peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]7ef4cbbb2011-02-06 11:19:1014294
bnc691fda62016-08-12 00:43:1614295 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4114296 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1414297
14298 const MockWrite kGet(
14299 "GET / HTTP/1.1\r\n"
14300 "Host: www.example.com\r\n"
14301 "Connection: keep-alive\r\n\r\n");
14302 const MockWrite kGetAuth(
14303 "GET / HTTP/1.1\r\n"
14304 "Host: www.example.com\r\n"
14305 "Connection: keep-alive\r\n"
14306 "Authorization: auth_token\r\n\r\n");
14307
14308 const MockRead kServerChallenge(
14309 "HTTP/1.1 401 Unauthorized\r\n"
14310 "WWW-Authenticate: Mock realm=server\r\n"
14311 "Content-Type: text/html; charset=iso-8859-1\r\n"
14312 "Content-Length: 14\r\n\r\n"
14313 "Unauthorized\r\n");
14314 const MockRead kSuccess(
14315 "HTTP/1.1 200 OK\r\n"
14316 "Content-Type: text/html; charset=iso-8859-1\r\n"
14317 "Content-Length: 3\r\n\r\n"
14318 "Yes");
14319
14320 MockWrite writes[] = {
14321 // First round
14322 kGet,
14323 // Second round
14324 kGetAuth,
14325 // Third round
14326 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3014327 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1014328 kGetAuth,
14329 // Competing request
14330 kGet,
[email protected]c871bce92010-07-15 21:51:1414331 };
14332 MockRead reads[] = {
14333 // First round
14334 kServerChallenge,
14335 // Second round
14336 kServerChallenge,
14337 // Third round
[email protected]eca50e122010-09-11 14:03:3014338 kServerChallenge,
14339 // Fourth round
[email protected]c871bce92010-07-15 21:51:1414340 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1014341 // Competing response
14342 kSuccess,
[email protected]c871bce92010-07-15 21:51:1414343 };
Ryan Sleevib8d7ea02018-05-07 20:01:0114344 StaticSocketDataProvider data_provider(reads, writes);
[email protected]bb88e1d32013-05-03 23:11:0714345 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1414346
thestig9d3bb0c2015-01-24 00:49:5114347 const char kSocketGroup[] = "www.example.com:80";
[email protected]7ef4cbbb2011-02-06 11:19:1014348
14349 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1414350 auth_handler->SetGenerateExpectation(false, OK);
tfarina42834112016-09-22 13:38:2014351 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]c871bce92010-07-15 21:51:1414352 if (rv == ERR_IO_PENDING)
14353 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114354 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1614355 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214356 ASSERT_TRUE(response);
14357 EXPECT_TRUE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2814358 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3114359 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
14360 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1414361
[email protected]7ef4cbbb2011-02-06 11:19:1014362 // In between rounds, another request comes in for the same domain.
14363 // It should not be able to grab the TCP socket that trans has already
14364 // claimed.
bnc691fda62016-08-12 00:43:1614365 HttpNetworkTransaction trans_compete(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4114366 TestCompletionCallback callback_compete;
tfarina42834112016-09-22 13:38:2014367 rv = trans_compete.Start(&request, callback_compete.callback(),
14368 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114369 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7ef4cbbb2011-02-06 11:19:1014370 // callback_compete.WaitForResult at this point would stall forever,
14371 // since the HttpNetworkTransaction does not release the request back to
14372 // the pool until after authentication completes.
14373
14374 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1414375 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1614376 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1414377 if (rv == ERR_IO_PENDING)
14378 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114379 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1614380 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214381 ASSERT_TRUE(response);
14382 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2814383 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3114384 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
14385 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1414386
[email protected]7ef4cbbb2011-02-06 11:19:1014387 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1414388 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1614389 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1414390 if (rv == ERR_IO_PENDING)
14391 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114392 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1614393 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214394 ASSERT_TRUE(response);
14395 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2814396 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3114397 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
14398 auth_handler->state());
[email protected]eca50e122010-09-11 14:03:3014399
[email protected]7ef4cbbb2011-02-06 11:19:1014400 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3014401 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1614402 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3014403 if (rv == ERR_IO_PENDING)
14404 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114405 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1614406 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214407 ASSERT_TRUE(response);
14408 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2814409 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1014410
asanka463ca4262016-11-16 02:34:3114411 // In WAIT_FOR_CHALLENGE, although in reality the auth handler is done. A real
14412 // auth handler should transition to a DONE state in concert with the remote
14413 // server. But that's not something we can test here with a mock handler.
14414 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_CHALLENGE,
14415 auth_handler->state());
14416
[email protected]7ef4cbbb2011-02-06 11:19:1014417 // Read the body since the fourth round was successful. This will also
14418 // release the socket back to the pool.
Victor Costan9c7302b2018-08-27 16:39:4414419 scoped_refptr<IOBufferWithSize> io_buf =
14420 base::MakeRefCounted<IOBufferWithSize>(50);
bnc691fda62016-08-12 00:43:1614421 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1014422 if (rv == ERR_IO_PENDING)
14423 rv = callback.WaitForResult();
14424 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1614425 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1014426 EXPECT_EQ(0, rv);
14427 // There are still 0 idle sockets, since the trans_compete transaction
14428 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:2814429 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1014430
14431 // The competing request can now finish. Wait for the headers and then
14432 // read the body.
14433 rv = callback_compete.WaitForResult();
robpercival214763f2016-07-01 23:27:0114434 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1614435 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1014436 if (rv == ERR_IO_PENDING)
14437 rv = callback.WaitForResult();
14438 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1614439 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1014440 EXPECT_EQ(0, rv);
14441
14442 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:2814443 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1414444}
14445
[email protected]65041fa2010-05-21 06:56:5314446// This tests the case that a request is issued via http instead of spdy after
14447// npn is negotiated.
bncd16676a2016-07-20 16:23:0114448TEST_F(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]65041fa2010-05-21 06:56:5314449 HttpRequestInfo request;
14450 request.method = "GET";
bncce36dca22015-04-21 22:11:2314451 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1014452 request.traffic_annotation =
14453 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]65041fa2010-05-21 06:56:5314454
14455 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2314456 MockWrite(
14457 "GET / HTTP/1.1\r\n"
14458 "Host: www.example.org\r\n"
14459 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5314460 };
14461
14462 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5214463 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4314464 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5214465 MockRead("\r\n"),
14466 MockRead("hello world"),
14467 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5314468 };
14469
[email protected]8ddf8322012-02-23 18:08:0614470 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614471 ssl.next_proto = kProtoHTTP11;
[email protected]65041fa2010-05-21 06:56:5314472
[email protected]bb88e1d32013-05-03 23:11:0714473 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5314474
Ryan Sleevib8d7ea02018-05-07 20:01:0114475 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0714476 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5314477
[email protected]49639fa2011-12-20 23:22:4114478 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5314479
danakj1fd259a02016-04-16 03:17:0914480 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614481 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]65041fa2010-05-21 06:56:5314482
tfarina42834112016-09-22 13:38:2014483 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]65041fa2010-05-21 06:56:5314484
robpercival214763f2016-07-01 23:27:0114485 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14486 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]65041fa2010-05-21 06:56:5314487
bnc691fda62016-08-12 00:43:1614488 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214489 ASSERT_TRUE(response);
14490 ASSERT_TRUE(response->headers);
[email protected]65041fa2010-05-21 06:56:5314491 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
14492
14493 std::string response_data;
bnc691fda62016-08-12 00:43:1614494 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]65041fa2010-05-21 06:56:5314495 EXPECT_EQ("hello world", response_data);
14496
14497 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214498 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]65041fa2010-05-21 06:56:5314499}
[email protected]26ef6582010-06-24 02:30:4714500
bnc55ff9da2015-08-19 18:42:3514501// Simulate the SSL handshake completing with an NPN negotiation followed by an
14502// immediate server closing of the socket.
14503// Regression test for https://crbug.com/46369.
bncd16676a2016-07-20 16:23:0114504TEST_F(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:4714505 HttpRequestInfo request;
14506 request.method = "GET";
bncce36dca22015-04-21 22:11:2314507 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1014508 request.traffic_annotation =
14509 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]26ef6582010-06-24 02:30:4714510
[email protected]8ddf8322012-02-23 18:08:0614511 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614512 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0714513 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4714514
Ryan Hamilton0239aac2018-05-19 00:03:1314515 spdy::SpdySerializedFrame req(
14516 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4114517 MockWrite spdy_writes[] = {CreateMockWrite(req, 1)};
[email protected]26ef6582010-06-24 02:30:4714518
14519 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0614520 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4714521 };
14522
Ryan Sleevib8d7ea02018-05-07 20:01:0114523 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0714524 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4714525
[email protected]49639fa2011-12-20 23:22:4114526 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4714527
danakj1fd259a02016-04-16 03:17:0914528 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614529 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]26ef6582010-06-24 02:30:4714530
tfarina42834112016-09-22 13:38:2014531 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114532 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14533 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]26ef6582010-06-24 02:30:4714534}
[email protected]65d34382010-07-01 18:12:2614535
[email protected]795cbf82013-07-22 09:37:2714536// A subclass of HttpAuthHandlerMock that records the request URL when
14537// it gets it. This is needed since the auth handler may get destroyed
14538// before we get a chance to query it.
14539class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
14540 public:
14541 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
14542
Chris Watkins7a41d3552017-12-01 02:13:2714543 ~UrlRecordingHttpAuthHandlerMock() override = default;
[email protected]795cbf82013-07-22 09:37:2714544
14545 protected:
dchengb03027d2014-10-21 12:00:2014546 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
14547 const HttpRequestInfo* request,
Bence Béky7236fb72018-08-01 14:35:0914548 CompletionOnceCallback callback,
dchengb03027d2014-10-21 12:00:2014549 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2714550 *url_ = request->url;
14551 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
Bence Béky7236fb72018-08-01 14:35:0914552 credentials, request, std::move(callback), auth_token);
[email protected]795cbf82013-07-22 09:37:2714553 }
14554
14555 private:
14556 GURL* url_;
14557};
14558
[email protected]8e6441ca2010-08-19 05:56:3814559// Test that if we cancel the transaction as the connection is completing, that
14560// everything tears down correctly.
bncd16676a2016-07-20 16:23:0114561TEST_F(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3814562 // Setup everything about the connection to complete synchronously, so that
14563 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
14564 // for is the callback from the HttpStreamRequest.
14565 // Then cancel the transaction.
14566 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3614567 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3814568 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0614569 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
14570 MockRead(SYNCHRONOUS, "hello world"),
14571 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3814572 };
14573
[email protected]8e6441ca2010-08-19 05:56:3814574 HttpRequestInfo request;
14575 request.method = "GET";
bncce36dca22015-04-21 22:11:2314576 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1014577 request.traffic_annotation =
14578 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8e6441ca2010-08-19 05:56:3814579
danakj1fd259a02016-04-16 03:17:0914580 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5814581 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1914582 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2714583
Ryan Sleevib8d7ea02018-05-07 20:01:0114584 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]8e6441ca2010-08-19 05:56:3814585 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0714586 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3814587
[email protected]49639fa2011-12-20 23:22:4114588 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3814589
vishal.b62985ca92015-04-17 08:45:5114590 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4114591 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114592 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8e6441ca2010-08-19 05:56:3814593 trans.reset(); // Cancel the transaction here.
14594
fdoray92e35a72016-06-10 15:54:5514595 base::RunLoop().RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3014596}
14597
[email protected]ecab6e052014-05-16 14:58:1214598// Test that if a transaction is cancelled after receiving the headers, the
14599// stream is drained properly and added back to the socket pool. The main
14600// purpose of this test is to make sure that an HttpStreamParser can be read
14601// from after the HttpNetworkTransaction and the objects it owns have been
14602// deleted.
14603// See http://crbug.com/368418
bncd16676a2016-07-20 16:23:0114604TEST_F(HttpNetworkTransactionTest, CancelAfterHeaders) {
[email protected]ecab6e052014-05-16 14:58:1214605 MockRead data_reads[] = {
14606 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
14607 MockRead(ASYNC, "Content-Length: 2\r\n"),
14608 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
14609 MockRead(ASYNC, "1"),
14610 // 2 async reads are necessary to trigger a ReadResponseBody call after the
14611 // HttpNetworkTransaction has been deleted.
14612 MockRead(ASYNC, "2"),
14613 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
14614 };
Ryan Sleevib8d7ea02018-05-07 20:01:0114615 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]ecab6e052014-05-16 14:58:1214616 session_deps_.socket_factory->AddSocketDataProvider(&data);
14617
danakj1fd259a02016-04-16 03:17:0914618 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]ecab6e052014-05-16 14:58:1214619
14620 {
14621 HttpRequestInfo request;
14622 request.method = "GET";
bncce36dca22015-04-21 22:11:2314623 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1014624 request.traffic_annotation =
14625 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ecab6e052014-05-16 14:58:1214626
dcheng48459ac22014-08-26 00:46:4114627 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1214628 TestCompletionCallback callback;
14629
tfarina42834112016-09-22 13:38:2014630 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114631 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ecab6e052014-05-16 14:58:1214632 callback.WaitForResult();
14633
14634 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214635 ASSERT_TRUE(response);
14636 EXPECT_TRUE(response->headers);
[email protected]ecab6e052014-05-16 14:58:1214637 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
14638
14639 // The transaction and HttpRequestInfo are deleted.
14640 }
14641
14642 // Let the HttpResponseBodyDrainer drain the socket.
fdoray92e35a72016-06-10 15:54:5514643 base::RunLoop().RunUntilIdle();
[email protected]ecab6e052014-05-16 14:58:1214644
14645 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4114646 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1214647}
14648
[email protected]76a505b2010-08-25 06:23:0014649// Test a basic GET request through a proxy.
bncd16676a2016-07-20 16:23:0114650TEST_F(HttpNetworkTransactionTest, ProxyGet) {
Lily Houghton8c2f97d2018-01-22 05:06:5914651 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4914652 ProxyResolutionService::CreateFixedFromPacResult(
14653 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5114654 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714655 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0914656 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0014657
[email protected]76a505b2010-08-25 06:23:0014658 HttpRequestInfo request;
14659 request.method = "GET";
bncce36dca22015-04-21 22:11:2314660 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1014661 request.traffic_annotation =
14662 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0014663
14664 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2314665 MockWrite(
14666 "GET http://www.example.org/ HTTP/1.1\r\n"
14667 "Host: www.example.org\r\n"
14668 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014669 };
14670
14671 MockRead data_reads1[] = {
14672 MockRead("HTTP/1.1 200 OK\r\n"),
14673 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14674 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0614675 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0014676 };
14677
Ryan Sleevib8d7ea02018-05-07 20:01:0114678 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:0714679 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0014680
[email protected]49639fa2011-12-20 23:22:4114681 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0014682
bnc691fda62016-08-12 00:43:1614683 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0914684 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1614685 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0914686 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
14687 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5014688
bnc691fda62016-08-12 00:43:1614689 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114690 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0014691
14692 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0114693 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:0014694
bnc691fda62016-08-12 00:43:1614695 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214696 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0014697
14698 EXPECT_TRUE(response->headers->IsKeepAlive());
14699 EXPECT_EQ(200, response->headers->response_code());
14700 EXPECT_EQ(100, response->headers->GetContentLength());
14701 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4714702 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
14703 HostPortPair::FromString("myproxy:70")),
14704 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0914705 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
14706 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
14707 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0014708 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2014709
14710 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1614711 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2014712 TestLoadTimingNotReusedWithPac(load_timing_info,
14713 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0014714}
14715
14716// Test a basic HTTPS GET request through a proxy.
bncd16676a2016-07-20 16:23:0114717TEST_F(HttpNetworkTransactionTest, ProxyTunnelGet) {
Lily Houghton8c2f97d2018-01-22 05:06:5914718 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4914719 ProxyResolutionService::CreateFixedFromPacResult(
14720 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5114721 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714722 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0914723 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0014724
[email protected]76a505b2010-08-25 06:23:0014725 HttpRequestInfo request;
14726 request.method = "GET";
bncce36dca22015-04-21 22:11:2314727 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1014728 request.traffic_annotation =
14729 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0014730
14731 // Since we have proxy, should try to establish tunnel.
14732 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1714733 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
14734 "Host: www.example.org:443\r\n"
14735 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014736
rsleevidb16bb02015-11-12 23:47:1714737 MockWrite("GET / HTTP/1.1\r\n"
14738 "Host: www.example.org\r\n"
14739 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014740 };
14741
14742 MockRead data_reads1[] = {
14743 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
14744
14745 MockRead("HTTP/1.1 200 OK\r\n"),
14746 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14747 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0614748 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0014749 };
14750
Ryan Sleevib8d7ea02018-05-07 20:01:0114751 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:0714752 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0614753 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0714754 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0014755
[email protected]49639fa2011-12-20 23:22:4114756 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0014757
bnc691fda62016-08-12 00:43:1614758 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0914759 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1614760 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0914761 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
14762 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5014763
bnc691fda62016-08-12 00:43:1614764 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114765 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0014766
14767 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0114768 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:4614769 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4014770 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0014771 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014772 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
14773 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0014774 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4014775 entries, pos,
mikecirone8b85c432016-09-08 19:11:0014776 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
14777 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0014778
bnc691fda62016-08-12 00:43:1614779 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214780 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0014781
14782 EXPECT_TRUE(response->headers->IsKeepAlive());
14783 EXPECT_EQ(200, response->headers->response_code());
14784 EXPECT_EQ(100, response->headers->GetContentLength());
14785 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
14786 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4714787 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
14788 HostPortPair::FromString("myproxy:70")),
14789 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0914790 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
14791 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
14792 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]029c83b62013-01-24 05:28:2014793
14794 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1614795 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2014796 TestLoadTimingNotReusedWithPac(load_timing_info,
14797 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0014798}
14799
rsleevidb16bb02015-11-12 23:47:1714800// Test a basic HTTPS GET request through a proxy, connecting to an IPv6
14801// literal host.
bncd16676a2016-07-20 16:23:0114802TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetIPv6) {
Lily Houghton8c2f97d2018-01-22 05:06:5914803 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4914804 ProxyResolutionService::CreateFixedFromPacResult(
14805 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
rsleevidb16bb02015-11-12 23:47:1714806 BoundTestNetLog log;
14807 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0914808 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
rsleevidb16bb02015-11-12 23:47:1714809
14810 HttpRequestInfo request;
14811 request.method = "GET";
Eric Romanda790f92018-11-07 19:17:1514812 request.url = GURL("https://[::2]:443/");
Ramin Halavatib5e433e62018-02-07 07:41:1014813 request.traffic_annotation =
14814 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rsleevidb16bb02015-11-12 23:47:1714815
14816 // Since we have proxy, should try to establish tunnel.
14817 MockWrite data_writes1[] = {
Eric Romanda790f92018-11-07 19:17:1514818 MockWrite("CONNECT [::2]:443 HTTP/1.1\r\n"
14819 "Host: [::2]:443\r\n"
rsleevidb16bb02015-11-12 23:47:1714820 "Proxy-Connection: keep-alive\r\n\r\n"),
14821
14822 MockWrite("GET / HTTP/1.1\r\n"
Eric Romanda790f92018-11-07 19:17:1514823 "Host: [::2]\r\n"
rsleevidb16bb02015-11-12 23:47:1714824 "Connection: keep-alive\r\n\r\n"),
14825 };
14826
14827 MockRead data_reads1[] = {
14828 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
14829
14830 MockRead("HTTP/1.1 200 OK\r\n"),
14831 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14832 MockRead("Content-Length: 100\r\n\r\n"),
14833 MockRead(SYNCHRONOUS, OK),
14834 };
14835
Ryan Sleevib8d7ea02018-05-07 20:01:0114836 StaticSocketDataProvider data1(data_reads1, data_writes1);
rsleevidb16bb02015-11-12 23:47:1714837 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14838 SSLSocketDataProvider ssl(ASYNC, OK);
14839 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14840
14841 TestCompletionCallback callback1;
14842
bnc691fda62016-08-12 00:43:1614843 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
rsleevidb16bb02015-11-12 23:47:1714844
bnc691fda62016-08-12 00:43:1614845 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114846 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rsleevidb16bb02015-11-12 23:47:1714847
14848 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0114849 EXPECT_THAT(rv, IsOk());
rsleevidb16bb02015-11-12 23:47:1714850 TestNetLogEntry::List entries;
14851 log.GetEntries(&entries);
14852 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014853 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
14854 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1714855 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014856 entries, pos,
14857 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
14858 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1714859
bnc691fda62016-08-12 00:43:1614860 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214861 ASSERT_TRUE(response);
rsleevidb16bb02015-11-12 23:47:1714862
14863 EXPECT_TRUE(response->headers->IsKeepAlive());
14864 EXPECT_EQ(200, response->headers->response_code());
14865 EXPECT_EQ(100, response->headers->GetContentLength());
14866 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
14867 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4714868 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
14869 HostPortPair::FromString("myproxy:70")),
14870 response->proxy_server);
rsleevidb16bb02015-11-12 23:47:1714871
14872 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1614873 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
rsleevidb16bb02015-11-12 23:47:1714874 TestLoadTimingNotReusedWithPac(load_timing_info,
14875 CONNECT_TIMING_HAS_SSL_TIMES);
14876}
14877
[email protected]76a505b2010-08-25 06:23:0014878// Test a basic HTTPS GET request through a proxy, but the server hangs up
14879// while establishing the tunnel.
bncd16676a2016-07-20 16:23:0114880TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
Ramin Halavatica8d5252018-03-12 05:33:4914881 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
14882 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5114883 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714884 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0914885 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0014886
[email protected]76a505b2010-08-25 06:23:0014887 HttpRequestInfo request;
14888 request.method = "GET";
bncce36dca22015-04-21 22:11:2314889 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1014890 request.traffic_annotation =
14891 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0014892
14893 // Since we have proxy, should try to establish tunnel.
14894 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1714895 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
14896 "Host: www.example.org:443\r\n"
14897 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014898
rsleevidb16bb02015-11-12 23:47:1714899 MockWrite("GET / HTTP/1.1\r\n"
14900 "Host: www.example.org\r\n"
14901 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014902 };
14903
14904 MockRead data_reads1[] = {
[email protected]76a505b2010-08-25 06:23:0014905 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0614906 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0014907 };
14908
Ryan Sleevib8d7ea02018-05-07 20:01:0114909 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:0714910 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0614911 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0714912 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0014913
[email protected]49639fa2011-12-20 23:22:4114914 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0014915
bnc691fda62016-08-12 00:43:1614916 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5014917
bnc691fda62016-08-12 00:43:1614918 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114919 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0014920
14921 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0114922 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
mmenke43758e62015-05-04 21:09:4614923 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4014924 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0014925 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014926 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
14927 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0014928 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4014929 entries, pos,
mikecirone8b85c432016-09-08 19:11:0014930 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
14931 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0014932}
14933
[email protected]749eefa82010-09-13 22:14:0314934// Test for crbug.com/55424.
bncd16676a2016-07-20 16:23:0114935TEST_F(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
Ryan Hamilton0239aac2018-05-19 00:03:1314936 spdy::SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4914937 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4114938 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]749eefa82010-09-13 22:14:0314939
Ryan Hamilton0239aac2018-05-19 00:03:1314940 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
14941 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0314942 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114943 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0314944 };
14945
Ryan Sleevib8d7ea02018-05-07 20:01:0114946 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0714947 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0314948
[email protected]8ddf8322012-02-23 18:08:0614949 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614950 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0714951 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0314952
danakj1fd259a02016-04-16 03:17:0914953 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0314954
14955 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2314956 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4014957 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
Matt Menke2436b2f2018-12-11 18:07:1114958 PRIVACY_MODE_DISABLED,
14959 SpdySessionKey::IsProxySession::kFalse, SocketTag());
[email protected]795cbf82013-07-22 09:37:2714960 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:5214961 CreateSpdySession(session.get(), key, NetLogWithSource());
[email protected]749eefa82010-09-13 22:14:0314962
14963 HttpRequestInfo request;
14964 request.method = "GET";
bncce36dca22015-04-21 22:11:2314965 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1014966 request.traffic_annotation =
14967 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]749eefa82010-09-13 22:14:0314968
bnc691fda62016-08-12 00:43:1614969 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]749eefa82010-09-13 22:14:0314970
[email protected]41d64e82013-07-03 22:44:2614971 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014972 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114973 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14974 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]749eefa82010-09-13 22:14:0314975}
14976
[email protected]73b8dd222010-11-11 19:55:2414977// Given a net error, cause that error to be returned from the first Write()
bnc691fda62016-08-12 00:43:1614978// call and verify that the HttpNetworkTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0214979void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0714980 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2914981 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2714982 request_info.url = GURL("https://www.example.com/");
14983 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914984 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:1014985 request_info.traffic_annotation =
14986 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2714987
[email protected]8ddf8322012-02-23 18:08:0614988 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2914989 MockWrite data_writes[] = {
14990 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2414991 };
Ryan Sleevib8d7ea02018-05-07 20:01:0114992 StaticSocketDataProvider data(base::span<MockRead>(), data_writes);
[email protected]bb88e1d32013-05-03 23:11:0714993 session_deps_.socket_factory->AddSocketDataProvider(&data);
14994 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2414995
danakj1fd259a02016-04-16 03:17:0914996 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614997 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]73b8dd222010-11-11 19:55:2414998
[email protected]49639fa2011-12-20 23:22:4114999 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2015000 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
ttuttle859dc7a2015-04-23 19:42:2915001 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2415002 rv = callback.WaitForResult();
15003 ASSERT_EQ(error, rv);
15004}
15005
bncd16676a2016-07-20 16:23:0115006TEST_F(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2415007 // Just check a grab bag of cert errors.
15008 static const int kErrors[] = {
15009 ERR_CERT_COMMON_NAME_INVALID,
15010 ERR_CERT_AUTHORITY_INVALID,
15011 ERR_CERT_DATE_INVALID,
15012 };
Avi Drissman4365a4782018-12-28 19:26:2415013 for (size_t i = 0; i < base::size(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0615014 CheckErrorIsPassedBack(kErrors[i], ASYNC);
15015 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2415016 }
15017}
15018
[email protected]bd0b6772011-01-11 19:59:3015019// Ensure that a client certificate is removed from the SSL client auth
15020// cache when:
15021// 1) No proxy is involved.
15022// 2) TLS False Start is disabled.
15023// 3) The initial TLS handshake requests a client certificate.
15024// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0115025TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_NoFalseStart) {
ttuttle859dc7a2015-04-23 19:42:2915026 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2715027 request_info.url = GURL("https://www.example.com/");
15028 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2915029 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:1015030 request_info.traffic_annotation =
15031 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2715032
[email protected]bd0b6772011-01-11 19:59:3015033 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4115034 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3015035
15036 // [ssl_]data1 contains the data for the first SSL handshake. When a
15037 // CertificateRequest is received for the first time, the handshake will
15038 // be aborted to allow the caller to provide a certificate.
ttuttle859dc7a2015-04-23 19:42:2915039 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3015040 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715041 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
Ryan Sleevib8d7ea02018-05-07 20:01:0115042 StaticSocketDataProvider data1;
[email protected]bb88e1d32013-05-03 23:11:0715043 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3015044
15045 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
15046 // False Start is not being used, the result of the SSL handshake will be
15047 // returned as part of the SSLClientSocket::Connect() call. This test
15048 // matches the result of a server sending a handshake_failure alert,
15049 // rather than a Finished message, because it requires a client
15050 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2915051 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3015052 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715053 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
Ryan Sleevib8d7ea02018-05-07 20:01:0115054 StaticSocketDataProvider data2;
[email protected]bb88e1d32013-05-03 23:11:0715055 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3015056
15057 // [ssl_]data3 contains the data for the third SSL handshake. When a
15058 // connection to a server fails during an SSL handshake,
Steven Valdez0ef94d02018-11-19 23:28:1315059 // HttpNetworkTransaction will attempt to fallback to TLSv1.2 if the previous
15060 // connection was attempted with TLSv1.3. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3015061 // of the HttpNetworkTransaction. Because this test failure is due to
15062 // requiring a client certificate, this fallback handshake should also
15063 // fail.
ttuttle859dc7a2015-04-23 19:42:2915064 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
Steven Valdez0ef94d02018-11-19 23:28:1315065 ssl_data3.expected_ssl_version_max = SSL_PROTOCOL_VERSION_TLS1_2;
[email protected]bd0b6772011-01-11 19:59:3015066 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715067 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
Ryan Sleevib8d7ea02018-05-07 20:01:0115068 StaticSocketDataProvider data3;
[email protected]bb88e1d32013-05-03 23:11:0715069 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3015070
[email protected]80c75f682012-05-26 16:22:1715071 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
15072 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4215073 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
15074 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]80c75f682012-05-26 16:22:1715075 // of the HttpNetworkTransaction. Because this test failure is due to
15076 // requiring a client certificate, this fallback handshake should also
15077 // fail.
ttuttle859dc7a2015-04-23 19:42:2915078 SSLSocketDataProvider ssl_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1715079 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715080 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
Ryan Sleevib8d7ea02018-05-07 20:01:0115081 StaticSocketDataProvider data4;
[email protected]bb88e1d32013-05-03 23:11:0715082 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1715083
danakj1fd259a02016-04-16 03:17:0915084 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615085 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3015086
[email protected]bd0b6772011-01-11 19:59:3015087 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4115088 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2015089 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115090 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3015091
15092 // Complete the SSL handshake, which should abort due to requiring a
15093 // client certificate.
15094 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115095 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3015096
15097 // Indicate that no certificate should be supplied. From the perspective
15098 // of SSLClientCertCache, NULL is just as meaningful as a real
15099 // certificate, so this is the same as supply a
15100 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1615101 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0115102 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3015103
15104 // Ensure the certificate was added to the client auth cache before
15105 // allowing the connection to continue restarting.
15106 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5415107 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4115108 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415109 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5215110 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3015111
15112 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1715113 // then consume ssl_data3 and ssl_data4, both of which should also fail.
15114 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3015115 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115116 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3015117
15118 // Ensure that the client certificate is removed from the cache on a
15119 // handshake failure.
[email protected]791879c2013-12-17 07:22:4115120 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415121 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3015122}
15123
15124// Ensure that a client certificate is removed from the SSL client auth
15125// cache when:
15126// 1) No proxy is involved.
15127// 2) TLS False Start is enabled.
15128// 3) The initial TLS handshake requests a client certificate.
15129// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0115130TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2915131 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2715132 request_info.url = GURL("https://www.example.com/");
15133 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2915134 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:1015135 request_info.traffic_annotation =
15136 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2715137
[email protected]bd0b6772011-01-11 19:59:3015138 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4115139 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3015140
15141 // When TLS False Start is used, SSLClientSocket::Connect() calls will
15142 // return successfully after reading up to the peer's Certificate message.
15143 // This is to allow the caller to call SSLClientSocket::Write(), which can
15144 // enqueue application data to be sent in the same packet as the
15145 // ChangeCipherSpec and Finished messages.
15146 // The actual handshake will be finished when SSLClientSocket::Read() is
15147 // called, which expects to process the peer's ChangeCipherSpec and
15148 // Finished messages. If there was an error negotiating with the peer,
15149 // such as due to the peer requiring a client certificate when none was
15150 // supplied, the alert sent by the peer won't be processed until Read() is
15151 // called.
15152
15153 // Like the non-False Start case, when a client certificate is requested by
15154 // the peer, the handshake is aborted during the Connect() call.
15155 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2915156 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3015157 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715158 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
Ryan Sleevib8d7ea02018-05-07 20:01:0115159 StaticSocketDataProvider data1;
[email protected]bb88e1d32013-05-03 23:11:0715160 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3015161
15162 // When a client certificate is supplied, Connect() will not be aborted
15163 // when the peer requests the certificate. Instead, the handshake will
15164 // artificially succeed, allowing the caller to write the HTTP request to
15165 // the socket. The handshake messages are not processed until Read() is
15166 // called, which then detects that the handshake was aborted, due to the
15167 // peer sending a handshake_failure because it requires a client
15168 // certificate.
ttuttle859dc7a2015-04-23 19:42:2915169 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3015170 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715171 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2915172 MockRead data2_reads[] = {
15173 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3015174 };
Ryan Sleevib8d7ea02018-05-07 20:01:0115175 StaticSocketDataProvider data2(data2_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0715176 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3015177
15178 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1715179 // the data for the SSL handshake once the TLSv1.1 connection falls back to
15180 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2915181 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3015182 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715183 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
Ryan Sleevib8d7ea02018-05-07 20:01:0115184 StaticSocketDataProvider data3(data2_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0715185 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3015186
[email protected]80c75f682012-05-26 16:22:1715187 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
15188 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2915189 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1715190 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715191 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
Ryan Sleevib8d7ea02018-05-07 20:01:0115192 StaticSocketDataProvider data4(data2_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0715193 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1715194
[email protected]7799de12013-05-30 05:52:5115195 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2915196 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5115197 ssl_data5.cert_request_info = cert_request.get();
15198 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
Ryan Sleevib8d7ea02018-05-07 20:01:0115199 StaticSocketDataProvider data5(data2_reads, base::span<MockWrite>());
[email protected]7799de12013-05-30 05:52:5115200 session_deps_.socket_factory->AddSocketDataProvider(&data5);
15201
danakj1fd259a02016-04-16 03:17:0915202 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615203 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3015204
[email protected]bd0b6772011-01-11 19:59:3015205 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4115206 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2015207 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115208 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3015209
15210 // Complete the SSL handshake, which should abort due to requiring a
15211 // client certificate.
15212 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115213 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3015214
15215 // Indicate that no certificate should be supplied. From the perspective
15216 // of SSLClientCertCache, NULL is just as meaningful as a real
15217 // certificate, so this is the same as supply a
15218 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1615219 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0115220 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3015221
15222 // Ensure the certificate was added to the client auth cache before
15223 // allowing the connection to continue restarting.
15224 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5415225 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4115226 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415227 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5215228 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3015229
[email protected]bd0b6772011-01-11 19:59:3015230 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1715231 // then consume ssl_data3 and ssl_data4, both of which should also fail.
15232 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3015233 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115234 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3015235
15236 // Ensure that the client certificate is removed from the cache on a
15237 // handshake failure.
[email protected]791879c2013-12-17 07:22:4115238 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415239 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3015240}
15241
[email protected]8c405132011-01-11 22:03:1815242// Ensure that a client certificate is removed from the SSL client auth
15243// cache when:
15244// 1) An HTTPS proxy is involved.
15245// 3) The HTTPS proxy requests a client certificate.
15246// 4) The client supplies an invalid/unacceptable certificate for the
15247// proxy.
15248// The test is repeated twice, first for connecting to an HTTPS endpoint,
15249// then for connecting to an HTTP endpoint.
bncd16676a2016-07-20 16:23:0115250TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
Ramin Halavatica8d5252018-03-12 05:33:4915251 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
15252 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5115253 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0715254 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1815255
15256 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4115257 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1815258
15259 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
15260 // [ssl_]data[1-3]. Rather than represending the endpoint
15261 // (www.example.com:443), they represent failures with the HTTPS proxy
15262 // (proxy:70).
ttuttle859dc7a2015-04-23 19:42:2915263 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1815264 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715265 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
Ryan Sleevib8d7ea02018-05-07 20:01:0115266 StaticSocketDataProvider data1;
[email protected]bb88e1d32013-05-03 23:11:0715267 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1815268
ttuttle859dc7a2015-04-23 19:42:2915269 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1815270 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715271 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
Ryan Sleevib8d7ea02018-05-07 20:01:0115272 StaticSocketDataProvider data2;
[email protected]bb88e1d32013-05-03 23:11:0715273 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1815274
[email protected]80c75f682012-05-26 16:22:1715275 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
15276#if 0
ttuttle859dc7a2015-04-23 19:42:2915277 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1815278 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715279 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
Ryan Sleevib8d7ea02018-05-07 20:01:0115280 StaticSocketDataProvider data3;
[email protected]bb88e1d32013-05-03 23:11:0715281 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1715282#endif
[email protected]8c405132011-01-11 22:03:1815283
ttuttle859dc7a2015-04-23 19:42:2915284 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1815285 requests[0].url = GURL("https://www.example.com/");
15286 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2915287 requests[0].load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:1015288 requests[0].traffic_annotation =
15289 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c405132011-01-11 22:03:1815290
15291 requests[1].url = GURL("http://www.example.com/");
15292 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2915293 requests[1].load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:1015294 requests[1].traffic_annotation =
15295 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c405132011-01-11 22:03:1815296
Avi Drissman4365a4782018-12-28 19:26:2415297 for (size_t i = 0; i < base::size(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0715298 session_deps_.socket_factory->ResetNextMockIndexes();
danakj1fd259a02016-04-16 03:17:0915299 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615300 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]8c405132011-01-11 22:03:1815301
15302 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4115303 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2015304 int rv = trans.Start(&requests[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115305 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1815306
15307 // Complete the SSL handshake, which should abort due to requiring a
15308 // client certificate.
15309 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115310 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]8c405132011-01-11 22:03:1815311
15312 // Indicate that no certificate should be supplied. From the perspective
15313 // of SSLClientCertCache, NULL is just as meaningful as a real
15314 // certificate, so this is the same as supply a
15315 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1615316 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0115317 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1815318
15319 // Ensure the certificate was added to the client auth cache before
15320 // allowing the connection to continue restarting.
15321 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5415322 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4115323 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415324 HostPortPair("proxy", 70), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5215325 ASSERT_FALSE(client_cert);
[email protected]8c405132011-01-11 22:03:1815326 // Ensure the certificate was NOT cached for the endpoint. This only
15327 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4115328 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415329 HostPortPair("www.example.com", 443), &client_cert,
15330 &client_private_key));
[email protected]8c405132011-01-11 22:03:1815331
15332 // Restart the handshake. This will consume ssl_data2, which fails, and
15333 // then consume ssl_data3, which should also fail. The result code is
15334 // checked against what ssl_data3 should return.
15335 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115336 ASSERT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]8c405132011-01-11 22:03:1815337
15338 // Now that the new handshake has failed, ensure that the client
15339 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4115340 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415341 HostPortPair("proxy", 70), &client_cert, &client_private_key));
[email protected]791879c2013-12-17 07:22:4115342 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415343 HostPortPair("www.example.com", 443), &client_cert,
15344 &client_private_key));
[email protected]8c405132011-01-11 22:03:1815345 }
15346}
15347
bncd16676a2016-07-20 16:23:0115348TEST_F(HttpNetworkTransactionTest, UseIPConnectionPooling) {
[email protected]e3ceb682011-06-28 23:55:4615349 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1915350 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0915351 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4615352
bnc032658ba2016-09-26 18:17:1515353 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4615354
Ryan Hamilton0239aac2018-05-19 00:03:1315355 spdy::SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4915356 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3815357 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1315358 spdy::SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3715359 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4615360 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115361 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4615362 };
Ryan Hamilton0239aac2018-05-19 00:03:1315363 spdy::SpdySerializedFrame host1_resp(
15364 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
15365 spdy::SpdySerializedFrame host1_resp_body(
bncdf80d44fd2016-07-15 20:27:4115366 spdy_util_.ConstructSpdyDataFrame(1, true));
Ryan Hamilton0239aac2018-05-19 00:03:1315367 spdy::SpdySerializedFrame host2_resp(
15368 spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
15369 spdy::SpdySerializedFrame host2_resp_body(
bncdf80d44fd2016-07-15 20:27:4115370 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4615371 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115372 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
15373 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1315374 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4615375 };
15376
eroman36d84e54432016-03-17 03:23:0215377 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0215378 MockConnect connect(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115379 SequencedSocketData spdy_data(connect, spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0715380 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4615381
[email protected]aa22b242011-11-16 18:58:2915382 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4615383 HttpRequestInfo request1;
15384 request1.method = "GET";
bncce36dca22015-04-21 22:11:2315385 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4615386 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015387 request1.traffic_annotation =
15388 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015389 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4615390
tfarina42834112016-09-22 13:38:2015391 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115392 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15393 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615394
15395 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5215396 ASSERT_TRUE(response);
15397 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215398 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4615399
15400 std::string response_data;
robpercival214763f2016-07-01 23:27:0115401 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615402 EXPECT_EQ("hello!", response_data);
15403
bnca4d611d2016-09-22 19:55:3715404 // Preload mail.example.com into HostCache.
15405 HostPortPair host_port("mail.example.com", 443);
[email protected]5109c1952013-08-20 18:44:1015406 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4615407 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1015408 std::unique_ptr<HostResolver::Request> request;
15409 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
15410 &ignored, callback.callback(),
tfarina42834112016-09-22 13:38:2015411 &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115412 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4715413 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115414 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4615415
15416 HttpRequestInfo request2;
15417 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3715418 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4615419 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015420 request2.traffic_annotation =
15421 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015422 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4615423
tfarina42834112016-09-22 13:38:2015424 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115425 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15426 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615427
15428 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215429 ASSERT_TRUE(response);
15430 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215431 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4615432 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215433 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115434 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615435 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4615436}
15437
bncd16676a2016-07-20 16:23:0115438TEST_F(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d2b5f092012-06-08 23:55:0215439 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1915440 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0915441 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0215442
bnc032658ba2016-09-26 18:17:1515443 AddSSLSocketData();
[email protected]d2b5f092012-06-08 23:55:0215444
Ryan Hamilton0239aac2018-05-19 00:03:1315445 spdy::SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4915446 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3815447 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1315448 spdy::SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3715449 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0215450 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115451 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0215452 };
Ryan Hamilton0239aac2018-05-19 00:03:1315453 spdy::SpdySerializedFrame host1_resp(
15454 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
15455 spdy::SpdySerializedFrame host1_resp_body(
bncdf80d44fd2016-07-15 20:27:4115456 spdy_util_.ConstructSpdyDataFrame(1, true));
Ryan Hamilton0239aac2018-05-19 00:03:1315457 spdy::SpdySerializedFrame host2_resp(
15458 spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
15459 spdy::SpdySerializedFrame host2_resp_body(
bncdf80d44fd2016-07-15 20:27:4115460 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0215461 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115462 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
15463 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1315464 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0215465 };
15466
eroman36d84e54432016-03-17 03:23:0215467 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0215468 MockConnect connect(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115469 SequencedSocketData spdy_data(connect, spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0715470 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0215471
15472 TestCompletionCallback callback;
15473 HttpRequestInfo request1;
15474 request1.method = "GET";
bncce36dca22015-04-21 22:11:2315475 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0215476 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015477 request1.traffic_annotation =
15478 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015479 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0215480
tfarina42834112016-09-22 13:38:2015481 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115482 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15483 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0215484
15485 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5215486 ASSERT_TRUE(response);
15487 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215488 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0215489
15490 std::string response_data;
robpercival214763f2016-07-01 23:27:0115491 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0215492 EXPECT_EQ("hello!", response_data);
15493
15494 HttpRequestInfo request2;
15495 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3715496 request2.url = GURL("https://mail.example.com/");
[email protected]d2b5f092012-06-08 23:55:0215497 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015498 request2.traffic_annotation =
15499 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015500 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0215501
tfarina42834112016-09-22 13:38:2015502 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115503 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15504 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0215505
15506 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215507 ASSERT_TRUE(response);
15508 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215509 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0215510 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215511 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115512 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0215513 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0215514}
15515
bnc8016c1f2017-03-31 02:11:2915516// Regression test for https://crbug.com/546991.
15517// The server might not be able to serve an IP pooled request, and might send a
15518// 421 Misdirected Request response status to indicate this.
15519// HttpNetworkTransaction should reset the request and retry without IP pooling.
15520TEST_F(HttpNetworkTransactionTest, RetryWithoutConnectionPooling) {
15521 // Two hosts resolve to the same IP address.
15522 const std::string ip_addr = "1.2.3.4";
15523 IPAddress ip;
15524 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
15525 IPEndPoint peer_addr = IPEndPoint(ip, 443);
15526
Jeremy Roman0579ed62017-08-29 15:56:1915527 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
bnc8016c1f2017-03-31 02:11:2915528 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
15529 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
15530
15531 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15532
15533 // Two requests on the first connection.
Ryan Hamilton0239aac2018-05-19 00:03:1315534 spdy::SpdySerializedFrame req1(
bnc8016c1f2017-03-31 02:11:2915535 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
15536 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1315537 spdy::SpdySerializedFrame req2(
bnc8016c1f2017-03-31 02:11:2915538 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1315539 spdy::SpdySerializedFrame rst(
15540 spdy_util_.ConstructSpdyRstStream(3, spdy::ERROR_CODE_CANCEL));
bnc8016c1f2017-03-31 02:11:2915541 MockWrite writes1[] = {
15542 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
15543 CreateMockWrite(rst, 6),
15544 };
15545
15546 // The first one succeeds, the second gets error 421 Misdirected Request.
Ryan Hamilton0239aac2018-05-19 00:03:1315547 spdy::SpdySerializedFrame resp1(
15548 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
15549 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
15550 spdy::SpdyHeaderBlock response_headers;
15551 response_headers[spdy::kHttp2StatusHeader] = "421";
15552 spdy::SpdySerializedFrame resp2(
bnc8016c1f2017-03-31 02:11:2915553 spdy_util_.ConstructSpdyReply(3, std::move(response_headers)));
15554 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
15555 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
15556
15557 MockConnect connect1(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115558 SequencedSocketData data1(connect1, reads1, writes1);
bnc8016c1f2017-03-31 02:11:2915559 session_deps_.socket_factory->AddSocketDataProvider(&data1);
15560
15561 AddSSLSocketData();
15562
15563 // Retry the second request on a second connection.
15564 SpdyTestUtil spdy_util2;
Ryan Hamilton0239aac2018-05-19 00:03:1315565 spdy::SpdySerializedFrame req3(
bnc8016c1f2017-03-31 02:11:2915566 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
15567 MockWrite writes2[] = {
15568 CreateMockWrite(req3, 0),
15569 };
15570
Ryan Hamilton0239aac2018-05-19 00:03:1315571 spdy::SpdySerializedFrame resp3(
15572 spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
15573 spdy::SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
bnc8016c1f2017-03-31 02:11:2915574 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
15575 MockRead(ASYNC, 0, 3)};
15576
15577 MockConnect connect2(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115578 SequencedSocketData data2(connect2, reads2, writes2);
bnc8016c1f2017-03-31 02:11:2915579 session_deps_.socket_factory->AddSocketDataProvider(&data2);
15580
15581 AddSSLSocketData();
15582
15583 // Preload mail.example.org into HostCache.
15584 HostPortPair host_port("mail.example.org", 443);
15585 HostResolver::RequestInfo resolve_info(host_port);
15586 AddressList ignored;
15587 std::unique_ptr<HostResolver::Request> request;
15588 TestCompletionCallback callback;
15589 int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
15590 &ignored, callback.callback(),
15591 &request, NetLogWithSource());
15592 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15593 rv = callback.WaitForResult();
15594 EXPECT_THAT(rv, IsOk());
15595
15596 HttpRequestInfo request1;
15597 request1.method = "GET";
15598 request1.url = GURL("https://www.example.org/");
15599 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015600 request1.traffic_annotation =
15601 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8016c1f2017-03-31 02:11:2915602 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
15603
15604 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
15605 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15606 rv = callback.WaitForResult();
15607 EXPECT_THAT(rv, IsOk());
15608
15609 const HttpResponseInfo* response = trans1.GetResponseInfo();
15610 ASSERT_TRUE(response);
15611 ASSERT_TRUE(response->headers);
15612 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
15613 EXPECT_TRUE(response->was_fetched_via_spdy);
15614 EXPECT_TRUE(response->was_alpn_negotiated);
15615 std::string response_data;
15616 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
15617 EXPECT_EQ("hello!", response_data);
15618
15619 HttpRequestInfo request2;
15620 request2.method = "GET";
15621 request2.url = GURL("https://mail.example.org/");
15622 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015623 request2.traffic_annotation =
15624 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8016c1f2017-03-31 02:11:2915625 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
15626
15627 BoundTestNetLog log;
15628 rv = trans2.Start(&request2, callback.callback(), log.bound());
15629 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15630 rv = callback.WaitForResult();
15631 EXPECT_THAT(rv, IsOk());
15632
15633 response = trans2.GetResponseInfo();
15634 ASSERT_TRUE(response);
15635 ASSERT_TRUE(response->headers);
15636 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
15637 EXPECT_TRUE(response->was_fetched_via_spdy);
15638 EXPECT_TRUE(response->was_alpn_negotiated);
15639 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
15640 EXPECT_EQ("hello!", response_data);
15641
15642 TestNetLogEntry::List entries;
15643 log.GetEntries(&entries);
davidbence688ae2017-05-04 15:12:5915644 ExpectLogContainsSomewhere(
15645 entries, 0, NetLogEventType::HTTP_TRANSACTION_RESTART_MISDIRECTED_REQUEST,
bnc8016c1f2017-03-31 02:11:2915646 NetLogEventPhase::NONE);
davidbence688ae2017-05-04 15:12:5915647}
15648
15649// Test that HTTP 421 responses are properly returned to the caller if received
15650// on the retry as well. HttpNetworkTransaction should not infinite loop or lose
15651// portions of the response.
15652TEST_F(HttpNetworkTransactionTest, ReturnHTTP421OnRetry) {
15653 // Two hosts resolve to the same IP address.
15654 const std::string ip_addr = "1.2.3.4";
15655 IPAddress ip;
15656 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
15657 IPEndPoint peer_addr = IPEndPoint(ip, 443);
15658
Jeremy Roman0579ed62017-08-29 15:56:1915659 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
davidbence688ae2017-05-04 15:12:5915660 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
15661 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
15662
15663 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15664
15665 // Two requests on the first connection.
Ryan Hamilton0239aac2018-05-19 00:03:1315666 spdy::SpdySerializedFrame req1(
davidbence688ae2017-05-04 15:12:5915667 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
15668 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1315669 spdy::SpdySerializedFrame req2(
davidbence688ae2017-05-04 15:12:5915670 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1315671 spdy::SpdySerializedFrame rst(
15672 spdy_util_.ConstructSpdyRstStream(3, spdy::ERROR_CODE_CANCEL));
davidbence688ae2017-05-04 15:12:5915673 MockWrite writes1[] = {
15674 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
15675 CreateMockWrite(rst, 6),
15676 };
15677
15678 // The first one succeeds, the second gets error 421 Misdirected Request.
Ryan Hamilton0239aac2018-05-19 00:03:1315679 spdy::SpdySerializedFrame resp1(
15680 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
15681 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
15682 spdy::SpdyHeaderBlock response_headers;
15683 response_headers[spdy::kHttp2StatusHeader] = "421";
15684 spdy::SpdySerializedFrame resp2(
davidbence688ae2017-05-04 15:12:5915685 spdy_util_.ConstructSpdyReply(3, response_headers.Clone()));
15686 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
15687 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
15688
15689 MockConnect connect1(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115690 SequencedSocketData data1(connect1, reads1, writes1);
davidbence688ae2017-05-04 15:12:5915691 session_deps_.socket_factory->AddSocketDataProvider(&data1);
15692
15693 AddSSLSocketData();
15694
15695 // Retry the second request on a second connection. It returns 421 Misdirected
15696 // Retry again.
15697 SpdyTestUtil spdy_util2;
Ryan Hamilton0239aac2018-05-19 00:03:1315698 spdy::SpdySerializedFrame req3(
davidbence688ae2017-05-04 15:12:5915699 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
15700 MockWrite writes2[] = {
15701 CreateMockWrite(req3, 0),
15702 };
15703
Ryan Hamilton0239aac2018-05-19 00:03:1315704 spdy::SpdySerializedFrame resp3(
davidbence688ae2017-05-04 15:12:5915705 spdy_util2.ConstructSpdyReply(1, std::move(response_headers)));
Ryan Hamilton0239aac2018-05-19 00:03:1315706 spdy::SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
davidbence688ae2017-05-04 15:12:5915707 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
15708 MockRead(ASYNC, 0, 3)};
15709
15710 MockConnect connect2(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115711 SequencedSocketData data2(connect2, reads2, writes2);
davidbence688ae2017-05-04 15:12:5915712 session_deps_.socket_factory->AddSocketDataProvider(&data2);
15713
15714 AddSSLSocketData();
15715
15716 // Preload mail.example.org into HostCache.
15717 HostPortPair host_port("mail.example.org", 443);
15718 HostResolver::RequestInfo resolve_info(host_port);
15719 AddressList ignored;
15720 std::unique_ptr<HostResolver::Request> request;
15721 TestCompletionCallback callback;
15722 int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
15723 &ignored, callback.callback(),
15724 &request, NetLogWithSource());
15725 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15726 rv = callback.WaitForResult();
15727 EXPECT_THAT(rv, IsOk());
15728
15729 HttpRequestInfo request1;
15730 request1.method = "GET";
15731 request1.url = GURL("https://www.example.org/");
15732 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015733 request1.traffic_annotation =
15734 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
davidbence688ae2017-05-04 15:12:5915735 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
15736
15737 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 Halavatib5e433e62018-02-07 07:41:1015756 request2.traffic_annotation =
15757 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
davidbence688ae2017-05-04 15:12:5915758 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 // After a retry, the 421 Misdirected Request is reported back up to the
15767 // caller.
15768 response = trans2.GetResponseInfo();
15769 ASSERT_TRUE(response);
15770 ASSERT_TRUE(response->headers);
15771 EXPECT_EQ("HTTP/1.1 421", response->headers->GetStatusLine());
15772 EXPECT_TRUE(response->was_fetched_via_spdy);
15773 EXPECT_TRUE(response->was_alpn_negotiated);
15774 EXPECT_TRUE(response->ssl_info.cert);
15775 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
15776 EXPECT_EQ("hello!", response_data);
bnc8016c1f2017-03-31 02:11:2915777}
15778
bnc6dcd8192017-05-25 20:11:5015779class OneTimeCachingHostResolver : public MockHostResolverBase {
[email protected]e3ceb682011-06-28 23:55:4615780 public:
15781 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
bnc6dcd8192017-05-25 20:11:5015782 : MockHostResolverBase(/* use_caching = */ true), host_port_(host_port) {}
Chris Watkins7a41d3552017-12-01 02:13:2715783 ~OneTimeCachingHostResolver() override = default;
[email protected]e3ceb682011-06-28 23:55:4615784
dchengb03027d2014-10-21 12:00:2015785 int ResolveFromCache(const RequestInfo& info,
15786 AddressList* addresses,
tfarina42834112016-09-22 13:38:2015787 const NetLogWithSource& net_log) override {
bnc6dcd8192017-05-25 20:11:5015788 int rv = MockHostResolverBase::ResolveFromCache(info, addresses, net_log);
[email protected]95a214c2011-08-04 21:50:4015789 if (rv == OK && info.host_port_pair().Equals(host_port_))
bnc6dcd8192017-05-25 20:11:5015790 GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4615791 return rv;
15792 }
15793
[email protected]e3ceb682011-06-28 23:55:4615794 private:
[email protected]e3ceb682011-06-28 23:55:4615795 const HostPortPair host_port_;
15796};
15797
bncd16676a2016-07-20 16:23:0115798TEST_F(HttpNetworkTransactionTest,
mmenke5c642132015-06-02 16:05:1315799 UseIPConnectionPoolingWithHostCacheExpiration) {
[email protected]e3ceb682011-06-28 23:55:4615800 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1915801 session_deps_.host_resolver = std::make_unique<OneTimeCachingHostResolver>(
bnca4d611d2016-09-22 19:55:3715802 HostPortPair("mail.example.com", 443));
danakj1fd259a02016-04-16 03:17:0915803 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4615804
bnc032658ba2016-09-26 18:17:1515805 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4615806
Ryan Hamilton0239aac2018-05-19 00:03:1315807 spdy::SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4915808 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3815809 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1315810 spdy::SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3715811 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4615812 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115813 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4615814 };
Ryan Hamilton0239aac2018-05-19 00:03:1315815 spdy::SpdySerializedFrame host1_resp(
15816 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
15817 spdy::SpdySerializedFrame host1_resp_body(
bncdf80d44fd2016-07-15 20:27:4115818 spdy_util_.ConstructSpdyDataFrame(1, true));
Ryan Hamilton0239aac2018-05-19 00:03:1315819 spdy::SpdySerializedFrame host2_resp(
15820 spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
15821 spdy::SpdySerializedFrame host2_resp_body(
bncdf80d44fd2016-07-15 20:27:4115822 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4615823 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115824 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
15825 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1315826 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4615827 };
15828
eroman36d84e54432016-03-17 03:23:0215829 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0215830 MockConnect connect(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115831 SequencedSocketData spdy_data(connect, spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0715832 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4615833
[email protected]aa22b242011-11-16 18:58:2915834 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4615835 HttpRequestInfo request1;
15836 request1.method = "GET";
bncce36dca22015-04-21 22:11:2315837 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4615838 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015839 request1.traffic_annotation =
15840 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015841 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4615842
tfarina42834112016-09-22 13:38:2015843 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115844 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15845 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615846
15847 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5215848 ASSERT_TRUE(response);
15849 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215850 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4615851
15852 std::string response_data;
robpercival214763f2016-07-01 23:27:0115853 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615854 EXPECT_EQ("hello!", response_data);
15855
15856 // Preload cache entries into HostCache.
bnca4d611d2016-09-22 19:55:3715857 HostResolver::RequestInfo resolve_info(HostPortPair("mail.example.com", 443));
[email protected]e3ceb682011-06-28 23:55:4615858 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1015859 std::unique_ptr<HostResolver::Request> request;
bnc6dcd8192017-05-25 20:11:5015860 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
15861 &ignored, callback.callback(),
15862 &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115863 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4715864 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115865 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4615866
15867 HttpRequestInfo request2;
15868 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3715869 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4615870 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015871 request2.traffic_annotation =
15872 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015873 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4615874
tfarina42834112016-09-22 13:38:2015875 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115876 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15877 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615878
15879 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215880 ASSERT_TRUE(response);
15881 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215882 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4615883 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215884 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115885 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615886 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4615887}
15888
bncd16676a2016-07-20 16:23:0115889TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2315890 const std::string https_url = "https://www.example.org:8080/";
15891 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0415892
15893 // SPDY GET for HTTPS URL
Ryan Hamilton0239aac2018-05-19 00:03:1315894 spdy::SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4915895 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0415896
15897 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4115898 CreateMockWrite(req1, 0),
[email protected]8450d722012-07-02 19:14:0415899 };
15900
Ryan Hamilton0239aac2018-05-19 00:03:1315901 spdy::SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
15902 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
bncdf80d44fd2016-07-15 20:27:4115903 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
mmenkee24011922015-12-17 22:12:5915904 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)};
[email protected]8450d722012-07-02 19:14:0415905
Ryan Sleevib8d7ea02018-05-07 20:01:0115906 SequencedSocketData data1(reads1, writes1);
[email protected]8450d722012-07-02 19:14:0415907 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5715908 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0415909
15910 // HTTP GET for the HTTP URL
15911 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1315912 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3415913 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2315914 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3415915 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0415916 };
15917
15918 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1315919 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
15920 MockRead(ASYNC, 2, "hello"),
15921 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0415922 };
15923
Ryan Sleevib8d7ea02018-05-07 20:01:0115924 SequencedSocketData data2(reads2, writes2);
[email protected]8450d722012-07-02 19:14:0415925
[email protected]8450d722012-07-02 19:14:0415926 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615927 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0715928 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15929 session_deps_.socket_factory->AddSocketDataProvider(&data1);
15930 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0415931
danakj1fd259a02016-04-16 03:17:0915932 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0415933
15934 // Start the first transaction to set up the SpdySession
15935 HttpRequestInfo request1;
15936 request1.method = "GET";
15937 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0415938 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015939 request1.traffic_annotation =
15940 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015941 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0415942 TestCompletionCallback callback1;
15943 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015944 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5515945 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0415946
robpercival214763f2016-07-01 23:27:0115947 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0415948 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
15949
15950 // Now, start the HTTP request
15951 HttpRequestInfo request2;
15952 request2.method = "GET";
15953 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0415954 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015955 request2.traffic_annotation =
15956 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015957 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0415958 TestCompletionCallback callback2;
15959 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015960 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5515961 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0415962
robpercival214763f2016-07-01 23:27:0115963 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0415964 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
15965}
15966
bnc5452e2a2015-05-08 16:27:4215967// Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
15968// with the alternative server. That connection should not be used.
bncd16676a2016-07-20 16:23:0115969TEST_F(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
bnc8bef8da22016-05-30 01:28:2515970 url::SchemeHostPort server("https", "www.example.org", 443);
15971 HostPortPair alternative("www.example.org", 444);
bnc5452e2a2015-05-08 16:27:4215972
bnc8bef8da22016-05-30 01:28:2515973 // Negotiate HTTP/1.1 with alternative.
bnc5452e2a2015-05-08 16:27:4215974 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615975 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4215976 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15977
15978 // No data should be read from the alternative, because HTTP/1.1 is
15979 // negotiated.
15980 StaticSocketDataProvider data;
15981 session_deps_.socket_factory->AddSocketDataProvider(&data);
15982
15983 // This test documents that an alternate Job should not be used if HTTP/1.1 is
zhongyi3d4a55e72016-04-22 20:36:4615984 // negotiated. In order to test this, a failed connection to the server is
bnc5452e2a2015-05-08 16:27:4215985 // mocked. This way the request relies on the alternate Job.
15986 StaticSocketDataProvider data_refused;
15987 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
15988 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
15989
zhongyi3d4a55e72016-04-22 20:36:4615990 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0915991 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4015992 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4215993 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2115994 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1215995 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2115996 http_server_properties->SetHttp2AlternativeService(
15997 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4215998
bnc5452e2a2015-05-08 16:27:4215999 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4616000 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4216001 request.method = "GET";
bnc8bef8da22016-05-30 01:28:2516002 request.url = GURL("https://www.example.org:443");
Ramin Halavatib5e433e62018-02-07 07:41:1016003 request.traffic_annotation =
16004 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4216005 TestCompletionCallback callback;
16006
16007 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
bnc94c92842016-09-21 15:22:5216008 // negotiated, the alternate Job should fail with ERR_ALPN_NEGOTIATION_FAILED.
tfarina42834112016-09-22 13:38:2016009 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc94c92842016-09-21 15:22:5216010 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_ALPN_NEGOTIATION_FAILED));
bnc5452e2a2015-05-08 16:27:4216011}
16012
bnc40448a532015-05-11 19:13:1416013// A request to a server with an alternative service fires two Jobs: one to the
zhongyi3d4a55e72016-04-22 20:36:4616014// server, and an alternate one to the alternative server. If the former
bnc40448a532015-05-11 19:13:1416015// succeeds, the request should succeed, even if the latter fails because
16016// HTTP/1.1 is negotiated which is insufficient for alternative service.
bncd16676a2016-07-20 16:23:0116017TEST_F(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
bnc8bef8da22016-05-30 01:28:2516018 url::SchemeHostPort server("https", "www.example.org", 443);
16019 HostPortPair alternative("www.example.org", 444);
bnc40448a532015-05-11 19:13:1416020
16021 // Negotiate HTTP/1.1 with alternative.
16022 SSLSocketDataProvider alternative_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616023 alternative_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1416024 session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
16025
16026 // No data should be read from the alternative, because HTTP/1.1 is
16027 // negotiated.
16028 StaticSocketDataProvider data;
16029 session_deps_.socket_factory->AddSocketDataProvider(&data);
16030
zhongyi3d4a55e72016-04-22 20:36:4616031 // Negotiate HTTP/1.1 with server.
bnc40448a532015-05-11 19:13:1416032 SSLSocketDataProvider origin_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616033 origin_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1416034 session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
16035
16036 MockWrite http_writes[] = {
bnc8bef8da22016-05-30 01:28:2516037 MockWrite("GET / HTTP/1.1\r\n"
16038 "Host: www.example.org\r\n"
16039 "Connection: keep-alive\r\n\r\n"),
16040 MockWrite("GET /second HTTP/1.1\r\n"
16041 "Host: www.example.org\r\n"
16042 "Connection: keep-alive\r\n\r\n"),
bnc40448a532015-05-11 19:13:1416043 };
16044
16045 MockRead http_reads[] = {
16046 MockRead("HTTP/1.1 200 OK\r\n"),
16047 MockRead("Content-Type: text/html\r\n"),
16048 MockRead("Content-Length: 6\r\n\r\n"),
16049 MockRead("foobar"),
16050 MockRead("HTTP/1.1 200 OK\r\n"),
16051 MockRead("Content-Type: text/html\r\n"),
16052 MockRead("Content-Length: 7\r\n\r\n"),
16053 MockRead("another"),
16054 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116055 StaticSocketDataProvider http_data(http_reads, http_writes);
bnc40448a532015-05-11 19:13:1416056 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16057
zhongyi3d4a55e72016-04-22 20:36:4616058 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0916059 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4016060 HttpServerProperties* http_server_properties =
bnc40448a532015-05-11 19:13:1416061 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2116062 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1216063 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2116064 http_server_properties->SetHttp2AlternativeService(
16065 server, alternative_service, expiration);
bnc40448a532015-05-11 19:13:1416066
16067 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
16068 HttpRequestInfo request1;
16069 request1.method = "GET";
bnc8bef8da22016-05-30 01:28:2516070 request1.url = GURL("https://www.example.org:443");
bnc40448a532015-05-11 19:13:1416071 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016072 request1.traffic_annotation =
16073 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc40448a532015-05-11 19:13:1416074 TestCompletionCallback callback1;
16075
tfarina42834112016-09-22 13:38:2016076 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1416077 rv = callback1.GetResult(rv);
robpercival214763f2016-07-01 23:27:0116078 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1416079
16080 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5216081 ASSERT_TRUE(response1);
16082 ASSERT_TRUE(response1->headers);
bnc40448a532015-05-11 19:13:1416083 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
16084
16085 std::string response_data1;
robpercival214763f2016-07-01 23:27:0116086 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc40448a532015-05-11 19:13:1416087 EXPECT_EQ("foobar", response_data1);
16088
16089 // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
16090 // for alternative service.
16091 EXPECT_TRUE(
16092 http_server_properties->IsAlternativeServiceBroken(alternative_service));
16093
zhongyi3d4a55e72016-04-22 20:36:4616094 // Since |alternative_service| is broken, a second transaction to server
bnc40448a532015-05-11 19:13:1416095 // should not start an alternate Job. It should pool to existing connection
zhongyi3d4a55e72016-04-22 20:36:4616096 // to server.
bnc40448a532015-05-11 19:13:1416097 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
16098 HttpRequestInfo request2;
16099 request2.method = "GET";
bnc8bef8da22016-05-30 01:28:2516100 request2.url = GURL("https://www.example.org:443/second");
bnc40448a532015-05-11 19:13:1416101 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016102 request2.traffic_annotation =
16103 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc40448a532015-05-11 19:13:1416104 TestCompletionCallback callback2;
16105
tfarina42834112016-09-22 13:38:2016106 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1416107 rv = callback2.GetResult(rv);
robpercival214763f2016-07-01 23:27:0116108 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1416109
16110 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5216111 ASSERT_TRUE(response2);
16112 ASSERT_TRUE(response2->headers);
bnc40448a532015-05-11 19:13:1416113 EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
16114
16115 std::string response_data2;
robpercival214763f2016-07-01 23:27:0116116 ASSERT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
bnc40448a532015-05-11 19:13:1416117 EXPECT_EQ("another", response_data2);
16118}
16119
bnc5452e2a2015-05-08 16:27:4216120// Alternative service requires HTTP/2 (or SPDY), but there is already a
16121// HTTP/1.1 socket open to the alternative server. That socket should not be
16122// used.
bncd16676a2016-07-20 16:23:0116123TEST_F(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
zhongyi3d4a55e72016-04-22 20:36:4616124 url::SchemeHostPort server("https", "origin.example.org", 443);
bnc5452e2a2015-05-08 16:27:4216125 HostPortPair alternative("alternative.example.org", 443);
16126 std::string origin_url = "https://origin.example.org:443";
16127 std::string alternative_url = "https://alternative.example.org:443";
16128
16129 // Negotiate HTTP/1.1 with alternative.example.org.
16130 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616131 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4216132 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16133
16134 // HTTP/1.1 data for |request1| and |request2|.
16135 MockWrite http_writes[] = {
16136 MockWrite(
16137 "GET / HTTP/1.1\r\n"
16138 "Host: alternative.example.org\r\n"
16139 "Connection: keep-alive\r\n\r\n"),
16140 MockWrite(
16141 "GET / HTTP/1.1\r\n"
16142 "Host: alternative.example.org\r\n"
16143 "Connection: keep-alive\r\n\r\n"),
16144 };
16145
16146 MockRead http_reads[] = {
16147 MockRead(
16148 "HTTP/1.1 200 OK\r\n"
16149 "Content-Type: text/html; charset=iso-8859-1\r\n"
16150 "Content-Length: 40\r\n\r\n"
16151 "first HTTP/1.1 response from alternative"),
16152 MockRead(
16153 "HTTP/1.1 200 OK\r\n"
16154 "Content-Type: text/html; charset=iso-8859-1\r\n"
16155 "Content-Length: 41\r\n\r\n"
16156 "second HTTP/1.1 response from alternative"),
16157 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116158 StaticSocketDataProvider http_data(http_reads, http_writes);
bnc5452e2a2015-05-08 16:27:4216159 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16160
16161 // This test documents that an alternate Job should not pool to an already
16162 // existing HTTP/1.1 connection. In order to test this, a failed connection
zhongyi3d4a55e72016-04-22 20:36:4616163 // to the server is mocked. This way |request2| relies on the alternate Job.
bnc5452e2a2015-05-08 16:27:4216164 StaticSocketDataProvider data_refused;
16165 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
16166 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
16167
zhongyi3d4a55e72016-04-22 20:36:4616168 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0916169 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4016170 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4216171 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2116172 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1216173 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2116174 http_server_properties->SetHttp2AlternativeService(
16175 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4216176
16177 // First transaction to alternative to open an HTTP/1.1 socket.
bnc5452e2a2015-05-08 16:27:4216178 HttpRequestInfo request1;
krasinc06a72a2016-12-21 03:42:4616179 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4216180 request1.method = "GET";
16181 request1.url = GURL(alternative_url);
16182 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016183 request1.traffic_annotation =
16184 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4216185 TestCompletionCallback callback1;
16186
tfarina42834112016-09-22 13:38:2016187 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116188 EXPECT_THAT(callback1.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1616189 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4216190 ASSERT_TRUE(response1);
wezca1070932016-05-26 20:30:5216191 ASSERT_TRUE(response1->headers);
bnc5452e2a2015-05-08 16:27:4216192 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5216193 EXPECT_TRUE(response1->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4216194 EXPECT_FALSE(response1->was_fetched_via_spdy);
16195 std::string response_data1;
bnc691fda62016-08-12 00:43:1616196 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc5452e2a2015-05-08 16:27:4216197 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
16198
16199 // Request for origin.example.org, which has an alternative service. This
16200 // will start two Jobs: the alternative looks for connections to pool to,
16201 // finds one which is HTTP/1.1, and should ignore it, and should not try to
zhongyi3d4a55e72016-04-22 20:36:4616202 // open other connections to alternative server. The Job to server fails, so
bnc5452e2a2015-05-08 16:27:4216203 // this request fails.
bnc5452e2a2015-05-08 16:27:4216204 HttpRequestInfo request2;
krasinc06a72a2016-12-21 03:42:4616205 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4216206 request2.method = "GET";
16207 request2.url = GURL(origin_url);
16208 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016209 request2.traffic_annotation =
16210 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4216211 TestCompletionCallback callback2;
16212
tfarina42834112016-09-22 13:38:2016213 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116214 EXPECT_THAT(callback2.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc5452e2a2015-05-08 16:27:4216215
16216 // Another transaction to alternative. This is to test that the HTTP/1.1
16217 // socket is still open and in the pool.
bnc5452e2a2015-05-08 16:27:4216218 HttpRequestInfo request3;
krasinc06a72a2016-12-21 03:42:4616219 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4216220 request3.method = "GET";
16221 request3.url = GURL(alternative_url);
16222 request3.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016223 request3.traffic_annotation =
16224 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4216225 TestCompletionCallback callback3;
16226
tfarina42834112016-09-22 13:38:2016227 rv = trans3.Start(&request3, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116228 EXPECT_THAT(callback3.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1616229 const HttpResponseInfo* response3 = trans3.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4216230 ASSERT_TRUE(response3);
wezca1070932016-05-26 20:30:5216231 ASSERT_TRUE(response3->headers);
bnc5452e2a2015-05-08 16:27:4216232 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5216233 EXPECT_TRUE(response3->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4216234 EXPECT_FALSE(response3->was_fetched_via_spdy);
16235 std::string response_data3;
bnc691fda62016-08-12 00:43:1616236 ASSERT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
bnc5452e2a2015-05-08 16:27:4216237 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
16238}
16239
bncd16676a2016-07-20 16:23:0116240TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2316241 const std::string https_url = "https://www.example.org:8080/";
16242 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0416243
rdsmithebb50aa2015-11-12 03:44:3816244 // Separate SPDY util instance for naked and wrapped requests.
bncd16676a2016-07-20 16:23:0116245 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:3816246
[email protected]8450d722012-07-02 19:14:0416247 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2316248 const HostPortPair host_port_pair("www.example.org", 8080);
Ryan Hamilton0239aac2018-05-19 00:03:1316249 spdy::SpdySerializedFrame connect(
lgarrona91df87f2014-12-05 00:51:3416250 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
Ryan Hamilton0239aac2018-05-19 00:03:1316251 spdy::SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4916252 spdy_util_wrapped.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1316253 spdy::SpdySerializedFrame wrapped_req1(
[email protected]23e482282013-06-14 16:08:0216254 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3916255
16256 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
Ryan Hamilton0239aac2018-05-19 00:03:1316257 spdy::SpdyHeaderBlock req2_block;
16258 req2_block[spdy::kHttp2MethodHeader] = "GET";
16259 req2_block[spdy::kHttp2AuthorityHeader] = "www.example.org:8080";
16260 req2_block[spdy::kHttp2SchemeHeader] = "http";
16261 req2_block[spdy::kHttp2PathHeader] = "/";
16262 spdy::SpdySerializedFrame req2(
bnc42331402016-07-25 13:36:1516263 spdy_util_.ConstructSpdyHeaders(3, std::move(req2_block), MEDIUM, true));
[email protected]8450d722012-07-02 19:14:0416264
16265 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4116266 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_req1, 2),
16267 CreateMockWrite(req2, 6),
[email protected]8450d722012-07-02 19:14:0416268 };
16269
Ryan Hamilton0239aac2018-05-19 00:03:1316270 spdy::SpdySerializedFrame conn_resp(
bnc42331402016-07-25 13:36:1516271 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316272 spdy::SpdySerializedFrame resp1(
bnc42331402016-07-25 13:36:1516273 spdy_util_wrapped.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316274 spdy::SpdySerializedFrame body1(
16275 spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
16276 spdy::SpdySerializedFrame wrapped_resp1(
rdsmithebb50aa2015-11-12 03:44:3816277 spdy_util_wrapped.ConstructWrappedSpdyFrame(resp1, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316278 spdy::SpdySerializedFrame wrapped_body1(
rdsmithebb50aa2015-11-12 03:44:3816279 spdy_util_wrapped.ConstructWrappedSpdyFrame(body1, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316280 spdy::SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
16281 spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
mmenke666a6fea2015-12-19 04:16:3316282 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4116283 CreateMockRead(conn_resp, 1),
mmenke666a6fea2015-12-19 04:16:3316284 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:4116285 CreateMockRead(wrapped_resp1, 4),
16286 CreateMockRead(wrapped_body1, 5),
mmenke666a6fea2015-12-19 04:16:3316287 MockRead(ASYNC, ERR_IO_PENDING, 7),
bncdf80d44fd2016-07-15 20:27:4116288 CreateMockRead(resp2, 8),
16289 CreateMockRead(body2, 9),
mmenke666a6fea2015-12-19 04:16:3316290 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 10),
16291 };
[email protected]8450d722012-07-02 19:14:0416292
Ryan Sleevib8d7ea02018-05-07 20:01:0116293 SequencedSocketData data1(reads1, writes1);
[email protected]8450d722012-07-02 19:14:0416294 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5716295 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0416296
Lily Houghton8c2f97d2018-01-22 05:06:5916297 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4916298 ProxyResolutionService::CreateFixedFromPacResult(
16299 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5116300 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0716301 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0416302 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3616303 ssl1.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3316304 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0416305 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3616306 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3316307 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
16308 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0416309
danakj1fd259a02016-04-16 03:17:0916310 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]8450d722012-07-02 19:14:0416311
16312 // Start the first transaction to set up the SpdySession
16313 HttpRequestInfo request1;
16314 request1.method = "GET";
16315 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0416316 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016317 request1.traffic_annotation =
16318 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016319 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0416320 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:2016321 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0416322
mmenke666a6fea2015-12-19 04:16:3316323 // This pause is a hack to avoid running into https://crbug.com/497228.
16324 data1.RunUntilPaused();
16325 base::RunLoop().RunUntilIdle();
16326 data1.Resume();
robpercival214763f2016-07-01 23:27:0116327 EXPECT_THAT(callback1.GetResult(rv), IsOk());
[email protected]8450d722012-07-02 19:14:0416328 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
16329
[email protected]f6c63db52013-02-02 00:35:2216330 LoadTimingInfo load_timing_info1;
16331 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
16332 TestLoadTimingNotReusedWithPac(load_timing_info1,
16333 CONNECT_TIMING_HAS_SSL_TIMES);
16334
mmenke666a6fea2015-12-19 04:16:3316335 // Now, start the HTTP request.
[email protected]8450d722012-07-02 19:14:0416336 HttpRequestInfo request2;
16337 request2.method = "GET";
16338 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0416339 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016340 request2.traffic_annotation =
16341 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016342 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0416343 TestCompletionCallback callback2;
tfarina42834112016-09-22 13:38:2016344 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0416345
mmenke666a6fea2015-12-19 04:16:3316346 // This pause is a hack to avoid running into https://crbug.com/497228.
16347 data1.RunUntilPaused();
16348 base::RunLoop().RunUntilIdle();
16349 data1.Resume();
robpercival214763f2016-07-01 23:27:0116350 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenke666a6fea2015-12-19 04:16:3316351
[email protected]8450d722012-07-02 19:14:0416352 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2216353
16354 LoadTimingInfo load_timing_info2;
16355 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
16356 // The established SPDY sessions is considered reused by the HTTP request.
16357 TestLoadTimingReusedWithPac(load_timing_info2);
16358 // HTTP requests over a SPDY session should have a different connection
16359 // socket_log_id than requests over a tunnel.
16360 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0416361}
16362
[email protected]2d88e7d2012-07-19 17:55:1716363// Test that in the case where we have a SPDY session to a SPDY proxy
16364// that we do not pool other origins that resolve to the same IP when
16365// the certificate does not match the new origin.
16366// http://crbug.com/134690
bncd16676a2016-07-20 16:23:0116367TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2316368 const std::string url1 = "http://www.example.org/";
16369 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1716370 const std::string ip_addr = "1.2.3.4";
16371
rdsmithebb50aa2015-11-12 03:44:3816372 // Second SpdyTestUtil instance for the second socket.
bncd16676a2016-07-20 16:23:0116373 SpdyTestUtil spdy_util_secure;
rdsmithebb50aa2015-11-12 03:44:3816374
[email protected]2d88e7d2012-07-19 17:55:1716375 // SPDY GET for HTTP URL (through SPDY proxy)
Ryan Hamilton0239aac2018-05-19 00:03:1316376 spdy::SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:2316377 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
Ryan Hamilton0239aac2018-05-19 00:03:1316378 spdy::SpdySerializedFrame req1(
bnc42331402016-07-25 13:36:1516379 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
[email protected]2d88e7d2012-07-19 17:55:1716380
16381 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4116382 CreateMockWrite(req1, 0),
[email protected]2d88e7d2012-07-19 17:55:1716383 };
16384
Ryan Hamilton0239aac2018-05-19 00:03:1316385 spdy::SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
16386 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1716387 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4116388 MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(resp1, 2),
16389 CreateMockRead(body1, 3), MockRead(ASYNC, OK, 4), // EOF
[email protected]2d88e7d2012-07-19 17:55:1716390 };
16391
Ryan Sleevib8d7ea02018-05-07 20:01:0116392 SequencedSocketData data1(reads1, writes1);
martijnfe9636e2016-02-06 14:33:3216393 IPAddress ip;
martijn654c8c42016-02-10 22:10:5916394 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
[email protected]2d88e7d2012-07-19 17:55:1716395 IPEndPoint peer_addr = IPEndPoint(ip, 443);
16396 MockConnect connect_data1(ASYNC, OK, peer_addr);
mmenke666a6fea2015-12-19 04:16:3316397 data1.set_connect_data(connect_data1);
[email protected]2d88e7d2012-07-19 17:55:1716398
16399 // SPDY GET for HTTPS URL (direct)
Ryan Hamilton0239aac2018-05-19 00:03:1316400 spdy::SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4916401 spdy_util_secure.ConstructSpdyGet(url2.c_str(), 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1716402
16403 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4116404 CreateMockWrite(req2, 0),
[email protected]2d88e7d2012-07-19 17:55:1716405 };
16406
Ryan Hamilton0239aac2018-05-19 00:03:1316407 spdy::SpdySerializedFrame resp2(
16408 spdy_util_secure.ConstructSpdyGetReply(NULL, 0, 1));
16409 spdy::SpdySerializedFrame body2(
16410 spdy_util_secure.ConstructSpdyDataFrame(1, true));
bncdf80d44fd2016-07-15 20:27:4116411 MockRead reads2[] = {CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
mmenke666a6fea2015-12-19 04:16:3316412 MockRead(ASYNC, OK, 3)};
[email protected]2d88e7d2012-07-19 17:55:1716413
Ryan Sleevib8d7ea02018-05-07 20:01:0116414 SequencedSocketData data2(reads2, writes2);
[email protected]2d88e7d2012-07-19 17:55:1716415 MockConnect connect_data2(ASYNC, OK);
mmenke666a6fea2015-12-19 04:16:3316416 data2.set_connect_data(connect_data2);
[email protected]2d88e7d2012-07-19 17:55:1716417
16418 // Set up a proxy config that sends HTTP requests to a proxy, and
16419 // all others direct.
16420 ProxyConfig proxy_config;
16421 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
Ramin Halavatica8d5252018-03-12 05:33:4916422 session_deps_.proxy_resolution_service =
16423 std::make_unique<ProxyResolutionService>(
16424 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
16425 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
16426 nullptr, nullptr);
[email protected]2d88e7d2012-07-19 17:55:1716427
bncce36dca22015-04-21 22:11:2316428 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3616429 ssl1.next_proto = kProtoHTTP2;
[email protected]2d88e7d2012-07-19 17:55:1716430 // Load a valid cert. Note, that this does not need to
16431 // be valid for proxy because the MockSSLClientSocket does
16432 // not actually verify it. But SpdySession will use this
16433 // to see if it is valid for the new origin
Ryan Sleevi4f832092017-11-21 23:25:4916434 ssl1.ssl_info.cert =
16435 ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
16436 ASSERT_TRUE(ssl1.ssl_info.cert);
mmenke666a6fea2015-12-19 04:16:3316437 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
16438 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d88e7d2012-07-19 17:55:1716439
16440 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3616441 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3316442 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
16443 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d88e7d2012-07-19 17:55:1716444
Jeremy Roman0579ed62017-08-29 15:56:1916445 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
bncce36dca22015-04-21 22:11:2316446 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0716447 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1716448
danakj1fd259a02016-04-16 03:17:0916449 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]2d88e7d2012-07-19 17:55:1716450
16451 // Start the first transaction to set up the SpdySession
16452 HttpRequestInfo request1;
16453 request1.method = "GET";
16454 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1716455 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016456 request1.traffic_annotation =
16457 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016458 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1716459 TestCompletionCallback callback1;
16460 ASSERT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016461 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
mmenke666a6fea2015-12-19 04:16:3316462 // This pause is a hack to avoid running into https://crbug.com/497228.
16463 data1.RunUntilPaused();
16464 base::RunLoop().RunUntilIdle();
16465 data1.Resume();
[email protected]2d88e7d2012-07-19 17:55:1716466
robpercival214763f2016-07-01 23:27:0116467 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1716468 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
16469
16470 // Now, start the HTTP request
16471 HttpRequestInfo request2;
16472 request2.method = "GET";
16473 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1716474 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016475 request2.traffic_annotation =
16476 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016477 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1716478 TestCompletionCallback callback2;
16479 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016480 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5516481 base::RunLoop().RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1716482
16483 ASSERT_TRUE(callback2.have_result());
robpercival214763f2016-07-01 23:27:0116484 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1716485 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
16486}
16487
[email protected]85f97342013-04-17 06:12:2416488// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
16489// error) in SPDY session, removes the socket from pool and closes the SPDY
16490// session. Verify that new url's from the same HttpNetworkSession (and a new
16491// SpdySession) do work. http://crbug.com/224701
bncd16676a2016-07-20 16:23:0116492TEST_F(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2316493 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2416494
16495 MockRead reads1[] = {
16496 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
16497 };
16498
Ryan Sleevib8d7ea02018-05-07 20:01:0116499 SequencedSocketData data1(reads1, base::span<MockWrite>());
[email protected]85f97342013-04-17 06:12:2416500
Ryan Hamilton0239aac2018-05-19 00:03:1316501 spdy::SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4916502 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2416503 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4116504 CreateMockWrite(req2, 0),
[email protected]85f97342013-04-17 06:12:2416505 };
16506
Ryan Hamilton0239aac2018-05-19 00:03:1316507 spdy::SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
16508 spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]85f97342013-04-17 06:12:2416509 MockRead reads2[] = {
bncdf80d44fd2016-07-15 20:27:4116510 CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
16511 MockRead(ASYNC, OK, 3) // EOF
[email protected]85f97342013-04-17 06:12:2416512 };
16513
Ryan Sleevib8d7ea02018-05-07 20:01:0116514 SequencedSocketData data2(reads2, writes2);
[email protected]85f97342013-04-17 06:12:2416515
[email protected]85f97342013-04-17 06:12:2416516 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616517 ssl1.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5016518 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
16519 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]85f97342013-04-17 06:12:2416520
16521 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616522 ssl2.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5016523 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
16524 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]85f97342013-04-17 06:12:2416525
danakj1fd259a02016-04-16 03:17:0916526 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:5016527 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]85f97342013-04-17 06:12:2416528
16529 // Start the first transaction to set up the SpdySession and verify that
16530 // connection was closed.
16531 HttpRequestInfo request1;
16532 request1.method = "GET";
16533 request1.url = GURL(https_url);
16534 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016535 request1.traffic_annotation =
16536 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016537 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2416538 TestCompletionCallback callback1;
16539 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016540 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0116541 EXPECT_THAT(callback1.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]85f97342013-04-17 06:12:2416542
16543 // Now, start the second request and make sure it succeeds.
16544 HttpRequestInfo request2;
16545 request2.method = "GET";
16546 request2.url = GURL(https_url);
16547 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016548 request2.traffic_annotation =
16549 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016550 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2416551 TestCompletionCallback callback2;
16552 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016553 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
[email protected]85f97342013-04-17 06:12:2416554
robpercival214763f2016-07-01 23:27:0116555 ASSERT_THAT(callback2.WaitForResult(), IsOk());
[email protected]85f97342013-04-17 06:12:2416556 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
16557}
16558
bncd16676a2016-07-20 16:23:0116559TEST_F(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]483fa202013-05-14 01:07:0316560 ClientSocketPoolManager::set_max_sockets_per_group(
16561 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16562 ClientSocketPoolManager::set_max_sockets_per_pool(
16563 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16564
16565 // Use two different hosts with different IPs so they don't get pooled.
16566 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
16567 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
danakj1fd259a02016-04-16 03:17:0916568 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]483fa202013-05-14 01:07:0316569
16570 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616571 ssl1.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0316572 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616573 ssl2.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0316574 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
16575 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
16576
Ryan Hamilton0239aac2018-05-19 00:03:1316577 spdy::SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4916578 spdy_util_.ConstructSpdyGet("https://www.a.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0316579 MockWrite spdy1_writes[] = {
bncdf80d44fd2016-07-15 20:27:4116580 CreateMockWrite(host1_req, 0),
[email protected]483fa202013-05-14 01:07:0316581 };
Ryan Hamilton0239aac2018-05-19 00:03:1316582 spdy::SpdySerializedFrame host1_resp(
16583 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
16584 spdy::SpdySerializedFrame host1_resp_body(
bncdf80d44fd2016-07-15 20:27:4116585 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0316586 MockRead spdy1_reads[] = {
bncdf80d44fd2016-07-15 20:27:4116587 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
mmenkee24011922015-12-17 22:12:5916588 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0316589 };
16590
rdsmithebb50aa2015-11-12 03:44:3816591 // Use a separate test instance for the separate SpdySession that will be
16592 // created.
bncd16676a2016-07-20 16:23:0116593 SpdyTestUtil spdy_util_2;
Ryan Sleevib8d7ea02018-05-07 20:01:0116594 SequencedSocketData spdy1_data(spdy1_reads, spdy1_writes);
Bence Béky53a5aef2018-03-29 21:54:1216595 session_deps_.socket_factory->AddSocketDataProvider(&spdy1_data);
[email protected]483fa202013-05-14 01:07:0316596
Ryan Hamilton0239aac2018-05-19 00:03:1316597 spdy::SpdySerializedFrame host2_req(
bnc38dcd392016-02-09 23:19:4916598 spdy_util_2.ConstructSpdyGet("https://www.b.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0316599 MockWrite spdy2_writes[] = {
bncdf80d44fd2016-07-15 20:27:4116600 CreateMockWrite(host2_req, 0),
[email protected]483fa202013-05-14 01:07:0316601 };
Ryan Hamilton0239aac2018-05-19 00:03:1316602 spdy::SpdySerializedFrame host2_resp(
16603 spdy_util_2.ConstructSpdyGetReply(NULL, 0, 1));
16604 spdy::SpdySerializedFrame host2_resp_body(
bncdf80d44fd2016-07-15 20:27:4116605 spdy_util_2.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0316606 MockRead spdy2_reads[] = {
bncdf80d44fd2016-07-15 20:27:4116607 CreateMockRead(host2_resp, 1), CreateMockRead(host2_resp_body, 2),
mmenkee24011922015-12-17 22:12:5916608 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0316609 };
16610
Ryan Sleevib8d7ea02018-05-07 20:01:0116611 SequencedSocketData spdy2_data(spdy2_reads, spdy2_writes);
Bence Béky53a5aef2018-03-29 21:54:1216612 session_deps_.socket_factory->AddSocketDataProvider(&spdy2_data);
[email protected]483fa202013-05-14 01:07:0316613
16614 MockWrite http_write[] = {
16615 MockWrite("GET / HTTP/1.1\r\n"
16616 "Host: www.a.com\r\n"
16617 "Connection: keep-alive\r\n\r\n"),
16618 };
16619
16620 MockRead http_read[] = {
16621 MockRead("HTTP/1.1 200 OK\r\n"),
16622 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
16623 MockRead("Content-Length: 6\r\n\r\n"),
16624 MockRead("hello!"),
16625 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116626 StaticSocketDataProvider http_data(http_read, http_write);
[email protected]483fa202013-05-14 01:07:0316627 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16628
16629 HostPortPair host_port_pair_a("www.a.com", 443);
Matt Menke2436b2f2018-12-11 18:07:1116630 SpdySessionKey spdy_session_key_a(
16631 host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
16632 SpdySessionKey::IsProxySession::kFalse, SocketTag());
[email protected]483fa202013-05-14 01:07:0316633 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616634 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0316635
16636 TestCompletionCallback callback;
16637 HttpRequestInfo request1;
16638 request1.method = "GET";
16639 request1.url = GURL("https://www.a.com/");
16640 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016641 request1.traffic_annotation =
16642 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5816643 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1916644 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0316645
tfarina42834112016-09-22 13:38:2016646 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116647 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16648 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0316649
16650 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5216651 ASSERT_TRUE(response);
16652 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0216653 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0316654 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5216655 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]483fa202013-05-14 01:07:0316656
16657 std::string response_data;
robpercival214763f2016-07-01 23:27:0116658 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0316659 EXPECT_EQ("hello!", response_data);
16660 trans.reset();
16661 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2616662 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0316663
16664 HostPortPair host_port_pair_b("www.b.com", 443);
Matt Menke2436b2f2018-12-11 18:07:1116665 SpdySessionKey spdy_session_key_b(
16666 host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
16667 SpdySessionKey::IsProxySession::kFalse, SocketTag());
[email protected]483fa202013-05-14 01:07:0316668 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616669 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0316670 HttpRequestInfo request2;
16671 request2.method = "GET";
16672 request2.url = GURL("https://www.b.com/");
16673 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016674 request2.traffic_annotation =
16675 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5816676 trans =
Jeremy Roman0579ed62017-08-29 15:56:1916677 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0316678
tfarina42834112016-09-22 13:38:2016679 rv = trans->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116680 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16681 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0316682
16683 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5216684 ASSERT_TRUE(response);
16685 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0216686 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0316687 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5216688 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0116689 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0316690 EXPECT_EQ("hello!", response_data);
16691 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616692 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0316693 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2616694 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0316695
16696 HostPortPair host_port_pair_a1("www.a.com", 80);
Matt Menke2436b2f2018-12-11 18:07:1116697 SpdySessionKey spdy_session_key_a1(
16698 host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
16699 SpdySessionKey::IsProxySession::kFalse, SocketTag());
[email protected]483fa202013-05-14 01:07:0316700 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616701 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0316702 HttpRequestInfo request3;
16703 request3.method = "GET";
16704 request3.url = GURL("http://www.a.com/");
16705 request3.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016706 request3.traffic_annotation =
16707 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5816708 trans =
Jeremy Roman0579ed62017-08-29 15:56:1916709 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0316710
tfarina42834112016-09-22 13:38:2016711 rv = trans->Start(&request3, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116712 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16713 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0316714
16715 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5216716 ASSERT_TRUE(response);
16717 ASSERT_TRUE(response->headers);
[email protected]483fa202013-05-14 01:07:0316718 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
16719 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5216720 EXPECT_FALSE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0116721 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0316722 EXPECT_EQ("hello!", response_data);
16723 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616724 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0316725 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616726 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0316727}
16728
bncd16676a2016-07-20 16:23:0116729TEST_F(HttpNetworkTransactionTest, HttpSyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0416730 HttpRequestInfo request;
16731 request.method = "GET";
bncce36dca22015-04-21 22:11:2316732 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016733 request.traffic_annotation =
16734 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416735
danakj1fd259a02016-04-16 03:17:0916736 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616737 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416738
ttuttled9dbc652015-09-29 20:00:5916739 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0416740 StaticSocketDataProvider data;
16741 data.set_connect_data(mock_connect);
16742 session_deps_.socket_factory->AddSocketDataProvider(&data);
16743
16744 TestCompletionCallback callback;
16745
tfarina42834112016-09-22 13:38:2016746 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116747 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416748
16749 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116750 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0416751
[email protected]79e1fd62013-06-20 06:50:0416752 // We don't care whether this succeeds or fails, but it shouldn't crash.
16753 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616754 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4716755
16756 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1616757 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4716758 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0116759 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5916760
16761 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1616762 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5916763 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0416764}
16765
bncd16676a2016-07-20 16:23:0116766TEST_F(HttpNetworkTransactionTest, HttpAsyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0416767 HttpRequestInfo request;
16768 request.method = "GET";
bncce36dca22015-04-21 22:11:2316769 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016770 request.traffic_annotation =
16771 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416772
danakj1fd259a02016-04-16 03:17:0916773 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616774 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416775
ttuttled9dbc652015-09-29 20:00:5916776 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0416777 StaticSocketDataProvider data;
16778 data.set_connect_data(mock_connect);
16779 session_deps_.socket_factory->AddSocketDataProvider(&data);
16780
16781 TestCompletionCallback callback;
16782
tfarina42834112016-09-22 13:38:2016783 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116784 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416785
16786 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116787 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0416788
[email protected]79e1fd62013-06-20 06:50:0416789 // We don't care whether this succeeds or fails, but it shouldn't crash.
16790 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616791 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4716792
16793 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1616794 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4716795 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0116796 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5916797
16798 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1616799 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5916800 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0416801}
16802
bncd16676a2016-07-20 16:23:0116803TEST_F(HttpNetworkTransactionTest, HttpSyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0416804 HttpRequestInfo request;
16805 request.method = "GET";
bncce36dca22015-04-21 22:11:2316806 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016807 request.traffic_annotation =
16808 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416809
danakj1fd259a02016-04-16 03:17:0916810 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616811 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416812
16813 MockWrite data_writes[] = {
16814 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16815 };
16816 MockRead data_reads[] = {
16817 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
16818 };
16819
Ryan Sleevib8d7ea02018-05-07 20:01:0116820 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0416821 session_deps_.socket_factory->AddSocketDataProvider(&data);
16822
16823 TestCompletionCallback callback;
16824
tfarina42834112016-09-22 13:38:2016825 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116826 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416827
16828 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116829 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416830
[email protected]79e1fd62013-06-20 06:50:0416831 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616832 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416833 EXPECT_TRUE(request_headers.HasHeader("Host"));
16834}
16835
bncd16676a2016-07-20 16:23:0116836TEST_F(HttpNetworkTransactionTest, HttpAsyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0416837 HttpRequestInfo request;
16838 request.method = "GET";
bncce36dca22015-04-21 22:11:2316839 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016840 request.traffic_annotation =
16841 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416842
danakj1fd259a02016-04-16 03:17:0916843 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616844 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416845
16846 MockWrite data_writes[] = {
16847 MockWrite(ASYNC, ERR_CONNECTION_RESET),
16848 };
16849 MockRead data_reads[] = {
16850 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
16851 };
16852
Ryan Sleevib8d7ea02018-05-07 20:01:0116853 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0416854 session_deps_.socket_factory->AddSocketDataProvider(&data);
16855
16856 TestCompletionCallback callback;
16857
tfarina42834112016-09-22 13:38:2016858 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116859 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416860
16861 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116862 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416863
[email protected]79e1fd62013-06-20 06:50:0416864 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616865 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416866 EXPECT_TRUE(request_headers.HasHeader("Host"));
16867}
16868
bncd16676a2016-07-20 16:23:0116869TEST_F(HttpNetworkTransactionTest, HttpSyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0416870 HttpRequestInfo request;
16871 request.method = "GET";
bncce36dca22015-04-21 22:11:2316872 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016873 request.traffic_annotation =
16874 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416875
danakj1fd259a02016-04-16 03:17:0916876 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616877 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416878
16879 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2316880 MockWrite(
16881 "GET / HTTP/1.1\r\n"
16882 "Host: www.example.org\r\n"
16883 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0416884 };
16885 MockRead data_reads[] = {
16886 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
16887 };
16888
Ryan Sleevib8d7ea02018-05-07 20:01:0116889 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0416890 session_deps_.socket_factory->AddSocketDataProvider(&data);
16891
16892 TestCompletionCallback callback;
16893
tfarina42834112016-09-22 13:38:2016894 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116895 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416896
16897 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116898 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416899
[email protected]79e1fd62013-06-20 06:50:0416900 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616901 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416902 EXPECT_TRUE(request_headers.HasHeader("Host"));
16903}
16904
bncd16676a2016-07-20 16:23:0116905TEST_F(HttpNetworkTransactionTest, HttpAsyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0416906 HttpRequestInfo request;
16907 request.method = "GET";
bncce36dca22015-04-21 22:11:2316908 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016909 request.traffic_annotation =
16910 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416911
danakj1fd259a02016-04-16 03:17:0916912 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616913 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416914
16915 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2316916 MockWrite(
16917 "GET / HTTP/1.1\r\n"
16918 "Host: www.example.org\r\n"
16919 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0416920 };
16921 MockRead data_reads[] = {
16922 MockRead(ASYNC, ERR_CONNECTION_RESET),
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, GetFullRequestHeadersIncludesExtraHeader) {
[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/");
[email protected]79e1fd62013-06-20 06:50:0416945 request.extra_headers.SetHeader("X-Foo", "bar");
Ramin Halavatib5e433e62018-02-07 07:41:1016946 request.traffic_annotation =
16947 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416948
danakj1fd259a02016-04-16 03:17:0916949 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616950 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416951
16952 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2316953 MockWrite(
16954 "GET / HTTP/1.1\r\n"
16955 "Host: www.example.org\r\n"
16956 "Connection: keep-alive\r\n"
16957 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0416958 };
16959 MockRead data_reads[] = {
16960 MockRead("HTTP/1.1 200 OK\r\n"
16961 "Content-Length: 5\r\n\r\n"
16962 "hello"),
16963 MockRead(ASYNC, ERR_UNEXPECTED),
16964 };
16965
Ryan Sleevib8d7ea02018-05-07 20:01:0116966 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0416967 session_deps_.socket_factory->AddSocketDataProvider(&data);
16968
16969 TestCompletionCallback callback;
16970
tfarina42834112016-09-22 13:38:2016971 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116972 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416973
16974 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116975 EXPECT_THAT(rv, IsOk());
[email protected]79e1fd62013-06-20 06:50:0416976
16977 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616978 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416979 std::string foo;
16980 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
16981 EXPECT_EQ("bar", foo);
16982}
16983
[email protected]043b68c82013-08-22 23:41:5216984// Tests that when a used socket is returned to the SSL socket pool, it's closed
16985// if the transport socket pool is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0116986TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
[email protected]043b68c82013-08-22 23:41:5216987 ClientSocketPoolManager::set_max_sockets_per_group(
16988 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16989 ClientSocketPoolManager::set_max_sockets_per_pool(
16990 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16991
16992 // Set up SSL request.
16993
16994 HttpRequestInfo ssl_request;
16995 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2316996 ssl_request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016997 ssl_request.traffic_annotation =
16998 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5216999
17000 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2317001 MockWrite(
17002 "GET / HTTP/1.1\r\n"
17003 "Host: www.example.org\r\n"
17004 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5217005 };
17006 MockRead ssl_reads[] = {
17007 MockRead("HTTP/1.1 200 OK\r\n"),
17008 MockRead("Content-Length: 11\r\n\r\n"),
17009 MockRead("hello world"),
17010 MockRead(SYNCHRONOUS, OK),
17011 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117012 StaticSocketDataProvider ssl_data(ssl_reads, ssl_writes);
[email protected]043b68c82013-08-22 23:41:5217013 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
17014
17015 SSLSocketDataProvider ssl(ASYNC, OK);
17016 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
17017
17018 // Set up HTTP request.
17019
17020 HttpRequestInfo http_request;
17021 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2317022 http_request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1017023 http_request.traffic_annotation =
17024 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5217025
17026 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2317027 MockWrite(
17028 "GET / HTTP/1.1\r\n"
17029 "Host: www.example.org\r\n"
17030 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5217031 };
17032 MockRead http_reads[] = {
17033 MockRead("HTTP/1.1 200 OK\r\n"),
17034 MockRead("Content-Length: 7\r\n\r\n"),
17035 MockRead("falafel"),
17036 MockRead(SYNCHRONOUS, OK),
17037 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117038 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]043b68c82013-08-22 23:41:5217039 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
17040
danakj1fd259a02016-04-16 03:17:0917041 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5217042
17043 // Start the SSL request.
17044 TestCompletionCallback ssl_callback;
bnc691fda62016-08-12 00:43:1617045 HttpNetworkTransaction ssl_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2017046 ASSERT_EQ(ERR_IO_PENDING,
17047 ssl_trans.Start(&ssl_request, ssl_callback.callback(),
17048 NetLogWithSource()));
[email protected]043b68c82013-08-22 23:41:5217049
17050 // Start the HTTP request. Pool should stall.
17051 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1617052 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2017053 ASSERT_EQ(ERR_IO_PENDING,
17054 http_trans.Start(&http_request, http_callback.callback(),
17055 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4117056 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5217057
17058 // Wait for response from SSL request.
robpercival214763f2016-07-01 23:27:0117059 ASSERT_THAT(ssl_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5217060 std::string response_data;
bnc691fda62016-08-12 00:43:1617061 ASSERT_THAT(ReadTransaction(&ssl_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5217062 EXPECT_EQ("hello world", response_data);
17063
17064 // The SSL socket should automatically be closed, so the HTTP request can
17065 // start.
Matt Menke9d5e2c92019-02-05 01:42:2317066 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
dcheng48459ac22014-08-26 00:46:4117067 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5217068
17069 // The HTTP request can now complete.
robpercival214763f2016-07-01 23:27:0117070 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
bnc691fda62016-08-12 00:43:1617071 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5217072 EXPECT_EQ("falafel", response_data);
17073
dcheng48459ac22014-08-26 00:46:4117074 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5217075}
17076
17077// Tests that when a SSL connection is established but there's no corresponding
17078// request that needs it, the new socket is closed if the transport socket pool
17079// is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0117080TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
[email protected]043b68c82013-08-22 23:41:5217081 ClientSocketPoolManager::set_max_sockets_per_group(
17082 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
17083 ClientSocketPoolManager::set_max_sockets_per_pool(
17084 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
17085
17086 // Set up an ssl request.
17087
17088 HttpRequestInfo ssl_request;
17089 ssl_request.method = "GET";
17090 ssl_request.url = GURL("https://www.foopy.com/");
Ramin Halavatib5e433e62018-02-07 07:41:1017091 ssl_request.traffic_annotation =
17092 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5217093
17094 // No data will be sent on the SSL socket.
17095 StaticSocketDataProvider ssl_data;
17096 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
17097
17098 SSLSocketDataProvider ssl(ASYNC, OK);
17099 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
17100
17101 // Set up HTTP request.
17102
17103 HttpRequestInfo http_request;
17104 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2317105 http_request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1017106 http_request.traffic_annotation =
17107 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5217108
17109 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2317110 MockWrite(
17111 "GET / HTTP/1.1\r\n"
17112 "Host: www.example.org\r\n"
17113 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5217114 };
17115 MockRead http_reads[] = {
17116 MockRead("HTTP/1.1 200 OK\r\n"),
17117 MockRead("Content-Length: 7\r\n\r\n"),
17118 MockRead("falafel"),
17119 MockRead(SYNCHRONOUS, OK),
17120 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117121 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]043b68c82013-08-22 23:41:5217122 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
17123
danakj1fd259a02016-04-16 03:17:0917124 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5217125
17126 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
17127 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2917128 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
nharper8cdb0fb2016-04-22 21:34:5917129 http_stream_factory->PreconnectStreams(1, ssl_request);
Matt Menke9d5e2c92019-02-05 01:42:2317130 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5217131
17132 // Start the HTTP request. Pool should stall.
17133 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1617134 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2017135 ASSERT_EQ(ERR_IO_PENDING,
17136 http_trans.Start(&http_request, http_callback.callback(),
17137 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4117138 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5217139
17140 // The SSL connection will automatically be closed once the connection is
17141 // established, to let the HTTP request start.
robpercival214763f2016-07-01 23:27:0117142 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5217143 std::string response_data;
bnc691fda62016-08-12 00:43:1617144 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5217145 EXPECT_EQ("falafel", response_data);
17146
dcheng48459ac22014-08-26 00:46:4117147 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5217148}
17149
bncd16676a2016-07-20 16:23:0117150TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0917151 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217152 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917153 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217154 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417155
17156 HttpRequestInfo request;
17157 request.method = "POST";
17158 request.url = GURL("http://www.foo.com/");
17159 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017160 request.traffic_annotation =
17161 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417162
danakj1fd259a02016-04-16 03:17:0917163 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617164 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417165 // Send headers successfully, but get an error while sending the body.
17166 MockWrite data_writes[] = {
17167 MockWrite("POST / HTTP/1.1\r\n"
17168 "Host: www.foo.com\r\n"
17169 "Connection: keep-alive\r\n"
17170 "Content-Length: 3\r\n\r\n"),
17171 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17172 };
17173
17174 MockRead data_reads[] = {
17175 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
17176 MockRead("hello world"),
17177 MockRead(SYNCHRONOUS, OK),
17178 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117179 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417180 session_deps_.socket_factory->AddSocketDataProvider(&data);
17181
17182 TestCompletionCallback callback;
17183
tfarina42834112016-09-22 13:38:2017184 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117185 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417186
17187 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117188 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417189
bnc691fda62016-08-12 00:43:1617190 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5217191 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5417192
wezca1070932016-05-26 20:30:5217193 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5417194 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
17195
17196 std::string response_data;
bnc691fda62016-08-12 00:43:1617197 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0117198 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417199 EXPECT_EQ("hello world", response_data);
17200}
17201
17202// This test makes sure the retry logic doesn't trigger when reading an error
17203// response from a server that rejected a POST with a CONNECTION_RESET.
bncd16676a2016-07-20 16:23:0117204TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5417205 PostReadsErrorResponseAfterResetOnReusedSocket) {
danakj1fd259a02016-04-16 03:17:0917206 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5417207 MockWrite data_writes[] = {
17208 MockWrite("GET / HTTP/1.1\r\n"
17209 "Host: www.foo.com\r\n"
17210 "Connection: keep-alive\r\n\r\n"),
17211 MockWrite("POST / HTTP/1.1\r\n"
17212 "Host: www.foo.com\r\n"
17213 "Connection: keep-alive\r\n"
17214 "Content-Length: 3\r\n\r\n"),
17215 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17216 };
17217
17218 MockRead data_reads[] = {
17219 MockRead("HTTP/1.1 200 Peachy\r\n"
17220 "Content-Length: 14\r\n\r\n"),
17221 MockRead("first response"),
17222 MockRead("HTTP/1.1 400 Not OK\r\n"
17223 "Content-Length: 15\r\n\r\n"),
17224 MockRead("second response"),
17225 MockRead(SYNCHRONOUS, OK),
17226 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117227 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417228 session_deps_.socket_factory->AddSocketDataProvider(&data);
17229
17230 TestCompletionCallback callback;
17231 HttpRequestInfo request1;
17232 request1.method = "GET";
17233 request1.url = GURL("http://www.foo.com/");
17234 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1017235 request1.traffic_annotation =
17236 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417237
bnc87dcefc2017-05-25 12:47:5817238 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:1917239 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2017240 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117241 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417242
17243 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117244 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417245
17246 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:5217247 ASSERT_TRUE(response1);
[email protected]02d74a02014-04-23 18:10:5417248
wezca1070932016-05-26 20:30:5217249 EXPECT_TRUE(response1->headers);
[email protected]02d74a02014-04-23 18:10:5417250 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
17251
17252 std::string response_data1;
17253 rv = ReadTransaction(trans1.get(), &response_data1);
robpercival214763f2016-07-01 23:27:0117254 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417255 EXPECT_EQ("first response", response_data1);
17256 // Delete the transaction to release the socket back into the socket pool.
17257 trans1.reset();
17258
danakj1fd259a02016-04-16 03:17:0917259 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217260 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917261 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217262 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417263
17264 HttpRequestInfo request2;
17265 request2.method = "POST";
17266 request2.url = GURL("http://www.foo.com/");
17267 request2.upload_data_stream = &upload_data_stream;
17268 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1017269 request2.traffic_annotation =
17270 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417271
bnc691fda62016-08-12 00:43:1617272 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2017273 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117274 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417275
17276 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117277 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417278
bnc691fda62016-08-12 00:43:1617279 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5217280 ASSERT_TRUE(response2);
[email protected]02d74a02014-04-23 18:10:5417281
wezca1070932016-05-26 20:30:5217282 EXPECT_TRUE(response2->headers);
[email protected]02d74a02014-04-23 18:10:5417283 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
17284
17285 std::string response_data2;
bnc691fda62016-08-12 00:43:1617286 rv = ReadTransaction(&trans2, &response_data2);
robpercival214763f2016-07-01 23:27:0117287 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417288 EXPECT_EQ("second response", response_data2);
17289}
17290
bncd16676a2016-07-20 16:23:0117291TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5417292 PostReadsErrorResponseAfterResetPartialBodySent) {
danakj1fd259a02016-04-16 03:17:0917293 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217294 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917295 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217296 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417297
17298 HttpRequestInfo request;
17299 request.method = "POST";
17300 request.url = GURL("http://www.foo.com/");
17301 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017302 request.traffic_annotation =
17303 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417304
danakj1fd259a02016-04-16 03:17:0917305 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617306 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417307 // Send headers successfully, but get an error while sending the body.
17308 MockWrite data_writes[] = {
17309 MockWrite("POST / HTTP/1.1\r\n"
17310 "Host: www.foo.com\r\n"
17311 "Connection: keep-alive\r\n"
17312 "Content-Length: 3\r\n\r\n"
17313 "fo"),
17314 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17315 };
17316
17317 MockRead data_reads[] = {
17318 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
17319 MockRead("hello world"),
17320 MockRead(SYNCHRONOUS, OK),
17321 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117322 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417323 session_deps_.socket_factory->AddSocketDataProvider(&data);
17324
17325 TestCompletionCallback callback;
17326
tfarina42834112016-09-22 13:38:2017327 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117328 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417329
17330 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117331 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417332
bnc691fda62016-08-12 00:43:1617333 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5217334 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5417335
wezca1070932016-05-26 20:30:5217336 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5417337 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
17338
17339 std::string response_data;
bnc691fda62016-08-12 00:43:1617340 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0117341 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417342 EXPECT_EQ("hello world", response_data);
17343}
17344
17345// This tests the more common case than the previous test, where headers and
17346// body are not merged into a single request.
bncd16676a2016-07-20 16:23:0117347TEST_F(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
mmenkecbc2b712014-10-09 20:29:0717348 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5417349
17350 HttpRequestInfo request;
17351 request.method = "POST";
17352 request.url = GURL("http://www.foo.com/");
17353 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017354 request.traffic_annotation =
17355 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417356
danakj1fd259a02016-04-16 03:17:0917357 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617358 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417359 // Send headers successfully, but get an error while sending the body.
17360 MockWrite data_writes[] = {
17361 MockWrite("POST / HTTP/1.1\r\n"
17362 "Host: www.foo.com\r\n"
17363 "Connection: keep-alive\r\n"
17364 "Transfer-Encoding: chunked\r\n\r\n"),
17365 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17366 };
17367
17368 MockRead data_reads[] = {
17369 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
17370 MockRead("hello world"),
17371 MockRead(SYNCHRONOUS, OK),
17372 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117373 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417374 session_deps_.socket_factory->AddSocketDataProvider(&data);
17375
17376 TestCompletionCallback callback;
17377
tfarina42834112016-09-22 13:38:2017378 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117379 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417380 // Make sure the headers are sent before adding a chunk. This ensures that
17381 // they can't be merged with the body in a single send. Not currently
17382 // necessary since a chunked body is never merged with headers, but this makes
17383 // the test more future proof.
17384 base::RunLoop().RunUntilIdle();
17385
mmenkecbc2b712014-10-09 20:29:0717386 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5417387
17388 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117389 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417390
bnc691fda62016-08-12 00:43:1617391 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5217392 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5417393
wezca1070932016-05-26 20:30:5217394 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5417395 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
17396
17397 std::string response_data;
bnc691fda62016-08-12 00:43:1617398 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0117399 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417400 EXPECT_EQ("hello world", response_data);
17401}
17402
bncd16676a2016-07-20 16:23:0117403TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0917404 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217405 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917406 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217407 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417408
17409 HttpRequestInfo request;
17410 request.method = "POST";
17411 request.url = GURL("http://www.foo.com/");
17412 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017413 request.traffic_annotation =
17414 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417415
danakj1fd259a02016-04-16 03:17:0917416 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617417 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417418
17419 MockWrite data_writes[] = {
17420 MockWrite("POST / HTTP/1.1\r\n"
17421 "Host: www.foo.com\r\n"
17422 "Connection: keep-alive\r\n"
17423 "Content-Length: 3\r\n\r\n"),
17424 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17425 };
17426
17427 MockRead data_reads[] = {
17428 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
17429 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
17430 MockRead("hello world"),
17431 MockRead(SYNCHRONOUS, OK),
17432 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117433 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417434 session_deps_.socket_factory->AddSocketDataProvider(&data);
17435
17436 TestCompletionCallback callback;
17437
tfarina42834112016-09-22 13:38:2017438 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117439 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417440
17441 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117442 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417443
bnc691fda62016-08-12 00:43:1617444 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5217445 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5417446
wezca1070932016-05-26 20:30:5217447 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5417448 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
17449
17450 std::string response_data;
bnc691fda62016-08-12 00:43:1617451 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0117452 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417453 EXPECT_EQ("hello world", response_data);
17454}
17455
bncd16676a2016-07-20 16:23:0117456TEST_F(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0917457 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217458 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917459 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217460 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417461
17462 HttpRequestInfo request;
17463 request.method = "POST";
17464 request.url = GURL("http://www.foo.com/");
17465 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017466 request.traffic_annotation =
17467 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417468
danakj1fd259a02016-04-16 03:17:0917469 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617470 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417471 // Send headers successfully, but get an error while sending the body.
17472 MockWrite data_writes[] = {
17473 MockWrite("POST / HTTP/1.1\r\n"
17474 "Host: www.foo.com\r\n"
17475 "Connection: keep-alive\r\n"
17476 "Content-Length: 3\r\n\r\n"),
17477 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17478 };
17479
17480 MockRead data_reads[] = {
17481 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
17482 MockRead("hello world"),
17483 MockRead(SYNCHRONOUS, OK),
17484 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117485 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417486 session_deps_.socket_factory->AddSocketDataProvider(&data);
17487
17488 TestCompletionCallback callback;
17489
tfarina42834112016-09-22 13:38:2017490 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117491 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417492
17493 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117494 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417495}
17496
bncd16676a2016-07-20 16:23:0117497TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5417498 PostIgnoresNonErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0917499 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217500 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917501 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217502 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417503
17504 HttpRequestInfo request;
17505 request.method = "POST";
17506 request.url = GURL("http://www.foo.com/");
17507 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017508 request.traffic_annotation =
17509 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417510
danakj1fd259a02016-04-16 03:17:0917511 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617512 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417513 // Send headers successfully, but get an error while sending the body.
17514 MockWrite data_writes[] = {
17515 MockWrite("POST / HTTP/1.1\r\n"
17516 "Host: www.foo.com\r\n"
17517 "Connection: keep-alive\r\n"
17518 "Content-Length: 3\r\n\r\n"),
17519 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17520 };
17521
17522 MockRead data_reads[] = {
17523 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
17524 MockRead("HTTP/1.0 302 Redirect\r\n"),
17525 MockRead("Location: http://somewhere-else.com/\r\n"),
17526 MockRead("Content-Length: 0\r\n\r\n"),
17527 MockRead(SYNCHRONOUS, OK),
17528 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117529 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417530 session_deps_.socket_factory->AddSocketDataProvider(&data);
17531
17532 TestCompletionCallback callback;
17533
tfarina42834112016-09-22 13:38:2017534 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117535 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417536
17537 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117538 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417539}
17540
bncd16676a2016-07-20 16:23:0117541TEST_F(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0917542 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217543 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917544 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217545 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417546
17547 HttpRequestInfo request;
17548 request.method = "POST";
17549 request.url = GURL("http://www.foo.com/");
17550 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017551 request.traffic_annotation =
17552 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417553
danakj1fd259a02016-04-16 03:17:0917554 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617555 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417556 // Send headers successfully, but get an error while sending the body.
17557 MockWrite data_writes[] = {
17558 MockWrite("POST / HTTP/1.1\r\n"
17559 "Host: www.foo.com\r\n"
17560 "Connection: keep-alive\r\n"
17561 "Content-Length: 3\r\n\r\n"),
17562 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17563 };
17564
17565 MockRead data_reads[] = {
17566 MockRead("HTTP 0.9 rocks!"),
17567 MockRead(SYNCHRONOUS, OK),
17568 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117569 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417570 session_deps_.socket_factory->AddSocketDataProvider(&data);
17571
17572 TestCompletionCallback callback;
17573
tfarina42834112016-09-22 13:38:2017574 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117575 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417576
17577 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117578 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417579}
17580
bncd16676a2016-07-20 16:23:0117581TEST_F(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
danakj1fd259a02016-04-16 03:17:0917582 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217583 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917584 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217585 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417586
17587 HttpRequestInfo request;
17588 request.method = "POST";
17589 request.url = GURL("http://www.foo.com/");
17590 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017591 request.traffic_annotation =
17592 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417593
danakj1fd259a02016-04-16 03:17:0917594 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617595 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417596 // Send headers successfully, but get an error while sending the body.
17597 MockWrite data_writes[] = {
17598 MockWrite("POST / HTTP/1.1\r\n"
17599 "Host: www.foo.com\r\n"
17600 "Connection: keep-alive\r\n"
17601 "Content-Length: 3\r\n\r\n"),
17602 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17603 };
17604
17605 MockRead data_reads[] = {
17606 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
17607 MockRead(SYNCHRONOUS, OK),
17608 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117609 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417610 session_deps_.socket_factory->AddSocketDataProvider(&data);
17611
17612 TestCompletionCallback callback;
17613
tfarina42834112016-09-22 13:38:2017614 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117615 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417616
17617 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117618 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417619}
17620
Bence Békydca6bd92018-01-30 13:43:0617621#if BUILDFLAG(ENABLE_WEBSOCKETS)
17622
17623namespace {
17624
17625void AddWebSocketHeaders(HttpRequestHeaders* headers) {
17626 headers->SetHeader("Connection", "Upgrade");
17627 headers->SetHeader("Upgrade", "websocket");
17628 headers->SetHeader("Origin", "http://www.example.org");
17629 headers->SetHeader("Sec-WebSocket-Version", "13");
Bence Békydca6bd92018-01-30 13:43:0617630}
17631
17632} // namespace
17633
17634TEST_F(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
Bence Béky2fcf4fa2018-04-06 20:06:0117635 for (bool secure : {true, false}) {
17636 MockWrite data_writes[] = {
17637 MockWrite("GET / HTTP/1.1\r\n"
17638 "Host: www.example.org\r\n"
17639 "Connection: Upgrade\r\n"
17640 "Upgrade: websocket\r\n"
17641 "Origin: http://www.example.org\r\n"
17642 "Sec-WebSocket-Version: 13\r\n"
17643 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
17644 "Sec-WebSocket-Extensions: permessage-deflate; "
17645 "client_max_window_bits\r\n\r\n")};
17646
17647 MockRead data_reads[] = {
17648 MockRead("HTTP/1.1 101 Switching Protocols\r\n"
17649 "Upgrade: websocket\r\n"
17650 "Connection: Upgrade\r\n"
17651 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
17652
Ryan Sleevib8d7ea02018-05-07 20:01:0117653 StaticSocketDataProvider data(data_reads, data_writes);
Bence Béky2fcf4fa2018-04-06 20:06:0117654 session_deps_.socket_factory->AddSocketDataProvider(&data);
17655 SSLSocketDataProvider ssl(ASYNC, OK);
17656 if (secure)
17657 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
Bence Békydca6bd92018-01-30 13:43:0617658
17659 HttpRequestInfo request;
17660 request.method = "GET";
Bence Béky2fcf4fa2018-04-06 20:06:0117661 request.url =
17662 GURL(secure ? "ws://www.example.org/" : "wss://www.example.org/");
17663 AddWebSocketHeaders(&request.extra_headers);
Ramin Halavatib5e433e62018-02-07 07:41:1017664 request.traffic_annotation =
17665 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Békydca6bd92018-01-30 13:43:0617666
Bence Béky2fcf4fa2018-04-06 20:06:0117667 TestWebSocketHandshakeStreamCreateHelper
17668 websocket_handshake_stream_create_helper;
Bence Béky8d1c6052018-02-07 12:48:1517669
Bence Béky2fcf4fa2018-04-06 20:06:0117670 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Bence Békydca6bd92018-01-30 13:43:0617671 HttpNetworkTransaction trans(LOW, session.get());
17672 trans.SetWebSocketHandshakeStreamCreateHelper(
Bence Béky2fcf4fa2018-04-06 20:06:0117673 &websocket_handshake_stream_create_helper);
Bence Békydca6bd92018-01-30 13:43:0617674
17675 TestCompletionCallback callback;
Bence Béky2fcf4fa2018-04-06 20:06:0117676 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17677 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Bence Békydca6bd92018-01-30 13:43:0617678
Bence Béky2fcf4fa2018-04-06 20:06:0117679 const HttpStreamRequest* stream_request = trans.stream_request_.get();
17680 ASSERT_TRUE(stream_request);
17681 EXPECT_EQ(&websocket_handshake_stream_create_helper,
17682 stream_request->websocket_handshake_stream_create_helper());
17683
17684 rv = callback.WaitForResult();
17685 EXPECT_THAT(rv, IsOk());
17686
17687 EXPECT_TRUE(data.AllReadDataConsumed());
17688 EXPECT_TRUE(data.AllWriteDataConsumed());
Bence Békydca6bd92018-01-30 13:43:0617689 }
17690}
17691
Adam Rice425cf122015-01-19 06:18:2417692// Verify that proxy headers are not sent to the destination server when
17693// establishing a tunnel for a secure WebSocket connection.
bncd16676a2016-07-20 16:23:0117694TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
Adam Rice425cf122015-01-19 06:18:2417695 HttpRequestInfo request;
17696 request.method = "GET";
bncce36dca22015-04-21 22:11:2317697 request.url = GURL("wss://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1017698 request.traffic_annotation =
17699 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417700 AddWebSocketHeaders(&request.extra_headers);
17701
17702 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:5917703 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4917704 ProxyResolutionService::CreateFixedFromPacResult(
17705 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417706
danakj1fd259a02016-04-16 03:17:0917707 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2417708
17709 // Since a proxy is configured, try to establish a tunnel.
17710 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1717711 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
17712 "Host: www.example.org:443\r\n"
17713 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417714
17715 // After calling trans->RestartWithAuth(), this is the request we should
17716 // be issuing -- the final header line contains the credentials.
rsleevidb16bb02015-11-12 23:47:1717717 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
17718 "Host: www.example.org:443\r\n"
17719 "Proxy-Connection: keep-alive\r\n"
17720 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417721
rsleevidb16bb02015-11-12 23:47:1717722 MockWrite("GET / HTTP/1.1\r\n"
17723 "Host: www.example.org\r\n"
17724 "Connection: Upgrade\r\n"
17725 "Upgrade: websocket\r\n"
17726 "Origin: http://www.example.org\r\n"
17727 "Sec-WebSocket-Version: 13\r\n"
Bence Béky8d1c6052018-02-07 12:48:1517728 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
17729 "Sec-WebSocket-Extensions: permessage-deflate; "
17730 "client_max_window_bits\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417731
17732 // The proxy responds to the connect with a 407, using a persistent
17733 // connection.
17734 MockRead data_reads[] = {
17735 // No credentials.
Bence Béky8d1c6052018-02-07 12:48:1517736 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"
17737 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
17738 "Content-Length: 0\r\n"
17739 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417740
17741 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
17742
Bence Béky8d1c6052018-02-07 12:48:1517743 MockRead("HTTP/1.1 101 Switching Protocols\r\n"
17744 "Upgrade: websocket\r\n"
17745 "Connection: Upgrade\r\n"
17746 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417747
Ryan Sleevib8d7ea02018-05-07 20:01:0117748 StaticSocketDataProvider data(data_reads, data_writes);
Adam Rice425cf122015-01-19 06:18:2417749 session_deps_.socket_factory->AddSocketDataProvider(&data);
17750 SSLSocketDataProvider ssl(ASYNC, OK);
17751 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
17752
Bence Béky8d1c6052018-02-07 12:48:1517753 TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
17754
bnc87dcefc2017-05-25 12:47:5817755 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917756 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2417757 trans->SetWebSocketHandshakeStreamCreateHelper(
17758 &websocket_stream_create_helper);
17759
17760 {
17761 TestCompletionCallback callback;
17762
tfarina42834112016-09-22 13:38:2017763 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117764 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2417765
17766 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117767 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2417768 }
17769
17770 const HttpResponseInfo* response = trans->GetResponseInfo();
17771 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5217772 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2417773 EXPECT_EQ(407, response->headers->response_code());
17774
17775 {
17776 TestCompletionCallback callback;
17777
17778 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
17779 callback.callback());
robpercival214763f2016-07-01 23:27:0117780 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2417781
17782 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117783 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2417784 }
17785
17786 response = trans->GetResponseInfo();
17787 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5217788 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2417789
17790 EXPECT_EQ(101, response->headers->response_code());
17791
17792 trans.reset();
17793 session->CloseAllConnections();
17794}
17795
17796// Verify that proxy headers are not sent to the destination server when
17797// establishing a tunnel for an insecure WebSocket connection.
17798// This requires the authentication info to be injected into the auth cache
17799// due to crbug.com/395064
17800// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
bncd16676a2016-07-20 16:23:0117801TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
Adam Rice425cf122015-01-19 06:18:2417802 HttpRequestInfo request;
17803 request.method = "GET";
bncce36dca22015-04-21 22:11:2317804 request.url = GURL("ws://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1017805 request.traffic_annotation =
17806 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417807 AddWebSocketHeaders(&request.extra_headers);
17808
17809 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:5917810 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4917811 ProxyResolutionService::CreateFixedFromPacResult(
17812 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417813
danakj1fd259a02016-04-16 03:17:0917814 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2417815
17816 MockWrite data_writes[] = {
17817 // Try to establish a tunnel for the WebSocket connection, with
17818 // credentials. Because WebSockets have a separate set of socket pools,
17819 // they cannot and will not use the same TCP/IP connection as the
17820 // preflight HTTP request.
Bence Béky8d1c6052018-02-07 12:48:1517821 MockWrite("CONNECT www.example.org:80 HTTP/1.1\r\n"
17822 "Host: www.example.org:80\r\n"
17823 "Proxy-Connection: keep-alive\r\n"
17824 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417825
Bence Béky8d1c6052018-02-07 12:48:1517826 MockWrite("GET / HTTP/1.1\r\n"
17827 "Host: www.example.org\r\n"
17828 "Connection: Upgrade\r\n"
17829 "Upgrade: websocket\r\n"
17830 "Origin: http://www.example.org\r\n"
17831 "Sec-WebSocket-Version: 13\r\n"
17832 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
17833 "Sec-WebSocket-Extensions: permessage-deflate; "
17834 "client_max_window_bits\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417835
17836 MockRead data_reads[] = {
17837 // HTTP CONNECT with credentials.
17838 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
17839
17840 // WebSocket connection established inside tunnel.
Bence Béky8d1c6052018-02-07 12:48:1517841 MockRead("HTTP/1.1 101 Switching Protocols\r\n"
17842 "Upgrade: websocket\r\n"
17843 "Connection: Upgrade\r\n"
17844 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417845
Ryan Sleevib8d7ea02018-05-07 20:01:0117846 StaticSocketDataProvider data(data_reads, data_writes);
Adam Rice425cf122015-01-19 06:18:2417847 session_deps_.socket_factory->AddSocketDataProvider(&data);
17848
17849 session->http_auth_cache()->Add(
17850 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
17851 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
17852
Bence Béky8d1c6052018-02-07 12:48:1517853 TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
17854
bnc87dcefc2017-05-25 12:47:5817855 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917856 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2417857 trans->SetWebSocketHandshakeStreamCreateHelper(
17858 &websocket_stream_create_helper);
17859
17860 TestCompletionCallback callback;
17861
tfarina42834112016-09-22 13:38:2017862 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117863 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2417864
17865 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117866 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2417867
17868 const HttpResponseInfo* response = trans->GetResponseInfo();
17869 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5217870 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2417871
17872 EXPECT_EQ(101, response->headers->response_code());
17873
17874 trans.reset();
17875 session->CloseAllConnections();
17876}
17877
Bence Békydca6bd92018-01-30 13:43:0617878#endif // BUILDFLAG(ENABLE_WEBSOCKETS)
17879
bncd16676a2016-07-20 16:23:0117880TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost) {
danakj1fd259a02016-04-16 03:17:0917881 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217882 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917883 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217884 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2217885
17886 HttpRequestInfo request;
17887 request.method = "POST";
17888 request.url = GURL("http://www.foo.com/");
17889 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017890 request.traffic_annotation =
17891 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2217892
danakj1fd259a02016-04-16 03:17:0917893 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617894 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2217895 MockWrite data_writes[] = {
17896 MockWrite("POST / HTTP/1.1\r\n"
17897 "Host: www.foo.com\r\n"
17898 "Connection: keep-alive\r\n"
17899 "Content-Length: 3\r\n\r\n"),
17900 MockWrite("foo"),
17901 };
17902
17903 MockRead data_reads[] = {
17904 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
17905 MockRead(SYNCHRONOUS, OK),
17906 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117907 StaticSocketDataProvider data(data_reads, data_writes);
sclittlefb249892015-09-10 21:33:2217908 session_deps_.socket_factory->AddSocketDataProvider(&data);
17909
17910 TestCompletionCallback callback;
17911
17912 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017913 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0117914 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2217915
17916 std::string response_data;
bnc691fda62016-08-12 00:43:1617917 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2217918
Ryan Sleevib8d7ea02018-05-07 20:01:0117919 EXPECT_EQ(CountWriteBytes(data_writes), trans.GetTotalSentBytes());
17920 EXPECT_EQ(CountReadBytes(data_reads), trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2217921}
17922
bncd16676a2016-07-20 16:23:0117923TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost100Continue) {
danakj1fd259a02016-04-16 03:17:0917924 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217925 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917926 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217927 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2217928
17929 HttpRequestInfo request;
17930 request.method = "POST";
17931 request.url = GURL("http://www.foo.com/");
17932 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017933 request.traffic_annotation =
17934 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2217935
danakj1fd259a02016-04-16 03:17:0917936 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617937 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2217938 MockWrite data_writes[] = {
17939 MockWrite("POST / HTTP/1.1\r\n"
17940 "Host: www.foo.com\r\n"
17941 "Connection: keep-alive\r\n"
17942 "Content-Length: 3\r\n\r\n"),
17943 MockWrite("foo"),
17944 };
17945
17946 MockRead data_reads[] = {
17947 MockRead("HTTP/1.1 100 Continue\r\n\r\n"),
17948 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
17949 MockRead(SYNCHRONOUS, OK),
17950 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117951 StaticSocketDataProvider data(data_reads, data_writes);
sclittlefb249892015-09-10 21:33:2217952 session_deps_.socket_factory->AddSocketDataProvider(&data);
17953
17954 TestCompletionCallback callback;
17955
17956 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017957 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0117958 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2217959
17960 std::string response_data;
bnc691fda62016-08-12 00:43:1617961 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2217962
Ryan Sleevib8d7ea02018-05-07 20:01:0117963 EXPECT_EQ(CountWriteBytes(data_writes), trans.GetTotalSentBytes());
17964 EXPECT_EQ(CountReadBytes(data_reads), trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2217965}
17966
bncd16676a2016-07-20 16:23:0117967TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) {
sclittlefb249892015-09-10 21:33:2217968 ChunkedUploadDataStream upload_data_stream(0);
17969
17970 HttpRequestInfo request;
17971 request.method = "POST";
17972 request.url = GURL("http://www.foo.com/");
17973 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017974 request.traffic_annotation =
17975 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2217976
danakj1fd259a02016-04-16 03:17:0917977 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617978 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2217979 // Send headers successfully, but get an error while sending the body.
17980 MockWrite data_writes[] = {
17981 MockWrite("POST / HTTP/1.1\r\n"
17982 "Host: www.foo.com\r\n"
17983 "Connection: keep-alive\r\n"
17984 "Transfer-Encoding: chunked\r\n\r\n"),
17985 MockWrite("1\r\nf\r\n"), MockWrite("2\r\noo\r\n"), MockWrite("0\r\n\r\n"),
17986 };
17987
17988 MockRead data_reads[] = {
17989 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
17990 MockRead(SYNCHRONOUS, OK),
17991 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117992 StaticSocketDataProvider data(data_reads, data_writes);
sclittlefb249892015-09-10 21:33:2217993 session_deps_.socket_factory->AddSocketDataProvider(&data);
17994
17995 TestCompletionCallback callback;
17996
17997 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017998 trans.Start(&request, callback.callback(), NetLogWithSource()));
sclittlefb249892015-09-10 21:33:2217999
18000 base::RunLoop().RunUntilIdle();
18001 upload_data_stream.AppendData("f", 1, false);
18002
18003 base::RunLoop().RunUntilIdle();
18004 upload_data_stream.AppendData("oo", 2, true);
18005
robpercival214763f2016-07-01 23:27:0118006 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2218007
18008 std::string response_data;
bnc691fda62016-08-12 00:43:1618009 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2218010
Ryan Sleevib8d7ea02018-05-07 20:01:0118011 EXPECT_EQ(CountWriteBytes(data_writes), trans.GetTotalSentBytes());
18012 EXPECT_EQ(CountReadBytes(data_reads), trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2218013}
18014
eustasc7d27da2017-04-06 10:33:2018015void CheckContentEncodingMatching(SpdySessionDependencies* session_deps,
18016 const std::string& accept_encoding,
18017 const std::string& content_encoding,
sky50576f32017-05-01 19:28:0318018 const std::string& location,
eustasc7d27da2017-04-06 10:33:2018019 bool should_match) {
18020 HttpRequestInfo request;
18021 request.method = "GET";
18022 request.url = GURL("http://www.foo.com/");
18023 request.extra_headers.SetHeader(HttpRequestHeaders::kAcceptEncoding,
18024 accept_encoding);
Ramin Halavatib5e433e62018-02-07 07:41:1018025 request.traffic_annotation =
18026 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
eustasc7d27da2017-04-06 10:33:2018027
18028 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps));
18029 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18030 // Send headers successfully, but get an error while sending the body.
18031 MockWrite data_writes[] = {
18032 MockWrite("GET / HTTP/1.1\r\n"
18033 "Host: www.foo.com\r\n"
18034 "Connection: keep-alive\r\n"
18035 "Accept-Encoding: "),
18036 MockWrite(accept_encoding.data()), MockWrite("\r\n\r\n"),
18037 };
18038
sky50576f32017-05-01 19:28:0318039 std::string response_code = "200 OK";
18040 std::string extra;
18041 if (!location.empty()) {
18042 response_code = "301 Redirect\r\nLocation: ";
18043 response_code.append(location);
18044 }
18045
eustasc7d27da2017-04-06 10:33:2018046 MockRead data_reads[] = {
sky50576f32017-05-01 19:28:0318047 MockRead("HTTP/1.0 "),
18048 MockRead(response_code.data()),
18049 MockRead("\r\nContent-Encoding: "),
18050 MockRead(content_encoding.data()),
18051 MockRead("\r\n\r\n"),
eustasc7d27da2017-04-06 10:33:2018052 MockRead(SYNCHRONOUS, OK),
18053 };
Ryan Sleevib8d7ea02018-05-07 20:01:0118054 StaticSocketDataProvider data(data_reads, data_writes);
eustasc7d27da2017-04-06 10:33:2018055 session_deps->socket_factory->AddSocketDataProvider(&data);
18056
18057 TestCompletionCallback callback;
18058
18059 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18060 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18061
18062 rv = callback.WaitForResult();
18063 if (should_match) {
18064 EXPECT_THAT(rv, IsOk());
18065 } else {
18066 EXPECT_THAT(rv, IsError(ERR_CONTENT_DECODING_FAILED));
18067 }
18068}
18069
18070TEST_F(HttpNetworkTransactionTest, MatchContentEncoding1) {
sky50576f32017-05-01 19:28:0318071 CheckContentEncodingMatching(&session_deps_, "gzip,sdch", "br", "", false);
eustasc7d27da2017-04-06 10:33:2018072}
18073
18074TEST_F(HttpNetworkTransactionTest, MatchContentEncoding2) {
sky50576f32017-05-01 19:28:0318075 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "", "",
18076 true);
eustasc7d27da2017-04-06 10:33:2018077}
18078
18079TEST_F(HttpNetworkTransactionTest, MatchContentEncoding3) {
18080 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
sky50576f32017-05-01 19:28:0318081 "", false);
18082}
18083
18084TEST_F(HttpNetworkTransactionTest, MatchContentEncoding4) {
18085 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
18086 "www.foo.com/other", true);
eustasc7d27da2017-04-06 10:33:2018087}
18088
xunjieli96f2a402017-06-05 17:24:2718089TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsSync) {
18090 ProxyConfig proxy_config;
18091 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
18092 proxy_config.set_pac_mandatory(true);
18093 MockAsyncProxyResolver resolver;
Lily Houghton8c2f97d2018-01-22 05:06:5918094 session_deps_.proxy_resolution_service.reset(new ProxyResolutionService(
Ramin Halavatica8d5252018-03-12 05:33:4918095 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
18096 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
Bence Béky8f9d7d3952017-10-09 19:58:0418097 std::make_unique<FailingProxyResolverFactory>(), nullptr));
xunjieli96f2a402017-06-05 17:24:2718098
18099 HttpRequestInfo request;
18100 request.method = "GET";
18101 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1018102 request.traffic_annotation =
18103 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2718104
18105 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18106 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18107
18108 TestCompletionCallback callback;
18109
18110 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18111 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18112 EXPECT_THAT(callback.WaitForResult(),
18113 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
18114}
18115
18116TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsAsync) {
18117 ProxyConfig proxy_config;
18118 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
18119 proxy_config.set_pac_mandatory(true);
18120 MockAsyncProxyResolverFactory* proxy_resolver_factory =
18121 new MockAsyncProxyResolverFactory(false);
18122 MockAsyncProxyResolver resolver;
Lily Houghton8c2f97d2018-01-22 05:06:5918123 session_deps_.proxy_resolution_service.reset(new ProxyResolutionService(
Ramin Halavatica8d5252018-03-12 05:33:4918124 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
18125 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
Lily Houghton8c2f97d2018-01-22 05:06:5918126 base::WrapUnique(proxy_resolver_factory), nullptr));
xunjieli96f2a402017-06-05 17:24:2718127 HttpRequestInfo request;
18128 request.method = "GET";
18129 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1018130 request.traffic_annotation =
18131 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2718132
18133 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18134 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18135
18136 TestCompletionCallback callback;
18137 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18138 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18139
18140 proxy_resolver_factory->pending_requests()[0]->CompleteNowWithForwarder(
18141 ERR_FAILED, &resolver);
18142 EXPECT_THAT(callback.WaitForResult(),
18143 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
18144}
18145
18146TEST_F(HttpNetworkTransactionTest, NoSupportedProxies) {
Lily Houghton8c2f97d2018-01-22 05:06:5918147 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4918148 ProxyResolutionService::CreateFixedFromPacResult(
18149 "QUIC myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2718150 session_deps_.enable_quic = false;
18151 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18152
18153 HttpRequestInfo request;
18154 request.method = "GET";
18155 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1018156 request.traffic_annotation =
18157 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2718158
18159 TestCompletionCallback callback;
18160 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18161 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18162 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18163
18164 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NO_SUPPORTED_PROXIES));
18165}
18166
Douglas Creager3cb042052018-11-06 23:08:5218167//-----------------------------------------------------------------------------
Douglas Creager134b52e2018-11-09 18:00:1418168// Reporting tests
18169
18170#if BUILDFLAG(ENABLE_REPORTING)
18171class HttpNetworkTransactionReportingTest : public HttpNetworkTransactionTest {
18172 protected:
18173 void SetUp() override {
Douglas Creageref5eecdc2018-11-09 20:50:3618174 HttpNetworkTransactionTest::SetUp();
Douglas Creager134b52e2018-11-09 18:00:1418175 auto test_reporting_context = std::make_unique<TestReportingContext>(
18176 &clock_, &tick_clock_, ReportingPolicy());
18177 test_reporting_context_ = test_reporting_context.get();
18178 session_deps_.reporting_service =
18179 ReportingService::CreateForTesting(std::move(test_reporting_context));
18180 }
18181
18182 TestReportingContext* reporting_context() const {
18183 return test_reporting_context_;
18184 }
18185
18186 void clear_reporting_service() {
18187 session_deps_.reporting_service.reset();
18188 test_reporting_context_ = nullptr;
18189 }
18190
18191 // Makes an HTTPS request that should install a valid Reporting policy.
Lily Chenfec60d92019-01-24 01:16:4218192 void RequestPolicy(CertStatus cert_status = 0) {
18193 HttpRequestInfo request;
18194 request.method = "GET";
18195 request.url = GURL(url_);
18196 request.traffic_annotation =
18197 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
18198
Douglas Creager134b52e2018-11-09 18:00:1418199 MockRead data_reads[] = {
18200 MockRead("HTTP/1.0 200 OK\r\n"),
18201 MockRead("Report-To: {\"group\": \"nel\", \"max_age\": 86400, "
18202 "\"endpoints\": [{\"url\": "
18203 "\"https://www.example.org/upload/\"}]}\r\n"),
18204 MockRead("\r\n"),
18205 MockRead("hello world"),
18206 MockRead(SYNCHRONOUS, OK),
18207 };
18208 MockWrite data_writes[] = {
18209 MockWrite("GET / HTTP/1.1\r\n"
18210 "Host: www.example.org\r\n"
18211 "Connection: keep-alive\r\n\r\n"),
18212 };
18213
Lily Chenfec60d92019-01-24 01:16:4218214 StaticSocketDataProvider reads(data_reads, data_writes);
18215 session_deps_.socket_factory->AddSocketDataProvider(&reads);
Douglas Creager134b52e2018-11-09 18:00:1418216
18217 SSLSocketDataProvider ssl(ASYNC, OK);
18218 if (request.url.SchemeIsCryptographic()) {
18219 ssl.ssl_info.cert =
18220 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
18221 ASSERT_TRUE(ssl.ssl_info.cert);
Lily Chenfec60d92019-01-24 01:16:4218222 ssl.ssl_info.cert_status = cert_status;
Douglas Creager134b52e2018-11-09 18:00:1418223 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
18224 }
18225
Douglas Creager134b52e2018-11-09 18:00:1418226 TestCompletionCallback callback;
18227 auto session = CreateSession(&session_deps_);
18228 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18229 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
Lily Chenfec60d92019-01-24 01:16:4218230 EXPECT_THAT(callback.GetResult(rv), IsOk());
Douglas Creager134b52e2018-11-09 18:00:1418231 }
18232
18233 protected:
18234 std::string url_ = "https://www.example.org/";
Douglas Creager134b52e2018-11-09 18:00:1418235
18236 private:
18237 TestReportingContext* test_reporting_context_;
18238};
18239
18240TEST_F(HttpNetworkTransactionReportingTest,
18241 DontProcessReportToHeaderNoService) {
18242 base::HistogramTester histograms;
18243 clear_reporting_service();
18244 RequestPolicy();
18245 histograms.ExpectBucketCount(
18246 ReportingHeaderParser::kHeaderOutcomeHistogram,
18247 ReportingHeaderParser::HeaderOutcome::DISCARDED_NO_REPORTING_SERVICE, 1);
18248}
18249
18250TEST_F(HttpNetworkTransactionReportingTest, DontProcessReportToHeaderHttp) {
18251 base::HistogramTester histograms;
18252 url_ = "http://www.example.org/";
18253 RequestPolicy();
18254 histograms.ExpectBucketCount(
18255 ReportingHeaderParser::kHeaderOutcomeHistogram,
18256 ReportingHeaderParser::HeaderOutcome::DISCARDED_INVALID_SSL_INFO, 1);
18257}
18258
18259TEST_F(HttpNetworkTransactionReportingTest, ProcessReportToHeaderHttps) {
18260 RequestPolicy();
18261 std::vector<const ReportingClient*> clients;
18262 reporting_context()->cache()->GetClients(&clients);
18263 ASSERT_EQ(1u, clients.size());
18264 const auto* client = clients[0];
18265 EXPECT_EQ(url::Origin::Create(GURL("https://www.example.org/")),
18266 client->origin);
18267 EXPECT_EQ(GURL("https://www.example.org/upload/"), client->endpoint);
18268 EXPECT_EQ("nel", client->group);
18269}
18270
18271TEST_F(HttpNetworkTransactionReportingTest,
18272 DontProcessReportToHeaderInvalidHttps) {
18273 base::HistogramTester histograms;
Lily Chenfec60d92019-01-24 01:16:4218274 CertStatus cert_status = CERT_STATUS_COMMON_NAME_INVALID;
18275 RequestPolicy(cert_status);
Douglas Creager134b52e2018-11-09 18:00:1418276 histograms.ExpectBucketCount(
18277 ReportingHeaderParser::kHeaderOutcomeHistogram,
18278 ReportingHeaderParser::HeaderOutcome::DISCARDED_CERT_STATUS_ERROR, 1);
18279}
18280#endif // BUILDFLAG(ENABLE_REPORTING)
18281
18282//-----------------------------------------------------------------------------
Douglas Creager3cb042052018-11-06 23:08:5218283// Network Error Logging tests
18284
18285#if BUILDFLAG(ENABLE_REPORTING)
Lily Chenfec60d92019-01-24 01:16:4218286namespace {
18287
18288const char kUserAgent[] = "Mozilla/1.0";
18289const char kReferrer[] = "https://www.referrer.org/";
18290
18291} // namespace
18292
Douglas Creager3cb042052018-11-06 23:08:5218293class HttpNetworkTransactionNetworkErrorLoggingTest
18294 : public HttpNetworkTransactionTest {
18295 protected:
18296 void SetUp() override {
Douglas Creageref5eecdc2018-11-09 20:50:3618297 HttpNetworkTransactionTest::SetUp();
Douglas Creager3cb042052018-11-06 23:08:5218298 auto network_error_logging_service =
18299 std::make_unique<TestNetworkErrorLoggingService>();
18300 test_network_error_logging_service_ = network_error_logging_service.get();
18301 session_deps_.network_error_logging_service =
18302 std::move(network_error_logging_service);
Lily Chenfec60d92019-01-24 01:16:4218303
18304 extra_headers_.SetHeader("User-Agent", kUserAgent);
18305 extra_headers_.SetHeader("Referer", kReferrer);
18306
18307 request_.method = "GET";
18308 request_.url = GURL(url_);
18309 request_.extra_headers = extra_headers_;
18310 request_.reporting_upload_depth = reporting_upload_depth_;
18311 request_.traffic_annotation =
18312 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Douglas Creager3cb042052018-11-06 23:08:5218313 }
18314
18315 TestNetworkErrorLoggingService* network_error_logging_service() const {
18316 return test_network_error_logging_service_;
18317 }
18318
18319 void clear_network_error_logging_service() {
18320 session_deps_.network_error_logging_service.reset();
18321 test_network_error_logging_service_ = nullptr;
18322 }
18323
18324 // Makes an HTTPS request that should install a valid NEL policy.
Lily Chenfec60d92019-01-24 01:16:4218325 void RequestPolicy(CertStatus cert_status = 0) {
Douglas Creageref5eecdc2018-11-09 20:50:3618326 std::string extra_header_string = extra_headers_.ToString();
Douglas Creager3cb042052018-11-06 23:08:5218327 MockRead data_reads[] = {
18328 MockRead("HTTP/1.0 200 OK\r\n"),
18329 MockRead("NEL: {\"report_to\": \"nel\", \"max_age\": 86400}\r\n"),
18330 MockRead("\r\n"),
18331 MockRead("hello world"),
18332 MockRead(SYNCHRONOUS, OK),
18333 };
18334 MockWrite data_writes[] = {
18335 MockWrite("GET / HTTP/1.1\r\n"
18336 "Host: www.example.org\r\n"
Douglas Creageref5eecdc2018-11-09 20:50:3618337 "Connection: keep-alive\r\n"),
18338 MockWrite(ASYNC, extra_header_string.data(),
18339 extra_header_string.size()),
Douglas Creager3cb042052018-11-06 23:08:5218340 };
18341
Lily Chenfec60d92019-01-24 01:16:4218342 StaticSocketDataProvider reads(data_reads, data_writes);
18343 session_deps_.socket_factory->AddSocketDataProvider(&reads);
Douglas Creager3cb042052018-11-06 23:08:5218344
18345 SSLSocketDataProvider ssl(ASYNC, OK);
Lily Chenfec60d92019-01-24 01:16:4218346 if (request_.url.SchemeIsCryptographic()) {
Douglas Creager3cb042052018-11-06 23:08:5218347 ssl.ssl_info.cert =
18348 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
18349 ASSERT_TRUE(ssl.ssl_info.cert);
Lily Chenfec60d92019-01-24 01:16:4218350 ssl.ssl_info.cert_status = cert_status;
Douglas Creager3cb042052018-11-06 23:08:5218351 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
18352 }
18353
Douglas Creager3cb042052018-11-06 23:08:5218354 TestCompletionCallback callback;
18355 auto session = CreateSession(&session_deps_);
18356 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
Lily Chenfec60d92019-01-24 01:16:4218357 int rv = trans.Start(&request_, callback.callback(), NetLogWithSource());
18358 EXPECT_THAT(callback.GetResult(rv), IsOk());
18359
18360 std::string response_data;
18361 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
18362 EXPECT_EQ("hello world", response_data);
18363 }
18364
18365 void CheckReport(size_t index,
18366 int status_code,
18367 int error_type,
18368 IPAddress server_ip = IPAddress::IPv4Localhost()) {
18369 ASSERT_LT(index, network_error_logging_service()->errors().size());
18370
18371 const NetworkErrorLoggingService::RequestDetails& error =
18372 network_error_logging_service()->errors()[index];
18373 EXPECT_EQ(url_, error.uri);
18374 EXPECT_EQ(kReferrer, error.referrer);
18375 EXPECT_EQ(kUserAgent, error.user_agent);
18376 EXPECT_EQ(server_ip, error.server_ip);
18377 EXPECT_EQ("http/1.1", error.protocol);
18378 EXPECT_EQ("GET", error.method);
18379 EXPECT_EQ(status_code, error.status_code);
18380 EXPECT_EQ(error_type, error.type);
18381 EXPECT_EQ(0, error.reporting_upload_depth);
Douglas Creager3cb042052018-11-06 23:08:5218382 }
18383
18384 protected:
18385 std::string url_ = "https://www.example.org/";
18386 CertStatus cert_status_ = 0;
Lily Chenfec60d92019-01-24 01:16:4218387 HttpRequestInfo request_;
Douglas Creageref5eecdc2018-11-09 20:50:3618388 HttpRequestHeaders extra_headers_;
18389 int reporting_upload_depth_ = 0;
Douglas Creager3cb042052018-11-06 23:08:5218390
18391 private:
18392 TestNetworkErrorLoggingService* test_network_error_logging_service_;
18393};
18394
18395TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18396 DontProcessNelHeaderNoService) {
18397 base::HistogramTester histograms;
18398 clear_network_error_logging_service();
18399 RequestPolicy();
18400 histograms.ExpectBucketCount(
18401 NetworkErrorLoggingService::kHeaderOutcomeHistogram,
18402 NetworkErrorLoggingService::HeaderOutcome::
18403 DISCARDED_NO_NETWORK_ERROR_LOGGING_SERVICE,
18404 1);
18405}
18406
18407TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18408 DontProcessNelHeaderHttp) {
18409 base::HistogramTester histograms;
18410 url_ = "http://www.example.org/";
Lily Chenfec60d92019-01-24 01:16:4218411 request_.url = GURL(url_);
Douglas Creager3cb042052018-11-06 23:08:5218412 RequestPolicy();
18413 histograms.ExpectBucketCount(
18414 NetworkErrorLoggingService::kHeaderOutcomeHistogram,
18415 NetworkErrorLoggingService::HeaderOutcome::DISCARDED_INVALID_SSL_INFO, 1);
18416}
18417
Lily Chen90ae93cc2019-02-14 01:15:3918418// Don't set NEL policies received on a proxied connection.
18419TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18420 DontProcessNelHeaderProxy) {
18421 session_deps_.proxy_resolution_service =
18422 ProxyResolutionService::CreateFixedFromPacResult(
18423 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
18424 BoundTestNetLog log;
18425 session_deps_.net_log = log.bound().net_log();
18426 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18427
18428 HttpRequestInfo request;
18429 request.method = "GET";
18430 request.url = GURL("https://www.example.org/");
18431 request.traffic_annotation =
18432 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
18433
18434 // Since we have proxy, should try to establish tunnel.
18435 MockWrite data_writes1[] = {
18436 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
18437 "Host: www.example.org:443\r\n"
18438 "Proxy-Connection: keep-alive\r\n\r\n"),
18439
18440 MockWrite("GET / HTTP/1.1\r\n"
18441 "Host: www.example.org\r\n"
18442 "Connection: keep-alive\r\n\r\n"),
18443 };
18444
18445 MockRead data_reads1[] = {
18446 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
18447
18448 MockRead("HTTP/1.1 200 OK\r\n"),
18449 MockRead("NEL: {\"report_to\": \"nel\", \"max_age\": 86400}\r\n"),
18450 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
18451 MockRead("Content-Length: 100\r\n\r\n"),
18452 MockRead(SYNCHRONOUS, OK),
18453 };
18454
18455 StaticSocketDataProvider data1(data_reads1, data_writes1);
18456 session_deps_.socket_factory->AddSocketDataProvider(&data1);
18457 SSLSocketDataProvider ssl(ASYNC, OK);
18458 ssl.ssl_info.cert =
18459 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
18460 ASSERT_TRUE(ssl.ssl_info.cert);
18461 ssl.ssl_info.cert_status = 0;
18462 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
18463
18464 TestCompletionCallback callback1;
18465 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18466
18467 int rv = trans.Start(&request, callback1.callback(), log.bound());
18468 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18469
18470 rv = callback1.WaitForResult();
18471 EXPECT_THAT(rv, IsOk());
18472
18473 const HttpResponseInfo* response = trans.GetResponseInfo();
18474 ASSERT_TRUE(response);
18475 EXPECT_EQ(200, response->headers->response_code());
18476 EXPECT_TRUE(response->was_fetched_via_proxy);
18477
18478 // No NEL header was set.
18479 EXPECT_EQ(0u, network_error_logging_service()->headers().size());
18480}
18481
Douglas Creager3cb042052018-11-06 23:08:5218482TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, ProcessNelHeaderHttps) {
18483 RequestPolicy();
18484 ASSERT_EQ(1u, network_error_logging_service()->headers().size());
18485 const auto& header = network_error_logging_service()->headers()[0];
18486 EXPECT_EQ(url::Origin::Create(GURL("https://www.example.org/")),
18487 header.origin);
18488 EXPECT_EQ(IPAddress::IPv4Localhost(), header.received_ip_address);
18489 EXPECT_EQ("{\"report_to\": \"nel\", \"max_age\": 86400}", header.value);
18490}
18491
18492TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18493 DontProcessNelHeaderInvalidHttps) {
18494 base::HistogramTester histograms;
Lily Chenfec60d92019-01-24 01:16:4218495 CertStatus cert_status = CERT_STATUS_COMMON_NAME_INVALID;
18496 RequestPolicy(cert_status);
Douglas Creager3cb042052018-11-06 23:08:5218497 histograms.ExpectBucketCount(
18498 NetworkErrorLoggingService::kHeaderOutcomeHistogram,
18499 NetworkErrorLoggingService::HeaderOutcome::DISCARDED_CERT_STATUS_ERROR,
18500 1);
18501}
Douglas Creageref5eecdc2018-11-09 20:50:3618502
Lily Chenfec60d92019-01-24 01:16:4218503TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, CreateReportSuccess) {
Douglas Creageref5eecdc2018-11-09 20:50:3618504 RequestPolicy();
18505 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
Lily Chenfec60d92019-01-24 01:16:4218506 CheckReport(0 /* index */, 200 /* status_code */, OK);
18507}
18508
18509TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18510 CreateReportErrorAfterStart) {
18511 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18512 auto trans =
18513 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18514
18515 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
18516 StaticSocketDataProvider data;
18517 data.set_connect_data(mock_connect);
18518 session_deps_.socket_factory->AddSocketDataProvider(&data);
18519
18520 TestCompletionCallback callback;
18521
18522 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
18523 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_NAME_NOT_RESOLVED));
18524
18525 trans.reset();
18526
18527 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18528 CheckReport(0 /* index */, 0 /* status_code */, ERR_NAME_NOT_RESOLVED,
18529 IPAddress() /* server_ip */);
18530}
18531
18532// Same as above except the error is ASYNC
18533TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18534 CreateReportErrorAfterStartAsync) {
18535 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18536 auto trans =
18537 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18538
18539 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
18540 StaticSocketDataProvider data;
18541 data.set_connect_data(mock_connect);
18542 session_deps_.socket_factory->AddSocketDataProvider(&data);
18543
18544 TestCompletionCallback callback;
18545
18546 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
18547 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_NAME_NOT_RESOLVED));
18548
18549 trans.reset();
18550
18551 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18552 CheckReport(0 /* index */, 0 /* status_code */, ERR_NAME_NOT_RESOLVED,
18553 IPAddress() /* server_ip */);
18554}
18555
18556TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18557 CreateReportReadBodyError) {
18558 std::string extra_header_string = extra_headers_.ToString();
18559 MockRead data_reads[] = {
18560 MockRead("HTTP/1.0 200 OK\r\n"),
18561 MockRead("Content-Length: 100\r\n\r\n"), // wrong content length
18562 MockRead("hello world"),
18563 MockRead(SYNCHRONOUS, OK),
18564 };
18565 MockWrite data_writes[] = {
18566 MockWrite("GET / HTTP/1.1\r\n"
18567 "Host: www.example.org\r\n"
18568 "Connection: keep-alive\r\n"),
18569 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18570 };
18571
18572 StaticSocketDataProvider reads(data_reads, data_writes);
18573 session_deps_.socket_factory->AddSocketDataProvider(&reads);
18574
18575 SSLSocketDataProvider ssl(ASYNC, OK);
18576 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
18577
18578 // Log start time
18579 base::TimeTicks start_time = base::TimeTicks::Now();
18580
18581 TestCompletionCallback callback;
18582 auto session = CreateSession(&session_deps_);
18583 auto trans =
18584 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18585 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
18586 EXPECT_THAT(callback.GetResult(rv), IsOk());
18587
18588 const HttpResponseInfo* response = trans->GetResponseInfo();
18589 ASSERT_TRUE(response);
18590
18591 EXPECT_TRUE(response->headers);
18592 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
18593
18594 std::string response_data;
18595 rv = ReadTransaction(trans.get(), &response_data);
18596 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
18597
18598 trans.reset();
18599
18600 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18601
18602 CheckReport(0 /* index */, 200 /* status_code */,
18603 ERR_CONTENT_LENGTH_MISMATCH);
18604 const NetworkErrorLoggingService::RequestDetails& error =
18605 network_error_logging_service()->errors()[0];
18606 EXPECT_LE(error.elapsed_time, base::TimeTicks::Now() - start_time);
18607}
18608
18609// Same as above except the final read is ASYNC.
18610TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18611 CreateReportReadBodyErrorAsync) {
18612 std::string extra_header_string = extra_headers_.ToString();
18613 MockRead data_reads[] = {
18614 MockRead("HTTP/1.0 200 OK\r\n"),
18615 MockRead("Content-Length: 100\r\n\r\n"), // wrong content length
18616 MockRead("hello world"),
18617 MockRead(ASYNC, OK),
18618 };
18619 MockWrite data_writes[] = {
18620 MockWrite("GET / HTTP/1.1\r\n"
18621 "Host: www.example.org\r\n"
18622 "Connection: keep-alive\r\n"),
18623 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18624 };
18625
18626 StaticSocketDataProvider reads(data_reads, data_writes);
18627 session_deps_.socket_factory->AddSocketDataProvider(&reads);
18628
18629 SSLSocketDataProvider ssl(ASYNC, OK);
18630 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
18631
18632 // Log start time
18633 base::TimeTicks start_time = base::TimeTicks::Now();
18634
18635 TestCompletionCallback callback;
18636 auto session = CreateSession(&session_deps_);
18637 auto trans =
18638 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18639 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
18640 EXPECT_THAT(callback.GetResult(rv), IsOk());
18641
18642 const HttpResponseInfo* response = trans->GetResponseInfo();
18643 ASSERT_TRUE(response);
18644
18645 EXPECT_TRUE(response->headers);
18646 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
18647
18648 std::string response_data;
18649 rv = ReadTransaction(trans.get(), &response_data);
18650 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
18651
18652 trans.reset();
18653
18654 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18655
18656 CheckReport(0 /* index */, 200 /* status_code */,
18657 ERR_CONTENT_LENGTH_MISMATCH);
18658 const NetworkErrorLoggingService::RequestDetails& error =
18659 network_error_logging_service()->errors()[0];
18660 EXPECT_LE(error.elapsed_time, base::TimeTicks::Now() - start_time);
18661}
18662
18663TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18664 CreateReportRestartWithAuth) {
18665 std::string extra_header_string = extra_headers_.ToString();
18666 static const base::TimeDelta kSleepDuration =
18667 base::TimeDelta::FromMilliseconds(10);
18668
18669 MockWrite data_writes1[] = {
18670 MockWrite("GET / HTTP/1.1\r\n"
18671 "Host: www.example.org\r\n"
18672 "Connection: keep-alive\r\n"),
18673 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18674 };
18675
18676 MockRead data_reads1[] = {
18677 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
18678 // Give a couple authenticate options (only the middle one is actually
18679 // supported).
18680 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
18681 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
18682 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
18683 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
18684 // Large content-length -- won't matter, as connection will be reset.
18685 MockRead("Content-Length: 10000\r\n\r\n"),
18686 MockRead(SYNCHRONOUS, ERR_FAILED),
18687 };
18688
18689 // After calling trans->RestartWithAuth(), this is the request we should
18690 // be issuing -- the final header line contains the credentials.
18691 MockWrite data_writes2[] = {
18692 MockWrite("GET / HTTP/1.1\r\n"
18693 "Host: www.example.org\r\n"
18694 "Connection: keep-alive\r\n"
18695 "Authorization: Basic Zm9vOmJhcg==\r\n"),
18696 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18697 };
18698
18699 // Lastly, the server responds with the actual content.
18700 MockRead data_reads2[] = {
18701 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
18702 MockRead("hello world"),
18703 MockRead(SYNCHRONOUS, OK),
18704 };
18705
18706 StaticSocketDataProvider data1(data_reads1, data_writes1);
18707 StaticSocketDataProvider data2(data_reads2, data_writes2);
18708 session_deps_.socket_factory->AddSocketDataProvider(&data1);
18709 session_deps_.socket_factory->AddSocketDataProvider(&data2);
18710
18711 SSLSocketDataProvider ssl1(ASYNC, OK);
18712 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
18713 SSLSocketDataProvider ssl2(ASYNC, OK);
18714 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
18715
18716 base::TimeTicks start_time = base::TimeTicks::Now();
18717 base::TimeTicks restart_time;
18718
18719 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18720 auto trans =
18721 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18722
18723 TestCompletionCallback callback1;
18724
18725 int rv = trans->Start(&request_, callback1.callback(), NetLogWithSource());
18726 EXPECT_THAT(callback1.GetResult(rv), IsOk());
18727
18728 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18729
18730 TestCompletionCallback callback2;
18731
18732 // Wait 10 ms then restart with auth
18733 FastForwardBy(kSleepDuration);
18734 restart_time = base::TimeTicks::Now();
18735 rv =
18736 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
18737 EXPECT_THAT(callback2.GetResult(rv), IsOk());
18738
18739 std::string response_data;
18740 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
18741 EXPECT_EQ("hello world", response_data);
18742
18743 trans.reset();
18744
18745 // One 401 report for the auth challenge, then a 200 report for the successful
18746 // retry. Note that we don't report the error draining the body, as the first
18747 // request already generated a report for the auth challenge.
18748 ASSERT_EQ(2u, network_error_logging_service()->errors().size());
18749
18750 // Check error report contents
18751 CheckReport(0 /* index */, 401 /* status_code */, OK);
18752 CheckReport(1 /* index */, 200 /* status_code */, OK);
18753
18754 const NetworkErrorLoggingService::RequestDetails& error1 =
18755 network_error_logging_service()->errors()[0];
18756 const NetworkErrorLoggingService::RequestDetails& error2 =
18757 network_error_logging_service()->errors()[1];
18758
18759 // Sanity-check elapsed time values
18760 EXPECT_EQ(error1.elapsed_time, restart_time - start_time - kSleepDuration);
18761 // Check that the start time is refreshed when restarting with auth.
18762 EXPECT_EQ(error2.elapsed_time, base::TimeTicks::Now() - restart_time);
18763}
18764
18765// Same as above, except draining the body before restarting fails
18766// asynchronously.
18767TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18768 CreateReportRestartWithAuthAsync) {
18769 std::string extra_header_string = extra_headers_.ToString();
18770 static const base::TimeDelta kSleepDuration =
18771 base::TimeDelta::FromMilliseconds(10);
18772
18773 MockWrite data_writes1[] = {
18774 MockWrite("GET / HTTP/1.1\r\n"
18775 "Host: www.example.org\r\n"
18776 "Connection: keep-alive\r\n"),
18777 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18778 };
18779
18780 MockRead data_reads1[] = {
18781 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
18782 // Give a couple authenticate options (only the middle one is actually
18783 // supported).
18784 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
18785 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
18786 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
18787 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
18788 // Large content-length -- won't matter, as connection will be reset.
18789 MockRead("Content-Length: 10000\r\n\r\n"),
18790 MockRead(ASYNC, ERR_FAILED),
18791 };
18792
18793 // After calling trans->RestartWithAuth(), this is the request we should
18794 // be issuing -- the final header line contains the credentials.
18795 MockWrite data_writes2[] = {
18796 MockWrite("GET / HTTP/1.1\r\n"
18797 "Host: www.example.org\r\n"
18798 "Connection: keep-alive\r\n"
18799 "Authorization: Basic Zm9vOmJhcg==\r\n"),
18800 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18801 };
18802
18803 // Lastly, the server responds with the actual content.
18804 MockRead data_reads2[] = {
18805 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
18806 MockRead("hello world"),
18807 MockRead(SYNCHRONOUS, OK),
18808 };
18809
18810 StaticSocketDataProvider data1(data_reads1, data_writes1);
18811 StaticSocketDataProvider data2(data_reads2, data_writes2);
18812 session_deps_.socket_factory->AddSocketDataProvider(&data1);
18813 session_deps_.socket_factory->AddSocketDataProvider(&data2);
18814
18815 SSLSocketDataProvider ssl1(ASYNC, OK);
18816 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
18817 SSLSocketDataProvider ssl2(ASYNC, OK);
18818 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
18819
18820 base::TimeTicks start_time = base::TimeTicks::Now();
18821 base::TimeTicks restart_time;
18822
18823 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18824 auto trans =
18825 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18826
18827 TestCompletionCallback callback1;
18828
18829 int rv = trans->Start(&request_, callback1.callback(), NetLogWithSource());
18830 EXPECT_THAT(callback1.GetResult(rv), IsOk());
18831
18832 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18833
18834 TestCompletionCallback callback2;
18835
18836 // Wait 10 ms then restart with auth
18837 FastForwardBy(kSleepDuration);
18838 restart_time = base::TimeTicks::Now();
18839 rv =
18840 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
18841 EXPECT_THAT(callback2.GetResult(rv), IsOk());
18842
18843 std::string response_data;
18844 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
18845 EXPECT_EQ("hello world", response_data);
18846
18847 trans.reset();
18848
18849 // One 401 report for the auth challenge, then a 200 report for the successful
18850 // retry. Note that we don't report the error draining the body, as the first
18851 // request already generated a report for the auth challenge.
18852 ASSERT_EQ(2u, network_error_logging_service()->errors().size());
18853
18854 // Check error report contents
18855 CheckReport(0 /* index */, 401 /* status_code */, OK);
18856 CheckReport(1 /* index */, 200 /* status_code */, OK);
18857
18858 const NetworkErrorLoggingService::RequestDetails& error1 =
18859 network_error_logging_service()->errors()[0];
18860 const NetworkErrorLoggingService::RequestDetails& error2 =
18861 network_error_logging_service()->errors()[1];
18862
18863 // Sanity-check elapsed time values
18864 EXPECT_EQ(error1.elapsed_time, restart_time - start_time - kSleepDuration);
18865 // Check that the start time is refreshed when restarting with auth.
18866 EXPECT_EQ(error2.elapsed_time, base::TimeTicks::Now() - restart_time);
18867}
18868
18869TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18870 CreateReportRetryKeepAliveConnectionReset) {
18871 std::string extra_header_string = extra_headers_.ToString();
18872 MockWrite data_writes1[] = {
18873 MockWrite("GET / HTTP/1.1\r\n"
18874 "Host: www.example.org\r\n"
18875 "Connection: keep-alive\r\n"),
18876 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18877 MockWrite("GET / HTTP/1.1\r\n"
18878 "Host: www.example.org\r\n"
18879 "Connection: keep-alive\r\n"),
18880 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18881 };
18882
18883 MockRead data_reads1[] = {
18884 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
18885 MockRead("hello"),
18886 // Connection is reset
18887 MockRead(ASYNC, ERR_CONNECTION_RESET),
18888 };
18889
18890 // Successful retry
18891 MockRead data_reads2[] = {
18892 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
18893 MockRead("world"),
18894 MockRead(ASYNC, OK),
18895 };
18896
18897 StaticSocketDataProvider data1(data_reads1, data_writes1);
18898 StaticSocketDataProvider data2(data_reads2, base::span<MockWrite>());
18899 session_deps_.socket_factory->AddSocketDataProvider(&data1);
18900 session_deps_.socket_factory->AddSocketDataProvider(&data2);
18901
18902 SSLSocketDataProvider ssl1(ASYNC, OK);
18903 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
18904 SSLSocketDataProvider ssl2(ASYNC, OK);
18905 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
18906
18907 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18908 auto trans1 =
18909 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18910
18911 TestCompletionCallback callback1;
18912
18913 int rv = trans1->Start(&request_, callback1.callback(), NetLogWithSource());
18914 EXPECT_THAT(callback1.GetResult(rv), IsOk());
18915
18916 std::string response_data;
18917 ASSERT_THAT(ReadTransaction(trans1.get(), &response_data), IsOk());
18918 EXPECT_EQ("hello", response_data);
18919
18920 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18921
18922 auto trans2 =
18923 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18924
18925 TestCompletionCallback callback2;
18926
18927 rv = trans2->Start(&request_, callback2.callback(), NetLogWithSource());
18928 EXPECT_THAT(callback2.GetResult(rv), IsOk());
18929
18930 ASSERT_THAT(ReadTransaction(trans2.get(), &response_data), IsOk());
18931 EXPECT_EQ("world", response_data);
18932
18933 trans1.reset();
18934 trans2.reset();
18935
18936 // One OK report from first request, then a ERR_CONNECTION_RESET report from
18937 // the second request, then an OK report from the successful retry.
18938 ASSERT_EQ(3u, network_error_logging_service()->errors().size());
18939
18940 // Check error report contents
18941 CheckReport(0 /* index */, 200 /* status_code */, OK);
18942 CheckReport(1 /* index */, 0 /* status_code */, ERR_CONNECTION_RESET);
18943 CheckReport(2 /* index */, 200 /* status_code */, OK);
18944}
18945
18946TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18947 CreateReportRetryKeepAlive408) {
18948 std::string extra_header_string = extra_headers_.ToString();
18949 MockWrite data_writes1[] = {
18950 MockWrite("GET / HTTP/1.1\r\n"
18951 "Host: www.example.org\r\n"
18952 "Connection: keep-alive\r\n"),
18953 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18954 MockWrite("GET / HTTP/1.1\r\n"
18955 "Host: www.example.org\r\n"
18956 "Connection: keep-alive\r\n"),
18957 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18958 };
18959
18960 MockRead data_reads1[] = {
18961 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
18962 MockRead("hello"),
18963 // 408 Request Timeout
18964 MockRead(SYNCHRONOUS,
18965 "HTTP/1.1 408 Request Timeout\r\n"
18966 "Connection: Keep-Alive\r\n"
18967 "Content-Length: 6\r\n\r\n"
18968 "Pickle"),
18969 };
18970
18971 // Successful retry
18972 MockRead data_reads2[] = {
18973 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
18974 MockRead("world"),
18975 MockRead(ASYNC, OK),
18976 };
18977
18978 StaticSocketDataProvider data1(data_reads1, data_writes1);
18979 StaticSocketDataProvider data2(data_reads2, base::span<MockWrite>());
18980 session_deps_.socket_factory->AddSocketDataProvider(&data1);
18981 session_deps_.socket_factory->AddSocketDataProvider(&data2);
18982
18983 SSLSocketDataProvider ssl1(ASYNC, OK);
18984 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
18985 SSLSocketDataProvider ssl2(ASYNC, OK);
18986 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
18987
18988 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18989 auto trans1 =
18990 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18991
18992 TestCompletionCallback callback1;
18993
18994 int rv = trans1->Start(&request_, callback1.callback(), NetLogWithSource());
18995 EXPECT_THAT(callback1.GetResult(rv), IsOk());
18996
18997 std::string response_data;
18998 ASSERT_THAT(ReadTransaction(trans1.get(), &response_data), IsOk());
18999 EXPECT_EQ("hello", response_data);
19000
19001 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
19002
19003 auto trans2 =
19004 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19005
19006 TestCompletionCallback callback2;
19007
19008 rv = trans2->Start(&request_, callback2.callback(), NetLogWithSource());
19009 EXPECT_THAT(callback2.GetResult(rv), IsOk());
19010
19011 ASSERT_THAT(ReadTransaction(trans2.get(), &response_data), IsOk());
19012 EXPECT_EQ("world", response_data);
19013
19014 trans1.reset();
19015 trans2.reset();
19016
19017 // One 200 report from first request, then a 408 report from
19018 // the second request, then a 200 report from the successful retry.
19019 ASSERT_EQ(3u, network_error_logging_service()->errors().size());
19020
19021 // Check error report contents
19022 CheckReport(0 /* index */, 200 /* status_code */, OK);
19023 CheckReport(1 /* index */, 408 /* status_code */, OK);
19024 CheckReport(2 /* index */, 200 /* status_code */, OK);
19025}
19026
19027TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
19028 CreateReportRetry421WithoutConnectionPooling) {
19029 // Two hosts resolve to the same IP address.
19030 const std::string ip_addr = "1.2.3.4";
19031 IPAddress ip;
19032 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
19033 IPEndPoint peer_addr = IPEndPoint(ip, 443);
19034
19035 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
19036 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
19037 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
19038
19039 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19040
19041 // Two requests on the first connection.
19042 spdy::SpdySerializedFrame req1(
19043 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
19044 spdy_util_.UpdateWithStreamDestruction(1);
19045 spdy::SpdySerializedFrame req2(
19046 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
19047 spdy::SpdySerializedFrame rst(
19048 spdy_util_.ConstructSpdyRstStream(3, spdy::ERROR_CODE_CANCEL));
19049 MockWrite writes1[] = {
19050 CreateMockWrite(req1, 0),
19051 CreateMockWrite(req2, 3),
19052 CreateMockWrite(rst, 6),
19053 };
19054
19055 // The first one succeeds, the second gets error 421 Misdirected Request.
19056 spdy::SpdySerializedFrame resp1(
19057 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
19058 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
19059 spdy::SpdyHeaderBlock response_headers;
19060 response_headers[spdy::kHttp2StatusHeader] = "421";
19061 spdy::SpdySerializedFrame resp2(
19062 spdy_util_.ConstructSpdyReply(3, std::move(response_headers)));
19063 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
19064 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
19065
19066 MockConnect connect1(ASYNC, OK, peer_addr);
19067 SequencedSocketData data1(connect1, reads1, writes1);
19068 session_deps_.socket_factory->AddSocketDataProvider(&data1);
19069
19070 AddSSLSocketData();
19071
19072 // Retry the second request on a second connection.
19073 SpdyTestUtil spdy_util2;
19074 spdy::SpdySerializedFrame req3(
19075 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
19076 MockWrite writes2[] = {
19077 CreateMockWrite(req3, 0),
19078 };
19079
19080 spdy::SpdySerializedFrame resp3(
19081 spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
19082 spdy::SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
19083 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
19084 MockRead(ASYNC, 0, 3)};
19085
19086 MockConnect connect2(ASYNC, OK, peer_addr);
19087 SequencedSocketData data2(connect2, reads2, writes2);
19088 session_deps_.socket_factory->AddSocketDataProvider(&data2);
19089
19090 AddSSLSocketData();
19091
19092 // Preload mail.example.org into HostCache.
19093 HostPortPair host_port("mail.example.org", 443);
19094 HostResolver::RequestInfo resolve_info(host_port);
19095 AddressList ignored;
19096 std::unique_ptr<HostResolver::Request> request;
19097 TestCompletionCallback callback;
19098 int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
19099 &ignored, callback.callback(),
19100 &request, NetLogWithSource());
19101 EXPECT_THAT(callback.GetResult(rv), IsOk());
19102
19103 HttpRequestInfo request1;
19104 request1.method = "GET";
19105 request1.url = GURL("https://www.example.org/");
19106 request1.load_flags = 0;
19107 request1.traffic_annotation =
19108 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19109 auto trans1 =
19110 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19111
19112 rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
19113 EXPECT_THAT(callback.GetResult(rv), IsOk());
19114
19115 const HttpResponseInfo* response = trans1->GetResponseInfo();
19116 ASSERT_TRUE(response);
19117 ASSERT_TRUE(response->headers);
19118 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
19119 EXPECT_TRUE(response->was_fetched_via_spdy);
19120 EXPECT_TRUE(response->was_alpn_negotiated);
19121 std::string response_data;
19122 ASSERT_THAT(ReadTransaction(trans1.get(), &response_data), IsOk());
19123 EXPECT_EQ("hello!", response_data);
19124
19125 trans1.reset();
19126
19127 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
19128
19129 HttpRequestInfo request2;
19130 request2.method = "GET";
19131 request2.url = GURL("https://mail.example.org/");
19132 request2.load_flags = 0;
19133 request2.traffic_annotation =
19134 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19135 auto trans2 =
19136 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19137
19138 BoundTestNetLog log;
19139 rv = trans2->Start(&request2, callback.callback(), log.bound());
19140 EXPECT_THAT(callback.GetResult(rv), IsOk());
19141
19142 response = trans2->GetResponseInfo();
19143 ASSERT_TRUE(response);
19144 ASSERT_TRUE(response->headers);
19145 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
19146 EXPECT_TRUE(response->was_fetched_via_spdy);
19147 EXPECT_TRUE(response->was_alpn_negotiated);
19148 ASSERT_THAT(ReadTransaction(trans2.get(), &response_data), IsOk());
19149 EXPECT_EQ("hello!", response_data);
19150
19151 trans2.reset();
19152
19153 // One 200 report from the first request, then a 421 report from the
19154 // second request, then a 200 report from the successful retry.
19155 ASSERT_EQ(3u, network_error_logging_service()->errors().size());
19156
19157 // Check error report contents
19158 const NetworkErrorLoggingService::RequestDetails& error1 =
19159 network_error_logging_service()->errors()[0];
19160 EXPECT_EQ(GURL("https://www.example.org/"), error1.uri);
19161 EXPECT_TRUE(error1.referrer.is_empty());
19162 EXPECT_EQ("", error1.user_agent);
19163 EXPECT_EQ(ip, error1.server_ip);
19164 EXPECT_EQ("h2", error1.protocol);
19165 EXPECT_EQ("GET", error1.method);
19166 EXPECT_EQ(200, error1.status_code);
19167 EXPECT_EQ(OK, error1.type);
19168 EXPECT_EQ(0, error1.reporting_upload_depth);
19169
19170 const NetworkErrorLoggingService::RequestDetails& error2 =
19171 network_error_logging_service()->errors()[1];
19172 EXPECT_EQ(GURL("https://mail.example.org/"), error2.uri);
19173 EXPECT_TRUE(error2.referrer.is_empty());
19174 EXPECT_EQ("", error2.user_agent);
19175 EXPECT_EQ(ip, error2.server_ip);
19176 EXPECT_EQ("h2", error2.protocol);
19177 EXPECT_EQ("GET", error2.method);
19178 EXPECT_EQ(421, error2.status_code);
19179 EXPECT_EQ(OK, error2.type);
19180 EXPECT_EQ(0, error2.reporting_upload_depth);
19181
19182 const NetworkErrorLoggingService::RequestDetails& error3 =
19183 network_error_logging_service()->errors()[2];
19184 EXPECT_EQ(GURL("https://mail.example.org/"), error3.uri);
19185 EXPECT_TRUE(error3.referrer.is_empty());
19186 EXPECT_EQ("", error3.user_agent);
19187 EXPECT_EQ(ip, error3.server_ip);
19188 EXPECT_EQ("h2", error3.protocol);
19189 EXPECT_EQ("GET", error3.method);
19190 EXPECT_EQ(200, error3.status_code);
19191 EXPECT_EQ(OK, error3.type);
19192 EXPECT_EQ(0, error3.reporting_upload_depth);
Douglas Creageref5eecdc2018-11-09 20:50:3619193}
19194
Lily Chen00196ab62018-12-04 19:52:2919195TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, DontCreateReportHttp) {
19196 base::HistogramTester histograms;
19197 RequestPolicy();
19198 EXPECT_EQ(1u, network_error_logging_service()->headers().size());
19199 EXPECT_EQ(1u, network_error_logging_service()->errors().size());
19200
19201 // Make HTTP request
19202 std::string extra_header_string = extra_headers_.ToString();
19203 MockRead data_reads[] = {
19204 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
19205 MockRead("hello world"),
19206 MockRead(SYNCHRONOUS, OK),
19207 };
19208 MockWrite data_writes[] = {
19209 MockWrite("GET / HTTP/1.1\r\n"
19210 "Host: www.example.org\r\n"
19211 "Connection: keep-alive\r\n"),
19212 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
19213 };
19214
Lily Chen00196ab62018-12-04 19:52:2919215 StaticSocketDataProvider reads(data_reads, data_writes);
19216 session_deps_.socket_factory->AddSocketDataProvider(&reads);
19217
Lily Chenfec60d92019-01-24 01:16:4219218 // Insecure url
19219 url_ = "http://www.example.org/";
19220 request_.url = GURL(url_);
19221
Lily Chen00196ab62018-12-04 19:52:2919222 TestCompletionCallback callback;
19223 auto session = CreateSession(&session_deps_);
Lily Chenfec60d92019-01-24 01:16:4219224 auto trans =
19225 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19226 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
19227 EXPECT_THAT(callback.GetResult(rv), IsOk());
19228
19229 std::string response_data;
19230 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
19231 EXPECT_EQ("hello world", response_data);
Lily Chen00196ab62018-12-04 19:52:2919232
19233 // Insecure request does not generate a report
19234 histograms.ExpectBucketCount(
19235 NetworkErrorLoggingService::kRequestOutcomeHistogram,
19236 NetworkErrorLoggingService::RequestOutcome::DISCARDED_INSECURE_ORIGIN, 1);
19237
19238 EXPECT_EQ(1u, network_error_logging_service()->errors().size());
19239}
19240
19241TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
19242 DontCreateReportHttpError) {
19243 base::HistogramTester histograms;
19244 RequestPolicy();
19245 EXPECT_EQ(1u, network_error_logging_service()->headers().size());
19246 EXPECT_EQ(1u, network_error_logging_service()->errors().size());
19247
19248 // Make HTTP request that fails
19249 MockRead data_reads[] = {
19250 MockRead("hello world"),
19251 MockRead(SYNCHRONOUS, OK),
19252 };
19253
19254 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
19255 session_deps_.socket_factory->AddSocketDataProvider(&data);
19256
Lily Chenfec60d92019-01-24 01:16:4219257 url_ = "http://www.originwithoutpolicy.com:2000/";
19258 request_.url = GURL(url_);
19259
Lily Chen00196ab62018-12-04 19:52:2919260 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19261
Lily Chen00196ab62018-12-04 19:52:2919262 auto trans =
19263 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Lily Chen00196ab62018-12-04 19:52:2919264 TestCompletionCallback callback;
Lily Chenfec60d92019-01-24 01:16:4219265 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
Lily Chen00196ab62018-12-04 19:52:2919266 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_INVALID_HTTP_RESPONSE));
19267
19268 // Insecure request does not generate a report, regardless of existence of a
19269 // policy for the origin.
19270 histograms.ExpectBucketCount(
19271 NetworkErrorLoggingService::kRequestOutcomeHistogram,
19272 NetworkErrorLoggingService::RequestOutcome::DISCARDED_INSECURE_ORIGIN, 1);
19273
19274 EXPECT_EQ(1u, network_error_logging_service()->errors().size());
19275}
19276
Lily Chen90ae93cc2019-02-14 01:15:3919277// Don't report on proxy auth challenges, don't report if connecting through a
19278// proxy.
19279TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, DontCreateReportProxy) {
19280 HttpRequestInfo request;
19281 request.method = "GET";
19282 request.url = GURL("https://www.example.org/");
19283 request.traffic_annotation =
19284 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19285
19286 // Configure against proxy server "myproxy:70".
19287 session_deps_.proxy_resolution_service =
19288 ProxyResolutionService::CreateFixedFromPacResult(
19289 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
19290 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19291
19292 // Since we have proxy, should try to establish tunnel.
19293 MockWrite data_writes1[] = {
19294 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
19295 "Host: www.example.org:443\r\n"
19296 "Proxy-Connection: keep-alive\r\n\r\n"),
19297 };
19298
19299 // The proxy responds to the connect with a 407, using a non-persistent
19300 // connection.
19301 MockRead data_reads1[] = {
19302 // No credentials.
19303 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
19304 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
19305 MockRead("Proxy-Connection: close\r\n\r\n"),
19306 };
19307
19308 MockWrite data_writes2[] = {
19309 // After calling trans->RestartWithAuth(), this is the request we should
19310 // be issuing -- the final header line contains the credentials.
19311 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
19312 "Host: www.example.org:443\r\n"
19313 "Proxy-Connection: keep-alive\r\n"
19314 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
19315
19316 MockWrite("GET / HTTP/1.1\r\n"
19317 "Host: www.example.org\r\n"
19318 "Connection: keep-alive\r\n\r\n"),
19319 };
19320
19321 MockRead data_reads2[] = {
19322 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
19323
19324 MockRead("HTTP/1.1 200 OK\r\n"),
19325 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
19326 MockRead("Content-Length: 5\r\n\r\n"),
19327 MockRead(SYNCHRONOUS, "hello"),
19328 };
19329
19330 StaticSocketDataProvider data1(data_reads1, data_writes1);
19331 session_deps_.socket_factory->AddSocketDataProvider(&data1);
19332 StaticSocketDataProvider data2(data_reads2, data_writes2);
19333 session_deps_.socket_factory->AddSocketDataProvider(&data2);
19334 SSLSocketDataProvider ssl(ASYNC, OK);
19335 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
19336
19337 TestCompletionCallback callback1;
19338
19339 auto trans =
19340 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19341
19342 int rv = trans->Start(&request, callback1.callback(), NetLogWithSource());
19343 EXPECT_THAT(callback1.GetResult(rv), IsOk());
19344
19345 const HttpResponseInfo* response = trans->GetResponseInfo();
19346 EXPECT_EQ(407, response->headers->response_code());
19347
19348 std::string response_data;
19349 rv = ReadTransaction(trans.get(), &response_data);
19350 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
19351
19352 // No NEL report is generated for the 407.
19353 EXPECT_EQ(0u, network_error_logging_service()->errors().size());
19354
19355 TestCompletionCallback callback2;
19356
19357 rv =
19358 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
19359 EXPECT_THAT(callback2.GetResult(rv), IsOk());
19360
19361 response = trans->GetResponseInfo();
19362 EXPECT_EQ(200, response->headers->response_code());
19363
19364 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
19365 EXPECT_EQ("hello", response_data);
19366
19367 trans.reset();
19368
19369 // No NEL report is generated because we are behind a proxy.
19370 EXPECT_EQ(0u, network_error_logging_service()->errors().size());
19371}
19372
Douglas Creageref5eecdc2018-11-09 20:50:3619373TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
19374 ReportContainsUploadDepth) {
19375 reporting_upload_depth_ = 7;
Lily Chenfec60d92019-01-24 01:16:4219376 request_.reporting_upload_depth = reporting_upload_depth_;
Douglas Creageref5eecdc2018-11-09 20:50:3619377 RequestPolicy();
19378 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
Lily Chenfec60d92019-01-24 01:16:4219379 const NetworkErrorLoggingService::RequestDetails& error =
19380 network_error_logging_service()->errors()[0];
Douglas Creageref5eecdc2018-11-09 20:50:3619381 EXPECT_EQ(7, error.reporting_upload_depth);
19382}
19383
Lily Chenfec60d92019-01-24 01:16:4219384TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, ReportElapsedTime) {
19385 std::string extra_header_string = extra_headers_.ToString();
19386 static const base::TimeDelta kSleepDuration =
19387 base::TimeDelta::FromMilliseconds(10);
19388
19389 std::vector<MockWrite> data_writes = {
19390 MockWrite(ASYNC, 0,
19391 "GET / HTTP/1.1\r\n"
19392 "Host: www.example.org\r\n"
19393 "Connection: keep-alive\r\n"),
19394 MockWrite(ASYNC, 1, extra_header_string.data()),
19395 };
19396
19397 std::vector<MockRead> data_reads = {
19398 // Write one byte of the status line, followed by a pause.
19399 MockRead(ASYNC, 2, "H"),
19400 MockRead(ASYNC, ERR_IO_PENDING, 3),
19401 MockRead(ASYNC, 4, "TTP/1.1 200 OK\r\n\r\n"),
19402 MockRead(ASYNC, 5, "hello world"),
19403 MockRead(SYNCHRONOUS, OK, 6),
19404 };
19405
19406 SequencedSocketData data(data_reads, data_writes);
19407 session_deps_.socket_factory->AddSocketDataProvider(&data);
19408
19409 SSLSocketDataProvider ssl(ASYNC, OK);
19410 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
19411
19412 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19413
19414 auto trans =
19415 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19416
19417 TestCompletionCallback callback;
19418
19419 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
19420 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
19421
19422 data.RunUntilPaused();
19423 ASSERT_TRUE(data.IsPaused());
19424 FastForwardBy(kSleepDuration);
19425 data.Resume();
19426
19427 EXPECT_THAT(callback.GetResult(rv), IsOk());
19428
19429 std::string response_data;
19430 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
19431 EXPECT_EQ("hello world", response_data);
19432
19433 trans.reset();
19434
Douglas Creageref5eecdc2018-11-09 20:50:3619435 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
Lily Chenfec60d92019-01-24 01:16:4219436
19437 CheckReport(0 /* index */, 200 /* status_code */, OK);
19438
19439 const NetworkErrorLoggingService::RequestDetails& error =
19440 network_error_logging_service()->errors()[0];
19441
19442 // Sanity-check elapsed time in error report
19443 EXPECT_EQ(kSleepDuration, error.elapsed_time);
Douglas Creageref5eecdc2018-11-09 20:50:3619444}
Lily Chenfec60d92019-01-24 01:16:4219445
Douglas Creager3cb042052018-11-06 23:08:5219446#endif // BUILDFLAG(ENABLE_REPORTING)
19447
[email protected]89ceba9a2009-03-21 03:46:0619448} // namespace net