blob: fe5e545c456fb0ab5480e5b2c51381f543c7e300 [file] [log] [blame]
[email protected]23e482282013-06-14 16:08:021// Copyright 2013 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit586acc5fe2008-07-26 22:42:524
[email protected]2d731a32010-04-29 01:04:065#include "net/http/http_network_transaction.h"
6
[email protected]77848d12008-11-14 00:00:227#include <math.h> // ceil
[email protected]5285d972011-10-18 18:56:348#include <stdarg.h>
sclittlebe1ccf62015-09-02 19:40:369#include <stdint.h>
danakj1fd259a02016-04-16 03:17:0910
avibf0746c2015-12-09 19:53:1411#include <limits>
rdsmith1d343be52016-10-21 20:37:5012#include <set>
[email protected]5285d972011-10-18 18:56:3413#include <string>
dchengc7eeda422015-12-26 03:56:4814#include <utility>
[email protected]95d88ffe2010-02-04 21:25:3315#include <vector>
[email protected]77848d12008-11-14 00:00:2216
Sebastien Marchand6d0558fd2019-01-25 16:49:3717#include "base/bind.h"
[email protected]68bf9152008-09-25 19:47:3018#include "base/compiler_specific.h"
[email protected]57999812013-02-24 05:40:5219#include "base/files/file_path.h"
thestigd8df0332014-09-04 06:33:2920#include "base/files/file_util.h"
[email protected]f3da152d2012-06-02 01:00:5721#include "base/json/json_writer.h"
Adam Rice425cf122015-01-19 06:18:2422#include "base/logging.h"
danakj1fd259a02016-04-16 03:17:0923#include "base/memory/ptr_util.h"
[email protected]bf828982013-08-14 18:01:4724#include "base/memory/weak_ptr.h"
Eric Orthf4db66a2019-02-19 21:35:3325#include "base/optional.h"
[email protected]a34f61ee2014-03-18 20:59:4926#include "base/run_loop.h"
Avi Drissman4365a4782018-12-28 19:26:2427#include "base/stl_util.h"
Bence Békyd74f4382018-02-20 18:26:1928#include "base/strings/string_piece.h"
[email protected]125ef482013-06-11 18:32:4729#include "base/strings/string_util.h"
[email protected]750b2f3c2013-06-07 18:41:0530#include "base/strings/utf_string_conversions.h"
Douglas Creager3cb042052018-11-06 23:08:5231#include "base/test/metrics/histogram_tester.h"
Matt Menkeecfecfc72019-02-05 19:15:2832#include "base/test/scoped_task_environment.h"
Douglas Creager134b52e2018-11-09 18:00:1433#include "base/test/simple_test_clock.h"
34#include "base/test/simple_test_tick_clock.h"
[email protected]f36a8132011-09-02 18:36:3335#include "base/test/test_file_util.h"
gabf767595f2016-05-11 18:50:3536#include "base/threading/thread_task_runner_handle.h"
[email protected]277d5942010-08-11 21:02:3537#include "net/base/auth.h"
mmenkecbc2b712014-10-09 20:29:0738#include "net/base/chunked_upload_data_stream.h"
Bence Békya25e3f72018-02-13 21:13:3939#include "net/base/completion_once_callback.h"
mmenkecbc2b712014-10-09 20:29:0740#include "net/base/elements_upload_data_stream.h"
Eric Orthf4db66a2019-02-19 21:35:3341#include "net/base/host_port_pair.h"
Tsuyoshi Horo01faed62019-02-20 22:11:3742#include "net/base/ip_endpoint.h"
[email protected]58e32bb2013-01-21 18:23:2543#include "net/base/load_timing_info.h"
44#include "net/base/load_timing_info_test_util.h"
Adam Rice425cf122015-01-19 06:18:2445#include "net/base/net_errors.h"
tbansal28e68f82016-02-04 02:56:1546#include "net/base/proxy_delegate.h"
Lily Houghton582d4622018-01-22 22:43:4047#include "net/base/proxy_server.h"
[email protected]ac790b42009-12-02 04:31:3148#include "net/base/request_priority.h"
initial.commit586acc5fe2008-07-26 22:42:5249#include "net/base/test_completion_callback.h"
tbansal28e68f82016-02-04 02:56:1550#include "net/base/test_proxy_delegate.h"
[email protected]b2d26cfd2012-12-11 10:36:0651#include "net/base/upload_bytes_element_reader.h"
[email protected]d98961652012-09-11 20:27:2152#include "net/base/upload_file_element_reader.h"
Bence Béky230ac612017-08-30 19:17:0853#include "net/cert/cert_status_flags.h"
[email protected]6e7845ae2013-03-29 21:48:1154#include "net/cert/mock_cert_verifier.h"
[email protected]f2cb3cf2013-03-21 01:40:5355#include "net/dns/mock_host_resolver.h"
[email protected]df41d0d82014-03-13 00:43:2456#include "net/http/http_auth_challenge_tokenizer.h"
[email protected]3c32c5f2010-05-18 15:18:1257#include "net/http/http_auth_handler_digest.h"
[email protected]3fd9dae2010-06-21 11:39:0058#include "net/http/http_auth_handler_mock.h"
[email protected]385a4672009-03-11 22:21:2959#include "net/http/http_auth_handler_ntlm.h"
aberentbba302d2015-12-03 10:20:1960#include "net/http/http_auth_scheme.h"
[email protected]0877e3d2009-10-17 22:29:5761#include "net/http/http_basic_stream.h"
initial.commit586acc5fe2008-07-26 22:42:5262#include "net/http/http_network_session.h"
[email protected]87bfa3f2010-09-30 14:54:5663#include "net/http/http_network_session_peer.h"
Adam Rice425cf122015-01-19 06:18:2464#include "net/http/http_request_headers.h"
mmenke5f94fda2016-06-02 20:54:1365#include "net/http/http_response_info.h"
[email protected]17291a022011-10-10 07:32:5366#include "net/http/http_server_properties_impl.h"
[email protected]0877e3d2009-10-17 22:29:5767#include "net/http/http_stream.h"
[email protected]8e6441ca2010-08-19 05:56:3868#include "net/http/http_stream_factory.h"
[email protected]c41737d2014-05-14 07:47:1969#include "net/http/http_transaction_test_util.h"
eroman87c53d62015-04-02 06:51:0770#include "net/log/net_log.h"
mikecirone8b85c432016-09-08 19:11:0071#include "net/log/net_log_event_type.h"
mikecironef22f9812016-10-04 03:40:1972#include "net/log/net_log_source.h"
vishal.b62985ca92015-04-17 08:45:5173#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4674#include "net/log/test_net_log_entry.h"
75#include "net/log/test_net_log_util.h"
Lily Houghton582d4622018-01-22 22:43:4076#include "net/proxy_resolution/mock_proxy_resolver.h"
77#include "net/proxy_resolution/proxy_config_service_fixed.h"
78#include "net/proxy_resolution/proxy_info.h"
Lily Houghtonffe89daa02018-03-09 18:30:0379#include "net/proxy_resolution/proxy_resolution_service.h"
Lily Houghton582d4622018-01-22 22:43:4080#include "net/proxy_resolution/proxy_resolver.h"
81#include "net/proxy_resolution/proxy_resolver_factory.h"
[email protected]f7984fc62009-06-22 23:26:4482#include "net/socket/client_socket_factory.h"
mmenked3641e12016-01-28 16:06:1583#include "net/socket/client_socket_pool.h"
[email protected]483fa202013-05-14 01:07:0384#include "net/socket/client_socket_pool_manager.h"
ttuttle1f2d7e92015-04-28 16:17:4785#include "net/socket/connection_attempts.h"
[email protected]a42dbd142011-11-17 16:42:0286#include "net/socket/mock_client_socket_pool_manager.h"
[email protected]bb88e1d32013-05-03 23:11:0787#include "net/socket/next_proto.h"
Paul Jensena457017a2018-01-19 23:52:0488#include "net/socket/socket_tag.h"
[email protected]f7984fc62009-06-22 23:26:4489#include "net/socket/socket_test_util.h"
Matt Menke4b412da2019-01-25 19:31:1290#include "net/socket/socks_connect_job.h"
[email protected]f7984fc62009-06-22 23:26:4491#include "net/socket/ssl_client_socket.h"
Bence Béky94658bf2018-05-11 19:22:5892#include "net/spdy/spdy_session.h"
93#include "net/spdy/spdy_session_pool.h"
94#include "net/spdy/spdy_test_util_common.h"
nharperb7441ef2016-01-25 23:54:1495#include "net/ssl/default_channel_id_store.h"
[email protected]536fd0b2013-03-14 17:41:5796#include "net/ssl/ssl_cert_request_info.h"
[email protected]e86839fd2013-08-14 18:29:0397#include "net/ssl/ssl_config_service.h"
[email protected]536fd0b2013-03-14 17:41:5798#include "net/ssl/ssl_info.h"
svaldez7872fd02015-11-19 21:10:5499#include "net/ssl/ssl_private_key.h"
[email protected]6e7845ae2013-03-29 21:48:11100#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:01101#include "net/test/gtest_util.h"
rsleevia69c79a2016-06-22 03:28:43102#include "net/test/test_data_directory.h"
Bence Béky98447b12018-05-08 03:14:01103#include "net/test/test_with_scoped_task_environment.h"
Victor Vasiliev27cc7712019-01-24 11:50:14104#include "net/third_party/quiche/src/spdy/core/spdy_framer.h"
[email protected]baee31a2018-01-18 06:10:23105#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
[email protected]831e4a32013-11-14 02:14:44106#include "net/websockets/websocket_handshake_stream_base.h"
Bence Békydca6bd92018-01-30 13:43:06107#include "net/websockets/websocket_test_util.h"
bncf4588402015-11-24 13:33:18108#include "testing/gmock/include/gmock/gmock.h"
initial.commit586acc5fe2008-07-26 22:42:52109#include "testing/gtest/include/gtest/gtest.h"
[email protected]23887f04f2008-12-02 19:20:15110#include "testing/platform_test.h"
[email protected]795cbf82013-07-22 09:37:27111#include "url/gurl.h"
initial.commit586acc5fe2008-07-26 22:42:52112
Zentaro Kavanagh5b27a6e22017-09-25 23:00:37113#if defined(NTLM_PORTABLE)
114#include "base/base64.h"
115#include "net/ntlm/ntlm_test_data.h"
116#endif
117
Douglas Creager3cb042052018-11-06 23:08:52118#if BUILDFLAG(ENABLE_REPORTING)
119#include "net/network_error_logging/network_error_logging_service.h"
120#include "net/network_error_logging/network_error_logging_test_util.h"
Douglas Creager134b52e2018-11-09 18:00:14121#include "net/reporting/reporting_cache.h"
122#include "net/reporting/reporting_client.h"
123#include "net/reporting/reporting_header_parser.h"
124#include "net/reporting/reporting_service.h"
125#include "net/reporting/reporting_test_util.h"
Douglas Creager3cb042052018-11-06 23:08:52126#endif // BUILDFLAG(ENABLE_REPORTING)
127
robpercival214763f2016-07-01 23:27:01128using net::test::IsError;
129using net::test::IsOk;
130
[email protected]ad65a3e2013-12-25 18:18:01131using base::ASCIIToUTF16;
132
initial.commit586acc5fe2008-07-26 22:42:52133//-----------------------------------------------------------------------------
134
ttuttle859dc7a2015-04-23 19:42:29135namespace net {
136
[email protected]13c8a092010-07-29 06:15:44137namespace {
138
[email protected]42cba2fb2013-03-29 19:58:57139const base::string16 kBar(ASCIIToUTF16("bar"));
140const base::string16 kBar2(ASCIIToUTF16("bar2"));
141const base::string16 kBar3(ASCIIToUTF16("bar3"));
142const base::string16 kBaz(ASCIIToUTF16("baz"));
143const base::string16 kFirst(ASCIIToUTF16("first"));
144const base::string16 kFoo(ASCIIToUTF16("foo"));
145const base::string16 kFoo2(ASCIIToUTF16("foo2"));
146const base::string16 kFoo3(ASCIIToUTF16("foo3"));
147const base::string16 kFou(ASCIIToUTF16("fou"));
148const base::string16 kSecond(ASCIIToUTF16("second"));
[email protected]42cba2fb2013-03-29 19:58:57149const base::string16 kWrongPassword(ASCIIToUTF16("wrongpassword"));
[email protected]13c8a092010-07-29 06:15:44150
bnc2df4b522016-07-08 18:17:43151const char kAlternativeServiceHttpHeader[] =
152 "Alt-Svc: h2=\"mail.example.org:443\"\r\n";
153
ttuttle859dc7a2015-04-23 19:42:29154int GetIdleSocketCountInTransportSocketPool(HttpNetworkSession* session) {
155 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
156 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02157}
158
ttuttle859dc7a2015-04-23 19:42:29159bool IsTransportSocketPoolStalled(HttpNetworkSession* session) {
160 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
161 ->IsStalled();
[email protected]043b68c82013-08-22 23:41:52162}
163
[email protected]f3da152d2012-06-02 01:00:57164// Takes in a Value created from a NetLogHttpResponseParameter, and returns
165// a JSONified list of headers as a single string. Uses single quotes instead
166// of double quotes for easier comparison. Returns false on failure.
[email protected]ea5ef4c2013-06-13 22:50:27167bool GetHeaders(base::DictionaryValue* params, std::string* headers) {
[email protected]f3da152d2012-06-02 01:00:57168 if (!params)
169 return false;
[email protected]ea5ef4c2013-06-13 22:50:27170 base::ListValue* header_list;
[email protected]f3da152d2012-06-02 01:00:57171 if (!params->GetList("headers", &header_list))
172 return false;
173 std::string double_quote_headers;
estade8d046462015-05-16 01:02:34174 base::JSONWriter::Write(*header_list, &double_quote_headers);
[email protected]466c9862013-12-03 22:05:28175 base::ReplaceChars(double_quote_headers, "\"", "'", headers);
[email protected]f3da152d2012-06-02 01:00:57176 return true;
177}
178
[email protected]029c83b62013-01-24 05:28:20179// Tests LoadTimingInfo in the case a socket is reused and no PAC script is
180// used.
ttuttle859dc7a2015-04-23 19:42:29181void TestLoadTimingReused(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20182 EXPECT_TRUE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19183 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]58e32bb2013-01-21 18:23:25184
[email protected]029c83b62013-01-24 05:28:20185 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
186 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
187
ttuttle859dc7a2015-04-23 19:42:29188 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20189 EXPECT_FALSE(load_timing_info.send_start.is_null());
[email protected]58e32bb2013-01-21 18:23:25190
191 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]58e32bb2013-01-21 18:23:25192
[email protected]3b23a222013-05-15 21:33:25193 // Set at a higher level.
[email protected]58e32bb2013-01-21 18:23:25194 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
195 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25196 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25197}
198
[email protected]029c83b62013-01-24 05:28:20199// Tests LoadTimingInfo in the case a new socket is used and no PAC script is
200// used.
ttuttle859dc7a2015-04-23 19:42:29201void TestLoadTimingNotReused(const LoadTimingInfo& load_timing_info,
[email protected]58e32bb2013-01-21 18:23:25202 int connect_timing_flags) {
[email protected]029c83b62013-01-24 05:28:20203 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19204 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20205
206 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
207 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
208
ttuttle859dc7a2015-04-23 19:42:29209 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
210 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20211 EXPECT_LE(load_timing_info.connect_timing.connect_end,
212 load_timing_info.send_start);
213
214 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20215
[email protected]3b23a222013-05-15 21:33:25216 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20217 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
218 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25219 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20220}
221
222// Tests LoadTimingInfo in the case a socket is reused and a PAC script is
223// used.
ttuttle859dc7a2015-04-23 19:42:29224void TestLoadTimingReusedWithPac(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20225 EXPECT_TRUE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19226 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20227
ttuttle859dc7a2015-04-23 19:42:29228 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20229
230 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
231 EXPECT_LE(load_timing_info.proxy_resolve_start,
232 load_timing_info.proxy_resolve_end);
233 EXPECT_LE(load_timing_info.proxy_resolve_end,
234 load_timing_info.send_start);
235 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20236
[email protected]3b23a222013-05-15 21:33:25237 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20238 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
239 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25240 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20241}
242
243// Tests LoadTimingInfo in the case a new socket is used and a PAC script is
244// used.
ttuttle859dc7a2015-04-23 19:42:29245void TestLoadTimingNotReusedWithPac(const LoadTimingInfo& load_timing_info,
[email protected]029c83b62013-01-24 05:28:20246 int connect_timing_flags) {
247 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19248 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20249
250 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
251 EXPECT_LE(load_timing_info.proxy_resolve_start,
252 load_timing_info.proxy_resolve_end);
253 EXPECT_LE(load_timing_info.proxy_resolve_end,
254 load_timing_info.connect_timing.connect_start);
ttuttle859dc7a2015-04-23 19:42:29255 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
256 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20257 EXPECT_LE(load_timing_info.connect_timing.connect_end,
258 load_timing_info.send_start);
259
260 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20261
[email protected]3b23a222013-05-15 21:33:25262 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20263 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
264 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25265 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25266}
267
Matt Menke2436b2f2018-12-11 18:07:11268// ProxyResolver that records URLs passed to it, and that can be told what
269// result to return.
270class CapturingProxyResolver : public ProxyResolver {
271 public:
272 CapturingProxyResolver()
273 : proxy_server_(ProxyServer::SCHEME_HTTP, HostPortPair("myproxy", 80)) {}
274 ~CapturingProxyResolver() override = default;
275
276 int GetProxyForURL(const GURL& url,
277 ProxyInfo* results,
278 CompletionOnceCallback callback,
279 std::unique_ptr<Request>* request,
280 const NetLogWithSource& net_log) override {
281 results->UseProxyServer(proxy_server_);
282 resolved_.push_back(url);
283 return OK;
284 }
285
286 // Sets whether the resolver should use direct connections, instead of a
287 // proxy.
288 void set_proxy_server(ProxyServer proxy_server) {
289 proxy_server_ = proxy_server;
290 }
291
292 const std::vector<GURL>& resolved() const { return resolved_; }
293
294 private:
295 std::vector<GURL> resolved_;
296
297 ProxyServer proxy_server_;
298
299 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
300};
301
302class CapturingProxyResolverFactory : public ProxyResolverFactory {
303 public:
304 explicit CapturingProxyResolverFactory(CapturingProxyResolver* resolver)
305 : ProxyResolverFactory(false), resolver_(resolver) {}
306
307 int CreateProxyResolver(const scoped_refptr<PacFileData>& pac_script,
308 std::unique_ptr<ProxyResolver>* resolver,
309 CompletionOnceCallback callback,
310 std::unique_ptr<Request>* request) override {
311 *resolver = std::make_unique<ForwardingProxyResolver>(resolver_);
312 return OK;
313 }
314
315 private:
316 ProxyResolver* resolver_;
317};
318
danakj1fd259a02016-04-16 03:17:09319std::unique_ptr<HttpNetworkSession> CreateSession(
mmenkee65e7af2015-10-13 17:16:42320 SpdySessionDependencies* session_deps) {
[email protected]c6bf8152012-12-02 07:43:34321 return SpdySessionDependencies::SpdyCreateSession(session_deps);
[email protected]e8d536192008-10-17 22:21:14322}
323
xunjieli96f2a402017-06-05 17:24:27324class FailingProxyResolverFactory : public ProxyResolverFactory {
325 public:
326 FailingProxyResolverFactory() : ProxyResolverFactory(false) {}
327
328 // ProxyResolverFactory override.
Lily Houghton99597862018-03-07 16:40:42329 int CreateProxyResolver(const scoped_refptr<PacFileData>& script_data,
330 std::unique_ptr<ProxyResolver>* result,
Bence Békycc5b88a2018-05-25 20:24:17331 CompletionOnceCallback callback,
Lily Houghton99597862018-03-07 16:40:42332 std::unique_ptr<Request>* request) override {
xunjieli96f2a402017-06-05 17:24:27333 return ERR_PAC_SCRIPT_FAILED;
334 }
335};
336
David Benjamin5cb91132018-04-06 05:54:49337class TestSSLConfigService : public SSLConfigService {
338 public:
339 explicit TestSSLConfigService(const SSLConfig& config) : config_(config) {}
Ryan Sleevib8449e02018-07-15 04:31:07340 ~TestSSLConfigService() override = default;
David Benjamin5cb91132018-04-06 05:54:49341
342 void GetSSLConfig(SSLConfig* config) override { *config = config_; }
343
Nick Harper89bc7212018-07-31 19:07:57344 bool CanShareConnectionWithClientCerts(
345 const std::string& hostname) const override {
346 return false;
347 }
348
David Benjamin5cb91132018-04-06 05:54:49349 private:
David Benjamin5cb91132018-04-06 05:54:49350 SSLConfig config_;
351};
352
[email protected]448d4ca52012-03-04 04:12:23353} // namespace
354
Bence Béky98447b12018-05-08 03:14:01355class HttpNetworkTransactionTest : public PlatformTest,
356 public WithScopedTaskEnvironment {
[email protected]483fa202013-05-14 01:07:03357 public:
bncd16676a2016-07-20 16:23:01358 ~HttpNetworkTransactionTest() override {
[email protected]483fa202013-05-14 01:07:03359 // Important to restore the per-pool limit first, since the pool limit must
360 // always be greater than group limit, and the tests reduce both limits.
361 ClientSocketPoolManager::set_max_sockets_per_pool(
362 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
363 ClientSocketPoolManager::set_max_sockets_per_group(
364 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
365 }
366
[email protected]e3ceb682011-06-28 23:55:46367 protected:
[email protected]23e482282013-06-14 16:08:02368 HttpNetworkTransactionTest()
Andrew Comminos517a92c2019-01-14 17:49:56369 : WithScopedTaskEnvironment(
370 base::test::ScopedTaskEnvironment::MainThreadType::IO_MOCK_TIME,
371 base::test::ScopedTaskEnvironment::NowSource::
372 MAIN_THREAD_MOCK_TIME),
373 ssl_(ASYNC, OK),
bnc032658ba2016-09-26 18:17:15374 old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
[email protected]483fa202013-05-14 01:07:03375 HttpNetworkSession::NORMAL_SOCKET_POOL)),
376 old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
377 HttpNetworkSession::NORMAL_SOCKET_POOL)) {
bnca86731e2017-04-17 12:31:28378 session_deps_.enable_http2_alternative_service = true;
[email protected]483fa202013-05-14 01:07:03379 }
[email protected]bb88e1d32013-05-03 23:11:07380
[email protected]e3ceb682011-06-28 23:55:46381 struct SimpleGetHelperResult {
382 int rv;
383 std::string status_line;
384 std::string response_data;
sclittlefb249892015-09-10 21:33:22385 int64_t total_received_bytes;
386 int64_t total_sent_bytes;
[email protected]58e32bb2013-01-21 18:23:25387 LoadTimingInfo load_timing_info;
ttuttle1f2d7e92015-04-28 16:17:47388 ConnectionAttempts connection_attempts;
ttuttled9dbc652015-09-29 20:00:59389 IPEndPoint remote_endpoint_after_start;
[email protected]e3ceb682011-06-28 23:55:46390 };
391
dcheng67be2b1f2014-10-27 21:47:29392 void SetUp() override {
[email protected]0b0bf032010-09-21 18:08:50393 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55394 base::RunLoop().RunUntilIdle();
Andrew Comminos517a92c2019-01-14 17:49:56395 // Set an initial delay to ensure that the first call to TimeTicks::Now()
396 // before incrementing the counter does not return a null value.
397 FastForwardBy(TimeDelta::FromSeconds(1));
[email protected]2ff8b312010-04-26 22:20:54398 }
399
dcheng67be2b1f2014-10-27 21:47:29400 void TearDown() override {
[email protected]0b0bf032010-09-21 18:08:50401 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55402 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09403 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:55404 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09405 PlatformTest::TearDown();
[email protected]0b0bf032010-09-21 18:08:50406 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55407 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09408 }
409
Andrew Comminos1f2ff1cc2018-12-14 05:22:38410 void Check100ResponseTiming(bool use_spdy);
411
[email protected]202965992011-12-07 23:04:51412 // Either |write_failure| specifies a write failure or |read_failure|
413 // specifies a read failure when using a reused socket. In either case, the
414 // failure should cause the network transaction to resend the request, and the
415 // other argument should be NULL.
416 void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
417 const MockRead* read_failure);
initial.commit586acc5fe2008-07-26 22:42:52418
[email protected]a34f61ee2014-03-18 20:59:49419 // Either |write_failure| specifies a write failure or |read_failure|
420 // specifies a read failure when using a reused socket. In either case, the
421 // failure should cause the network transaction to resend the request, and the
422 // other argument should be NULL.
423 void PreconnectErrorResendRequestTest(const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:10424 const MockRead* read_failure,
425 bool use_spdy);
[email protected]a34f61ee2014-03-18 20:59:49426
Ryan Sleevib8d7ea02018-05-07 20:01:01427 SimpleGetHelperResult SimpleGetHelperForData(
428 base::span<StaticSocketDataProvider*> providers) {
[email protected]ff007e162009-05-23 09:13:15429 SimpleGetHelperResult out;
initial.commit586acc5fe2008-07-26 22:42:52430
[email protected]ff007e162009-05-23 09:13:15431 HttpRequestInfo request;
432 request.method = "GET";
bncce36dca22015-04-21 22:11:23433 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:10434 request.traffic_annotation =
435 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:52436
vishal.b62985ca92015-04-17 08:45:51437 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:07438 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:09439 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16440 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:27441
Ryan Sleevib8d7ea02018-05-07 20:01:01442 for (auto* provider : providers) {
443 session_deps_.socket_factory->AddSocketDataProvider(provider);
[email protected]5a60c8b2011-10-19 20:14:29444 }
initial.commit586acc5fe2008-07-26 22:42:52445
[email protected]49639fa2011-12-20 23:22:41446 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52447
eroman24bc6a12015-05-06 19:55:48448 EXPECT_TRUE(log.bound().IsCapturing());
bnc691fda62016-08-12 00:43:16449 int rv = trans.Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:01450 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:52451
[email protected]ff007e162009-05-23 09:13:15452 out.rv = callback.WaitForResult();
bnc691fda62016-08-12 00:43:16453 out.total_received_bytes = trans.GetTotalReceivedBytes();
454 out.total_sent_bytes = trans.GetTotalSentBytes();
[email protected]58e32bb2013-01-21 18:23:25455
456 // Even in the failure cases that use this function, connections are always
457 // successfully established before the error.
bnc691fda62016-08-12 00:43:16458 EXPECT_TRUE(trans.GetLoadTimingInfo(&out.load_timing_info));
[email protected]58e32bb2013-01-21 18:23:25459 TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
460
[email protected]ff007e162009-05-23 09:13:15461 if (out.rv != OK)
462 return out;
463
bnc691fda62016-08-12 00:43:16464 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50465 // Can't use ASSERT_* inside helper functions like this, so
466 // return an error.
wezca1070932016-05-26 20:30:52467 if (!response || !response->headers) {
[email protected]fe2255a2011-09-20 19:37:50468 out.rv = ERR_UNEXPECTED;
469 return out;
470 }
[email protected]ff007e162009-05-23 09:13:15471 out.status_line = response->headers->GetStatusLine();
472
Tsuyoshi Horo01faed62019-02-20 22:11:37473 EXPECT_EQ("127.0.0.1", response->remote_endpoint.ToStringWithoutPort());
474 EXPECT_EQ(80, response->remote_endpoint.port());
[email protected]6d81b482011-02-22 19:47:19475
ttuttled9dbc652015-09-29 20:00:59476 bool got_endpoint =
bnc691fda62016-08-12 00:43:16477 trans.GetRemoteEndpoint(&out.remote_endpoint_after_start);
ttuttled9dbc652015-09-29 20:00:59478 EXPECT_EQ(got_endpoint,
479 out.remote_endpoint_after_start.address().size() > 0);
480
bnc691fda62016-08-12 00:43:16481 rv = ReadTransaction(&trans, &out.response_data);
robpercival214763f2016-07-01 23:27:01482 EXPECT_THAT(rv, IsOk());
[email protected]b2fcd0e2010-12-01 15:19:40483
mmenke43758e62015-05-04 21:09:46484 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40485 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:39486 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00487 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
488 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:39489 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00490 entries, pos, NetLogEventType::HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
491 NetLogEventPhase::NONE);
[email protected]ff007e162009-05-23 09:13:15492
[email protected]f3da152d2012-06-02 01:00:57493 std::string line;
494 EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
495 EXPECT_EQ("GET / HTTP/1.1\r\n", line);
496
[email protected]79e1fd62013-06-20 06:50:04497 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:16498 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:04499 std::string value;
500 EXPECT_TRUE(request_headers.GetHeader("Host", &value));
bncce36dca22015-04-21 22:11:23501 EXPECT_EQ("www.example.org", value);
[email protected]79e1fd62013-06-20 06:50:04502 EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
503 EXPECT_EQ("keep-alive", value);
504
505 std::string response_headers;
506 EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
bncce36dca22015-04-21 22:11:23507 EXPECT_EQ("['Host: www.example.org','Connection: keep-alive']",
[email protected]79e1fd62013-06-20 06:50:04508 response_headers);
[email protected]3deb9a52010-11-11 00:24:40509
bnc691fda62016-08-12 00:43:16510 out.total_received_bytes = trans.GetTotalReceivedBytes();
sclittlefb249892015-09-10 21:33:22511 // The total number of sent bytes should not have changed.
bnc691fda62016-08-12 00:43:16512 EXPECT_EQ(out.total_sent_bytes, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:22513
bnc691fda62016-08-12 00:43:16514 trans.GetConnectionAttempts(&out.connection_attempts);
[email protected]aecfbf22008-10-16 02:02:47515 return out;
[email protected]ff007e162009-05-23 09:13:15516 }
initial.commit586acc5fe2008-07-26 22:42:52517
Ryan Sleevib8d7ea02018-05-07 20:01:01518 SimpleGetHelperResult SimpleGetHelper(base::span<const MockRead> data_reads) {
sclittlefb249892015-09-10 21:33:22519 MockWrite data_writes[] = {
520 MockWrite("GET / HTTP/1.1\r\n"
521 "Host: www.example.org\r\n"
522 "Connection: keep-alive\r\n\r\n"),
523 };
[email protected]5a60c8b2011-10-19 20:14:29524
Ryan Sleevib8d7ea02018-05-07 20:01:01525 StaticSocketDataProvider reads(data_reads, data_writes);
sclittlefb249892015-09-10 21:33:22526 StaticSocketDataProvider* data[] = {&reads};
Ryan Sleevib8d7ea02018-05-07 20:01:01527 SimpleGetHelperResult out = SimpleGetHelperForData(data);
sclittlefb249892015-09-10 21:33:22528
Ryan Sleevib8d7ea02018-05-07 20:01:01529 EXPECT_EQ(CountWriteBytes(data_writes), out.total_sent_bytes);
sclittlefb249892015-09-10 21:33:22530 return out;
[email protected]b8015c42013-12-24 15:18:19531 }
532
bnc032658ba2016-09-26 18:17:15533 void AddSSLSocketData() {
534 ssl_.next_proto = kProtoHTTP2;
Ryan Sleevi4f832092017-11-21 23:25:49535 ssl_.ssl_info.cert =
536 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
537 ASSERT_TRUE(ssl_.ssl_info.cert);
bnc032658ba2016-09-26 18:17:15538 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_);
539 }
540
[email protected]ff007e162009-05-23 09:13:15541 void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
542 int expected_status);
initial.commit586acc5fe2008-07-26 22:42:52543
[email protected]ff007e162009-05-23 09:13:15544 void ConnectStatusHelper(const MockRead& status);
[email protected]bb88e1d32013-05-03 23:11:07545
[email protected]bb88e1d32013-05-03 23:11:07546 void CheckErrorIsPassedBack(int error, IoMode mode);
547
Douglas Creager134b52e2018-11-09 18:00:14548 // These clocks are defined here, even though they're only used in the
549 // Reporting tests below, since they need to be destroyed after
550 // |session_deps_|.
551 base::SimpleTestClock clock_;
552 base::SimpleTestTickClock tick_clock_;
553
[email protected]4bd46222013-05-14 19:32:23554 SpdyTestUtil spdy_util_;
[email protected]bb88e1d32013-05-03 23:11:07555 SpdySessionDependencies session_deps_;
bnc032658ba2016-09-26 18:17:15556 SSLSocketDataProvider ssl_;
[email protected]483fa202013-05-14 01:07:03557
558 // Original socket limits. Some tests set these. Safest to always restore
559 // them once each test has been run.
560 int old_max_group_sockets_;
561 int old_max_pool_sockets_;
[email protected]ff007e162009-05-23 09:13:15562};
[email protected]231d5a32008-09-13 00:45:27563
[email protected]448d4ca52012-03-04 04:12:23564namespace {
565
ryansturm49a8cb12016-06-15 16:51:09566class BeforeHeadersSentHandler {
[email protected]597a1ab2014-06-26 08:12:27567 public:
ryansturm49a8cb12016-06-15 16:51:09568 BeforeHeadersSentHandler()
569 : observed_before_headers_sent_with_proxy_(false),
570 observed_before_headers_sent_(false) {}
[email protected]597a1ab2014-06-26 08:12:27571
ryansturm49a8cb12016-06-15 16:51:09572 void OnBeforeHeadersSent(const ProxyInfo& proxy_info,
573 HttpRequestHeaders* request_headers) {
574 observed_before_headers_sent_ = true;
575 if (!proxy_info.is_http() && !proxy_info.is_https() &&
576 !proxy_info.is_quic()) {
577 return;
578 }
579 observed_before_headers_sent_with_proxy_ = true;
[email protected]597a1ab2014-06-26 08:12:27580 observed_proxy_server_uri_ = proxy_info.proxy_server().ToURI();
581 }
582
ryansturm49a8cb12016-06-15 16:51:09583 bool observed_before_headers_sent_with_proxy() const {
584 return observed_before_headers_sent_with_proxy_;
585 }
586
587 bool observed_before_headers_sent() const {
588 return observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27589 }
590
591 std::string observed_proxy_server_uri() const {
592 return observed_proxy_server_uri_;
593 }
594
595 private:
ryansturm49a8cb12016-06-15 16:51:09596 bool observed_before_headers_sent_with_proxy_;
597 bool observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27598 std::string observed_proxy_server_uri_;
599
ryansturm49a8cb12016-06-15 16:51:09600 DISALLOW_COPY_AND_ASSIGN(BeforeHeadersSentHandler);
[email protected]597a1ab2014-06-26 08:12:27601};
602
[email protected]15a5ccf82008-10-23 19:57:43603// Fill |str| with a long header list that consumes >= |size| bytes.
604void FillLargeHeadersString(std::string* str, int size) {
thestig9d3bb0c2015-01-24 00:49:51605 const char row[] =
[email protected]4ddaf2502008-10-23 18:26:19606 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
607 const int sizeof_row = strlen(row);
608 const int num_rows = static_cast<int>(
609 ceil(static_cast<float>(size) / sizeof_row));
610 const int sizeof_data = num_rows * sizeof_row;
611 DCHECK(sizeof_data >= size);
[email protected]15a5ccf82008-10-23 19:57:43612 str->reserve(sizeof_data);
[email protected]372d34a2008-11-05 21:30:51613
[email protected]4ddaf2502008-10-23 18:26:19614 for (int i = 0; i < num_rows; ++i)
[email protected]15a5ccf82008-10-23 19:57:43615 str->append(row, sizeof_row);
[email protected]4ddaf2502008-10-23 18:26:19616}
617
thakis84dff942015-07-28 20:47:38618#if defined(NTLM_PORTABLE)
Zentaro Kavanagh6ccee512017-09-28 18:34:09619uint64_t MockGetMSTime() {
620 // Tue, 23 May 2017 20:13:07 +0000
621 return 131400439870000000;
622}
623
[email protected]385a4672009-03-11 22:21:29624// Alternative functions that eliminate randomness and dependency on the local
625// host name so that the generated NTLM messages are reproducible.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:37626void MockGenerateRandom(uint8_t* output, size_t n) {
627 // This is set to 0xaa because the client challenge for testing in
628 // [MS-NLMP] Section 4.2.1 is 8 bytes of 0xaa.
629 memset(output, 0xaa, n);
[email protected]385a4672009-03-11 22:21:29630}
631
[email protected]fe2bc6a2009-03-23 16:52:20632std::string MockGetHostName() {
Zentaro Kavanagh5b27a6e22017-09-25 23:00:37633 return ntlm::test::kHostnameAscii;
[email protected]385a4672009-03-11 22:21:29634}
thakis84dff942015-07-28 20:47:38635#endif // defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29636
[email protected]e60e47a2010-07-14 03:37:18637template<typename ParentPool>
638class CaptureGroupNameSocketPool : public ParentPool {
[email protected]04e5be32009-06-26 20:00:31639 public:
[email protected]9e1bdd32011-02-03 21:48:34640 CaptureGroupNameSocketPool(HostResolver* host_resolver,
641 CertVerifier* cert_verifier);
[email protected]e60e47a2010-07-14 03:37:18642
[email protected]d80a4322009-08-14 07:07:49643 const std::string last_group_name_received() const {
644 return last_group_name_;
645 }
646
Tarun Bansal162eabe52018-01-20 01:16:39647 bool socket_requested() const { return socket_requested_; }
648
dmichaeld6e570d2014-12-18 22:30:57649 int RequestSocket(const std::string& group_name,
650 const void* socket_params,
651 RequestPriority priority,
Paul Jensen8d6f87ec2018-01-13 00:46:54652 const SocketTag& socket_tag,
mmenked3641e12016-01-28 16:06:15653 ClientSocketPool::RespectLimits respect_limits,
dmichaeld6e570d2014-12-18 22:30:57654 ClientSocketHandle* handle,
Bence Béky5a8662b2018-07-03 13:04:03655 CompletionOnceCallback callback,
tfarina42834112016-09-22 13:38:20656 const NetLogWithSource& net_log) override {
[email protected]04e5be32009-06-26 20:00:31657 last_group_name_ = group_name;
Tarun Bansal162eabe52018-01-20 01:16:39658 socket_requested_ = true;
[email protected]04e5be32009-06-26 20:00:31659 return ERR_IO_PENDING;
660 }
dmichaeld6e570d2014-12-18 22:30:57661 void CancelRequest(const std::string& group_name,
662 ClientSocketHandle* handle) override {}
663 void ReleaseSocket(const std::string& group_name,
danakj1fd259a02016-04-16 03:17:09664 std::unique_ptr<StreamSocket> socket,
dmichaeld6e570d2014-12-18 22:30:57665 int id) override {}
666 void CloseIdleSockets() override {}
xunjieli92feb332017-03-03 17:19:23667 void CloseIdleSocketsInGroup(const std::string& group_name) override {}
dmichaeld6e570d2014-12-18 22:30:57668 int IdleSocketCount() const override { return 0; }
669 int IdleSocketCountInGroup(const std::string& group_name) const override {
[email protected]04e5be32009-06-26 20:00:31670 return 0;
671 }
dmichaeld6e570d2014-12-18 22:30:57672 LoadState GetLoadState(const std::string& group_name,
673 const ClientSocketHandle* handle) const override {
[email protected]04e5be32009-06-26 20:00:31674 return LOAD_STATE_IDLE;
675 }
[email protected]d80a4322009-08-14 07:07:49676
677 private:
[email protected]04e5be32009-06-26 20:00:31678 std::string last_group_name_;
Tarun Bansal162eabe52018-01-20 01:16:39679 bool socket_requested_ = false;
[email protected]04e5be32009-06-26 20:00:31680};
681
[email protected]ab739042011-04-07 15:22:28682typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
683CaptureGroupNameTransportSocketPool;
[email protected]e60e47a2010-07-14 03:37:18684
rkaplowd90695c2015-03-25 22:12:41685template <typename ParentPool>
[email protected]e60e47a2010-07-14 03:37:18686CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34687 HostResolver* host_resolver,
688 CertVerifier* /* cert_verifier */)
Matt Menkecb77b5402019-01-28 17:11:23689 : ParentPool(0,
690 0,
Tarun Bansala7635092019-02-20 10:00:59691 base::TimeDelta(),
Matt Menkecb77b5402019-01-28 17:11:23692 NULL,
693 host_resolver,
694 NULL,
695 NULL,
696 NULL,
697 NULL,
698 NULL,
Matt Menkec94d97b2019-02-01 19:28:28699 NULL,
Matt Menke1751ba72019-02-09 02:23:46700 NULL,
Daniel McArdleda3fa942019-02-15 16:41:21701 NULL,
Matt Menkecb77b5402019-01-28 17:11:23702 NULL,
703 NULL,
Matt Menkefa9574f2019-01-28 18:55:27704 NULL,
Matt Menkecb77b5402019-01-28 17:11:23705 NULL) {}
[email protected]e60e47a2010-07-14 03:37:18706
[email protected]231d5a32008-09-13 00:45:27707//-----------------------------------------------------------------------------
708
[email protected]79cb5c12011-09-12 13:12:04709// Helper functions for validating that AuthChallengeInfo's are correctly
710// configured for common cases.
711bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
712 if (!auth_challenge)
713 return false;
714 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43715 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04716 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19717 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04718 return true;
719}
720
721bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
722 if (!auth_challenge)
723 return false;
724 EXPECT_TRUE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43725 EXPECT_EQ("http://myproxy:70", auth_challenge->challenger.Serialize());
726 EXPECT_EQ("MyRealm1", auth_challenge->realm);
727 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
728 return true;
729}
730
731bool CheckBasicSecureProxyAuth(const AuthChallengeInfo* auth_challenge) {
732 if (!auth_challenge)
733 return false;
734 EXPECT_TRUE(auth_challenge->is_proxy);
735 EXPECT_EQ("https://myproxy:70", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04736 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19737 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04738 return true;
739}
740
741bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
742 if (!auth_challenge)
743 return false;
744 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43745 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04746 EXPECT_EQ("digestive", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19747 EXPECT_EQ(kDigestAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04748 return true;
749}
750
thakis84dff942015-07-28 20:47:38751#if defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04752bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
753 if (!auth_challenge)
754 return false;
755 EXPECT_FALSE(auth_challenge->is_proxy);
Zentaro Kavanagh1890a3d2018-01-29 19:52:55756 EXPECT_EQ("https://server", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04757 EXPECT_EQ(std::string(), auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19758 EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04759 return true;
760}
David Benjamin5cb91132018-04-06 05:54:49761
762bool CheckNTLMProxyAuth(const AuthChallengeInfo* auth_challenge) {
763 if (!auth_challenge)
764 return false;
765 EXPECT_TRUE(auth_challenge->is_proxy);
766 EXPECT_EQ("http://server", auth_challenge->challenger.Serialize());
767 EXPECT_EQ(std::string(), auth_challenge->realm);
768 EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
769 return true;
770}
thakis84dff942015-07-28 20:47:38771#endif // defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04772
[email protected]448d4ca52012-03-04 04:12:23773} // namespace
774
bncd16676a2016-07-20 16:23:01775TEST_F(HttpNetworkTransactionTest, Basic) {
danakj1fd259a02016-04-16 03:17:09776 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16777 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]231d5a32008-09-13 00:45:27778}
779
bncd16676a2016-07-20 16:23:01780TEST_F(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27781 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35782 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
783 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06784 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27785 };
Ryan Sleevib8d7ea02018-05-07 20:01:01786 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01787 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27788 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
789 EXPECT_EQ("hello world", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01790 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22791 EXPECT_EQ(reads_size, out.total_received_bytes);
ttuttle1f2d7e92015-04-28 16:17:47792 EXPECT_EQ(0u, out.connection_attempts.size());
ttuttled9dbc652015-09-29 20:00:59793
794 EXPECT_FALSE(out.remote_endpoint_after_start.address().empty());
[email protected]231d5a32008-09-13 00:45:27795}
796
797// Response with no status line.
bncd16676a2016-07-20 16:23:01798TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27799 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35800 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06801 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27802 };
Ryan Sleevib8d7ea02018-05-07 20:01:01803 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41804 EXPECT_THAT(out.rv, IsOk());
805 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
806 EXPECT_EQ("hello world", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01807 int64_t reads_size = CountReadBytes(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41808 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27809}
810
mmenkea7da6da2016-09-01 21:56:52811// Response with no status line, and a weird port. Should fail by default.
812TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPort) {
813 MockRead data_reads[] = {
814 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
815 };
816
Ryan Sleevib8d7ea02018-05-07 20:01:01817 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
mmenkea7da6da2016-09-01 21:56:52818 session_deps_.socket_factory->AddSocketDataProvider(&data);
819
820 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
821
krasinc06a72a2016-12-21 03:42:46822 HttpRequestInfo request;
bnc87dcefc2017-05-25 12:47:58823 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:19824 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenkea7da6da2016-09-01 21:56:52825
mmenkea7da6da2016-09-01 21:56:52826 request.method = "GET";
827 request.url = GURL("http://www.example.com:2000/");
Ramin Halavatib5e433e2018-02-07 07:41:10828 request.traffic_annotation =
829 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
830
mmenkea7da6da2016-09-01 21:56:52831 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20832 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52833 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_INVALID_HTTP_RESPONSE));
834}
835
Shivani Sharmafdcaefd2017-11-02 00:12:26836// Tests that request info can be destroyed after the headers phase is complete.
837TEST_F(HttpNetworkTransactionTest, SimpleGETNoReadDestroyRequestInfo) {
838 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
839 auto trans =
840 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
841
842 MockRead data_reads[] = {
843 MockRead("HTTP/1.0 200 OK\r\n"), MockRead("Connection: keep-alive\r\n"),
844 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, 0),
845 };
Ryan Sleevib8d7ea02018-05-07 20:01:01846 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
Shivani Sharmafdcaefd2017-11-02 00:12:26847 session_deps_.socket_factory->AddSocketDataProvider(&data);
848
849 TestCompletionCallback callback;
850
851 {
852 auto request = std::make_unique<HttpRequestInfo>();
853 request->method = "GET";
854 request->url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:10855 request->traffic_annotation =
856 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Shivani Sharmafdcaefd2017-11-02 00:12:26857
858 int rv =
859 trans->Start(request.get(), callback.callback(), NetLogWithSource());
860
861 EXPECT_THAT(callback.GetResult(rv), IsOk());
862 } // Let request info be destroyed.
863
864 trans.reset();
865}
866
mmenkea7da6da2016-09-01 21:56:52867// Response with no status line, and a weird port. Option to allow weird ports
868// enabled.
869TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPortAllowed) {
870 MockRead data_reads[] = {
871 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
872 };
873
Ryan Sleevib8d7ea02018-05-07 20:01:01874 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
mmenkea7da6da2016-09-01 21:56:52875 session_deps_.socket_factory->AddSocketDataProvider(&data);
876 session_deps_.http_09_on_non_default_ports_enabled = true;
877 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
878
krasinc06a72a2016-12-21 03:42:46879 HttpRequestInfo request;
bnc87dcefc2017-05-25 12:47:58880 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:19881 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenkea7da6da2016-09-01 21:56:52882
mmenkea7da6da2016-09-01 21:56:52883 request.method = "GET";
884 request.url = GURL("http://www.example.com:2000/");
Ramin Halavatib5e433e2018-02-07 07:41:10885 request.traffic_annotation =
886 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
887
mmenkea7da6da2016-09-01 21:56:52888 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20889 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52890 EXPECT_THAT(callback.GetResult(rv), IsOk());
891
892 const HttpResponseInfo* info = trans->GetResponseInfo();
893 ASSERT_TRUE(info->headers);
894 EXPECT_EQ("HTTP/0.9 200 OK", info->headers->GetStatusLine());
895
896 // Don't bother to read the body - that's verified elsewhere, important thing
897 // is that the option to allow HTTP/0.9 on non-default ports is respected.
898}
899
[email protected]231d5a32008-09-13 00:45:27900// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01901TEST_F(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27902 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35903 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06904 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27905 };
Ryan Sleevib8d7ea02018-05-07 20:01:01906 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01907 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27908 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
909 EXPECT_EQ("DATA", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01910 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22911 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27912}
913
914// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01915TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27916 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35917 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06918 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27919 };
Ryan Sleevib8d7ea02018-05-07 20:01:01920 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01921 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27922 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
923 EXPECT_EQ("DATA", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01924 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22925 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27926}
927
928// Beyond 4 bytes of slop and it should fail to find a status line.
bncd16676a2016-07-20 16:23:01929TEST_F(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27930 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35931 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06932 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27933 };
Ryan Sleevib8d7ea02018-05-07 20:01:01934 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41935 EXPECT_THAT(out.rv, IsOk());
936 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
937 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01938 int64_t reads_size = CountReadBytes(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41939 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27940}
941
942// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
bncd16676a2016-07-20 16:23:01943TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27944 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35945 MockRead("\n"),
946 MockRead("\n"),
947 MockRead("Q"),
948 MockRead("J"),
949 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06950 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27951 };
Ryan Sleevib8d7ea02018-05-07 20:01:01952 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01953 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27954 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
955 EXPECT_EQ("DATA", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01956 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22957 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27958}
959
960// Close the connection before enough bytes to have a status line.
bncd16676a2016-07-20 16:23:01961TEST_F(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:27962 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35963 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:06964 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27965 };
Ryan Sleevib8d7ea02018-05-07 20:01:01966 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41967 EXPECT_THAT(out.rv, IsOk());
968 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
969 EXPECT_EQ("HTT", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01970 int64_t reads_size = CountReadBytes(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41971 EXPECT_EQ(reads_size, out.total_received_bytes);
initial.commit586acc5fe2008-07-26 22:42:52972}
973
[email protected]f9d44aa2008-09-23 23:57:17974// Simulate a 204 response, lacking a Content-Length header, sent over a
975// persistent connection. The response should still terminate since a 204
976// cannot have a response body.
bncd16676a2016-07-20 16:23:01977TEST_F(HttpNetworkTransactionTest, StopsReading204) {
[email protected]b8015c42013-12-24 15:18:19978 char junk[] = "junk";
[email protected]f9d44aa2008-09-23 23:57:17979 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35980 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
[email protected]b8015c42013-12-24 15:18:19981 MockRead(junk), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:06982 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:17983 };
Ryan Sleevib8d7ea02018-05-07 20:01:01984 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01985 EXPECT_THAT(out.rv, IsOk());
[email protected]f9d44aa2008-09-23 23:57:17986 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
987 EXPECT_EQ("", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01988 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22989 int64_t response_size = reads_size - strlen(junk);
990 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]f9d44aa2008-09-23 23:57:17991}
992
[email protected]0877e3d2009-10-17 22:29:57993// A simple request using chunked encoding with some extra data after.
bncd16676a2016-07-20 16:23:01994TEST_F(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]b8015c42013-12-24 15:18:19995 std::string final_chunk = "0\r\n\r\n";
996 std::string extra_data = "HTTP/1.1 200 OK\r\n";
997 std::string last_read = final_chunk + extra_data;
[email protected]0877e3d2009-10-17 22:29:57998 MockRead data_reads[] = {
999 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
1000 MockRead("5\r\nHello\r\n"),
1001 MockRead("1\r\n"),
1002 MockRead(" \r\n"),
1003 MockRead("5\r\nworld\r\n"),
[email protected]b8015c42013-12-24 15:18:191004 MockRead(last_read.data()),
[email protected]8ddf8322012-02-23 18:08:061005 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:571006 };
Ryan Sleevib8d7ea02018-05-07 20:01:011007 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011008 EXPECT_THAT(out.rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:571009 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1010 EXPECT_EQ("Hello world", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:011011 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:221012 int64_t response_size = reads_size - extra_data.size();
1013 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]0877e3d2009-10-17 22:29:571014}
1015
[email protected]9fe44f52010-09-23 18:36:001016// Next tests deal with http://crbug.com/56344.
1017
bncd16676a2016-07-20 16:23:011018TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001019 MultipleContentLengthHeadersNoTransferEncoding) {
1020 MockRead data_reads[] = {
1021 MockRead("HTTP/1.1 200 OK\r\n"),
1022 MockRead("Content-Length: 10\r\n"),
1023 MockRead("Content-Length: 5\r\n\r\n"),
1024 };
Ryan Sleevib8d7ea02018-05-07 20:01:011025 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011026 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]9fe44f52010-09-23 18:36:001027}
1028
bncd16676a2016-07-20 16:23:011029TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:041030 DuplicateContentLengthHeadersNoTransferEncoding) {
1031 MockRead data_reads[] = {
1032 MockRead("HTTP/1.1 200 OK\r\n"),
1033 MockRead("Content-Length: 5\r\n"),
1034 MockRead("Content-Length: 5\r\n\r\n"),
1035 MockRead("Hello"),
1036 };
Ryan Sleevib8d7ea02018-05-07 20:01:011037 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011038 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041039 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1040 EXPECT_EQ("Hello", out.response_data);
1041}
1042
bncd16676a2016-07-20 16:23:011043TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:041044 ComplexContentLengthHeadersNoTransferEncoding) {
1045 // More than 2 dupes.
1046 {
1047 MockRead data_reads[] = {
1048 MockRead("HTTP/1.1 200 OK\r\n"),
1049 MockRead("Content-Length: 5\r\n"),
1050 MockRead("Content-Length: 5\r\n"),
1051 MockRead("Content-Length: 5\r\n\r\n"),
1052 MockRead("Hello"),
1053 };
Ryan Sleevib8d7ea02018-05-07 20:01:011054 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011055 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041056 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1057 EXPECT_EQ("Hello", out.response_data);
1058 }
1059 // HTTP/1.0
1060 {
1061 MockRead data_reads[] = {
1062 MockRead("HTTP/1.0 200 OK\r\n"),
1063 MockRead("Content-Length: 5\r\n"),
1064 MockRead("Content-Length: 5\r\n"),
1065 MockRead("Content-Length: 5\r\n\r\n"),
1066 MockRead("Hello"),
1067 };
Ryan Sleevib8d7ea02018-05-07 20:01:011068 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011069 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041070 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
1071 EXPECT_EQ("Hello", out.response_data);
1072 }
1073 // 2 dupes and one mismatched.
1074 {
1075 MockRead data_reads[] = {
1076 MockRead("HTTP/1.1 200 OK\r\n"),
1077 MockRead("Content-Length: 10\r\n"),
1078 MockRead("Content-Length: 10\r\n"),
1079 MockRead("Content-Length: 5\r\n\r\n"),
1080 };
Ryan Sleevib8d7ea02018-05-07 20:01:011081 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011082 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]44b52042010-10-29 22:48:041083 }
1084}
1085
bncd16676a2016-07-20 16:23:011086TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001087 MultipleContentLengthHeadersTransferEncoding) {
1088 MockRead data_reads[] = {
1089 MockRead("HTTP/1.1 200 OK\r\n"),
1090 MockRead("Content-Length: 666\r\n"),
1091 MockRead("Content-Length: 1337\r\n"),
1092 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
1093 MockRead("5\r\nHello\r\n"),
1094 MockRead("1\r\n"),
1095 MockRead(" \r\n"),
1096 MockRead("5\r\nworld\r\n"),
1097 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:061098 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:001099 };
Ryan Sleevib8d7ea02018-05-07 20:01:011100 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011101 EXPECT_THAT(out.rv, IsOk());
[email protected]9fe44f52010-09-23 18:36:001102 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1103 EXPECT_EQ("Hello world", out.response_data);
1104}
1105
[email protected]1628fe92011-10-04 23:04:551106// Next tests deal with http://crbug.com/98895.
1107
1108// Checks that a single Content-Disposition header results in no error.
bncd16676a2016-07-20 16:23:011109TEST_F(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:551110 MockRead data_reads[] = {
1111 MockRead("HTTP/1.1 200 OK\r\n"),
1112 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
1113 MockRead("Content-Length: 5\r\n\r\n"),
1114 MockRead("Hello"),
1115 };
Ryan Sleevib8d7ea02018-05-07 20:01:011116 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011117 EXPECT_THAT(out.rv, IsOk());
[email protected]1628fe92011-10-04 23:04:551118 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1119 EXPECT_EQ("Hello", out.response_data);
1120}
1121
[email protected]54a9c6e52012-03-21 20:10:591122// Checks that two identical Content-Disposition headers result in no error.
bncd16676a2016-07-20 16:23:011123TEST_F(HttpNetworkTransactionTest, TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551124 MockRead data_reads[] = {
1125 MockRead("HTTP/1.1 200 OK\r\n"),
1126 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1127 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1128 MockRead("Content-Length: 5\r\n\r\n"),
1129 MockRead("Hello"),
1130 };
Ryan Sleevib8d7ea02018-05-07 20:01:011131 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011132 EXPECT_THAT(out.rv, IsOk());
[email protected]54a9c6e52012-03-21 20:10:591133 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1134 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:551135}
1136
1137// Checks that two distinct Content-Disposition headers result in an error.
bncd16676a2016-07-20 16:23:011138TEST_F(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551139 MockRead data_reads[] = {
1140 MockRead("HTTP/1.1 200 OK\r\n"),
1141 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1142 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
1143 MockRead("Content-Length: 5\r\n\r\n"),
1144 MockRead("Hello"),
1145 };
Ryan Sleevib8d7ea02018-05-07 20:01:011146 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011147 EXPECT_THAT(out.rv,
1148 IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION));
[email protected]1628fe92011-10-04 23:04:551149}
1150
[email protected]54a9c6e52012-03-21 20:10:591151// Checks that two identical Location headers result in no error.
1152// Also tests Location header behavior.
bncd16676a2016-07-20 16:23:011153TEST_F(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551154 MockRead data_reads[] = {
1155 MockRead("HTTP/1.1 302 Redirect\r\n"),
1156 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:591157 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:551158 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061159 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551160 };
1161
1162 HttpRequestInfo request;
1163 request.method = "GET";
1164 request.url = GURL("http://redirect.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101165 request.traffic_annotation =
1166 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1628fe92011-10-04 23:04:551167
danakj1fd259a02016-04-16 03:17:091168 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161169 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1628fe92011-10-04 23:04:551170
Ryan Sleevib8d7ea02018-05-07 20:01:011171 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071172 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:551173
[email protected]49639fa2011-12-20 23:22:411174 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:551175
tfarina42834112016-09-22 13:38:201176 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011177 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1628fe92011-10-04 23:04:551178
robpercival214763f2016-07-01 23:27:011179 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]1628fe92011-10-04 23:04:551180
bnc691fda62016-08-12 00:43:161181 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521182 ASSERT_TRUE(response);
1183 ASSERT_TRUE(response->headers);
[email protected]1628fe92011-10-04 23:04:551184 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
1185 std::string url;
1186 EXPECT_TRUE(response->headers->IsRedirect(&url));
1187 EXPECT_EQ("http://good.com/", url);
tbansal2ecbbc72016-10-06 17:15:471188 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]1628fe92011-10-04 23:04:551189}
1190
[email protected]1628fe92011-10-04 23:04:551191// Checks that two distinct Location headers result in an error.
bncd16676a2016-07-20 16:23:011192TEST_F(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551193 MockRead data_reads[] = {
1194 MockRead("HTTP/1.1 302 Redirect\r\n"),
1195 MockRead("Location: http://good.com/\r\n"),
1196 MockRead("Location: http://evil.com/\r\n"),
1197 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061198 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551199 };
Ryan Sleevib8d7ea02018-05-07 20:01:011200 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011201 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION));
[email protected]1628fe92011-10-04 23:04:551202}
1203
[email protected]ef0faf2e72009-03-05 23:27:231204// Do a request using the HEAD method. Verify that we don't try to read the
1205// message body (since HEAD has none).
bncd16676a2016-07-20 16:23:011206TEST_F(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:421207 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:231208 request.method = "HEAD";
bncce36dca22015-04-21 22:11:231209 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:101210 request.traffic_annotation =
1211 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ef0faf2e72009-03-05 23:27:231212
danakj1fd259a02016-04-16 03:17:091213 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161214 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:091215 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:161216 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:091217 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
1218 base::Unretained(&headers_handler)));
[email protected]cb9bf6ca2011-01-28 13:15:271219
[email protected]ef0faf2e72009-03-05 23:27:231220 MockWrite data_writes1[] = {
csharrisonf473dd192015-08-18 13:54:131221 MockWrite("HEAD / HTTP/1.1\r\n"
1222 "Host: www.example.org\r\n"
1223 "Connection: keep-alive\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231224 };
1225 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:231226 MockRead("HTTP/1.1 404 Not Found\r\n"), MockRead("Server: Blah\r\n"),
1227 MockRead("Content-Length: 1234\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231228
mmenked39192ee2015-12-09 00:57:231229 // No response body because the test stops reading here.
1230 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]ef0faf2e72009-03-05 23:27:231231 };
1232
Ryan Sleevib8d7ea02018-05-07 20:01:011233 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:071234 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:231235
[email protected]49639fa2011-12-20 23:22:411236 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:231237
tfarina42834112016-09-22 13:38:201238 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011239 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ef0faf2e72009-03-05 23:27:231240
1241 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:011242 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231243
bnc691fda62016-08-12 00:43:161244 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521245 ASSERT_TRUE(response);
[email protected]ef0faf2e72009-03-05 23:27:231246
1247 // Check that the headers got parsed.
wezca1070932016-05-26 20:30:521248 EXPECT_TRUE(response->headers);
[email protected]ef0faf2e72009-03-05 23:27:231249 EXPECT_EQ(1234, response->headers->GetContentLength());
1250 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471251 EXPECT_TRUE(response->proxy_server.is_direct());
ryansturm49a8cb12016-06-15 16:51:091252 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
1253 EXPECT_FALSE(headers_handler.observed_before_headers_sent_with_proxy());
[email protected]ef0faf2e72009-03-05 23:27:231254
1255 std::string server_header;
olli.raulaee489a52016-01-25 08:37:101256 size_t iter = 0;
[email protected]ef0faf2e72009-03-05 23:27:231257 bool has_server_header = response->headers->EnumerateHeader(
1258 &iter, "Server", &server_header);
1259 EXPECT_TRUE(has_server_header);
1260 EXPECT_EQ("Blah", server_header);
1261
1262 // Reading should give EOF right away, since there is no message body
1263 // (despite non-zero content-length).
1264 std::string response_data;
bnc691fda62016-08-12 00:43:161265 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011266 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231267 EXPECT_EQ("", response_data);
1268}
1269
bncd16676a2016-07-20 16:23:011270TEST_F(HttpNetworkTransactionTest, ReuseConnection) {
danakj1fd259a02016-04-16 03:17:091271 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:521272
1273 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351274 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1275 MockRead("hello"),
1276 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1277 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061278 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521279 };
Ryan Sleevib8d7ea02018-05-07 20:01:011280 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071281 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521282
[email protected]0b0bf032010-09-21 18:08:501283 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521284 "hello", "world"
1285 };
1286
1287 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:421288 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521289 request.method = "GET";
bncce36dca22015-04-21 22:11:231290 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:101291 request.traffic_annotation =
1292 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:521293
bnc691fda62016-08-12 00:43:161294 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271295
[email protected]49639fa2011-12-20 23:22:411296 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521297
tfarina42834112016-09-22 13:38:201298 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011299 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521300
1301 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011302 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521303
bnc691fda62016-08-12 00:43:161304 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521305 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521306
wezca1070932016-05-26 20:30:521307 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251308 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471309 EXPECT_TRUE(response->proxy_server.is_direct());
initial.commit586acc5fe2008-07-26 22:42:521310
1311 std::string response_data;
bnc691fda62016-08-12 00:43:161312 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011313 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251314 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521315 }
1316}
1317
bncd16676a2016-07-20 16:23:011318TEST_F(HttpNetworkTransactionTest, Ignores100) {
danakj1fd259a02016-04-16 03:17:091319 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:221320 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:191321 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:221322 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:271323
[email protected]1c773ea12009-04-28 19:58:421324 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521325 request.method = "POST";
1326 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271327 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:101328 request.traffic_annotation =
1329 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:521330
shivanishab9a143952016-09-19 17:23:411331 // Check the upload progress returned before initialization is correct.
1332 UploadProgress progress = request.upload_data_stream->GetUploadProgress();
1333 EXPECT_EQ(0u, progress.size());
1334 EXPECT_EQ(0u, progress.position());
1335
danakj1fd259a02016-04-16 03:17:091336 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161337 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271338
initial.commit586acc5fe2008-07-26 22:42:521339 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351340 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1341 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1342 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061343 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521344 };
Ryan Sleevib8d7ea02018-05-07 20:01:011345 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071346 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521347
[email protected]49639fa2011-12-20 23:22:411348 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521349
tfarina42834112016-09-22 13:38:201350 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011351 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521352
1353 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011354 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521355
bnc691fda62016-08-12 00:43:161356 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521357 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521358
wezca1070932016-05-26 20:30:521359 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251360 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521361
1362 std::string response_data;
bnc691fda62016-08-12 00:43:161363 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011364 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251365 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521366}
1367
[email protected]3a2d3662009-03-27 03:49:141368// This test is almost the same as Ignores100 above, but the response contains
1369// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571370// HTTP/1.1 and the two status headers are read in one read.
bncd16676a2016-07-20 16:23:011371TEST_F(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421372 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141373 request.method = "GET";
1374 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101375 request.traffic_annotation =
1376 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3a2d3662009-03-27 03:49:141377
danakj1fd259a02016-04-16 03:17:091378 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161379 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271380
[email protected]3a2d3662009-03-27 03:49:141381 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571382 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1383 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141384 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061385 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141386 };
Ryan Sleevib8d7ea02018-05-07 20:01:011387 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071388 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141389
[email protected]49639fa2011-12-20 23:22:411390 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141391
tfarina42834112016-09-22 13:38:201392 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011393 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3a2d3662009-03-27 03:49:141394
1395 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011396 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141397
bnc691fda62016-08-12 00:43:161398 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521399 ASSERT_TRUE(response);
[email protected]3a2d3662009-03-27 03:49:141400
wezca1070932016-05-26 20:30:521401 EXPECT_TRUE(response->headers);
[email protected]3a2d3662009-03-27 03:49:141402 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1403
1404 std::string response_data;
bnc691fda62016-08-12 00:43:161405 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011406 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141407 EXPECT_EQ("hello world", response_data);
1408}
1409
Andrew Comminos517a92c2019-01-14 17:49:561410TEST_F(HttpNetworkTransactionTest, LoadTimingMeasuresTimeToFirstByteForHttp) {
1411 static const base::TimeDelta kDelayAfterFirstByte =
Andrew Comminos1f2ff1cc2018-12-14 05:22:381412 base::TimeDelta::FromMilliseconds(10);
1413
1414 HttpRequestInfo request;
1415 request.method = "GET";
1416 request.url = GURL("http://www.foo.com/");
1417 request.traffic_annotation =
1418 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1419
1420 std::vector<MockWrite> data_writes = {
1421 MockWrite(ASYNC, 0,
1422 "GET / HTTP/1.1\r\n"
1423 "Host: www.foo.com\r\n"
1424 "Connection: keep-alive\r\n\r\n"),
1425 };
1426
1427 std::vector<MockRead> data_reads = {
1428 // Write one byte of the status line, followed by a pause.
1429 MockRead(ASYNC, 1, "H"),
1430 MockRead(ASYNC, ERR_IO_PENDING, 2),
1431 MockRead(ASYNC, 3, "TTP/1.1 200 OK\r\n\r\n"),
1432 MockRead(ASYNC, 4, "hello world"),
1433 MockRead(SYNCHRONOUS, OK, 5),
1434 };
1435
1436 SequencedSocketData data(data_reads, data_writes);
1437 session_deps_.socket_factory->AddSocketDataProvider(&data);
1438
1439 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1440
1441 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1442
1443 TestCompletionCallback callback;
1444
1445 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1446 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1447
1448 data.RunUntilPaused();
1449 ASSERT_TRUE(data.IsPaused());
Andrew Comminos517a92c2019-01-14 17:49:561450 FastForwardBy(kDelayAfterFirstByte);
Andrew Comminos1f2ff1cc2018-12-14 05:22:381451 data.Resume();
1452
1453 rv = callback.WaitForResult();
1454 EXPECT_THAT(rv, IsOk());
1455
1456 const HttpResponseInfo* response = trans.GetResponseInfo();
1457 ASSERT_TRUE(response);
1458
1459 EXPECT_TRUE(response->headers);
1460 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1461
1462 LoadTimingInfo load_timing_info;
1463 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
1464 EXPECT_FALSE(load_timing_info.receive_headers_start.is_null());
1465 EXPECT_FALSE(load_timing_info.connect_timing.connect_end.is_null());
Andrew Comminos517a92c2019-01-14 17:49:561466 // Ensure we didn't include the delay in the TTFB time.
1467 EXPECT_EQ(load_timing_info.receive_headers_start,
1468 load_timing_info.connect_timing.connect_end);
1469 // Ensure that the mock clock advanced at all.
1470 EXPECT_EQ(base::TimeTicks::Now() - load_timing_info.receive_headers_start,
1471 kDelayAfterFirstByte);
Andrew Comminos1f2ff1cc2018-12-14 05:22:381472
1473 std::string response_data;
1474 rv = ReadTransaction(&trans, &response_data);
1475 EXPECT_THAT(rv, IsOk());
1476 EXPECT_EQ("hello world", response_data);
1477}
1478
1479// Tests that the time-to-first-byte reported in a transaction's load timing
1480// info uses the first response, even if 1XX/informational.
1481void HttpNetworkTransactionTest::Check100ResponseTiming(bool use_spdy) {
Andrew Comminos517a92c2019-01-14 17:49:561482 static const base::TimeDelta kDelayAfter100Response =
Andrew Comminos1f2ff1cc2018-12-14 05:22:381483 base::TimeDelta::FromMilliseconds(10);
1484
1485 HttpRequestInfo request;
1486 request.method = "GET";
1487 request.url = GURL("https://www.foo.com/");
1488 request.traffic_annotation =
1489 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1490
1491 SSLSocketDataProvider ssl(ASYNC, OK);
1492 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
1493
1494 std::vector<MockWrite> data_writes;
1495 std::vector<MockRead> data_reads;
1496
1497 spdy::SpdySerializedFrame spdy_req(
1498 spdy_util_.ConstructSpdyGet(request.url.spec().c_str(), 1, LOWEST));
1499
1500 spdy::SpdyHeaderBlock spdy_resp1_headers;
1501 spdy_resp1_headers[spdy::kHttp2StatusHeader] = "100";
1502 spdy::SpdySerializedFrame spdy_resp1(
1503 spdy_util_.ConstructSpdyReply(1, spdy_resp1_headers.Clone()));
1504 spdy::SpdySerializedFrame spdy_resp2(
1505 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
1506 spdy::SpdySerializedFrame spdy_data(
1507 spdy_util_.ConstructSpdyDataFrame(1, "hello world", true));
1508
1509 if (use_spdy) {
1510 ssl.next_proto = kProtoHTTP2;
1511
1512 data_writes = {CreateMockWrite(spdy_req, 0)};
1513
1514 data_reads = {
1515 CreateMockRead(spdy_resp1, 1), MockRead(ASYNC, ERR_IO_PENDING, 2),
1516 CreateMockRead(spdy_resp2, 3), CreateMockRead(spdy_data, 4),
1517 MockRead(SYNCHRONOUS, OK, 5),
1518 };
1519 } else {
1520 data_writes = {
1521 MockWrite(ASYNC, 0,
1522 "GET / HTTP/1.1\r\n"
1523 "Host: www.foo.com\r\n"
1524 "Connection: keep-alive\r\n\r\n"),
1525 };
1526
1527 data_reads = {
1528 MockRead(ASYNC, 1, "HTTP/1.1 100 Continue\r\n\r\n"),
1529 MockRead(ASYNC, ERR_IO_PENDING, 2),
1530
1531 MockRead(ASYNC, 3, "HTTP/1.1 200 OK\r\n\r\n"),
1532 MockRead(ASYNC, 4, "hello world"),
1533 MockRead(SYNCHRONOUS, OK, 5),
1534 };
1535 }
1536
1537 SequencedSocketData data(data_reads, data_writes);
1538 session_deps_.socket_factory->AddSocketDataProvider(&data);
1539
1540 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1541
1542 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1543
1544 TestCompletionCallback callback;
1545
1546 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1547 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1548
1549 data.RunUntilPaused();
1550 // We should now have parsed the 100 response and hit ERR_IO_PENDING. Insert
1551 // the delay before parsing the 200 response.
1552 ASSERT_TRUE(data.IsPaused());
Andrew Comminos517a92c2019-01-14 17:49:561553 FastForwardBy(kDelayAfter100Response);
Andrew Comminos1f2ff1cc2018-12-14 05:22:381554 data.Resume();
1555
1556 rv = callback.WaitForResult();
1557 EXPECT_THAT(rv, IsOk());
1558
1559 const HttpResponseInfo* response = trans.GetResponseInfo();
1560 ASSERT_TRUE(response);
1561
1562 LoadTimingInfo load_timing_info;
1563 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
1564 EXPECT_FALSE(load_timing_info.receive_headers_start.is_null());
1565 EXPECT_FALSE(load_timing_info.connect_timing.connect_end.is_null());
Andrew Comminos517a92c2019-01-14 17:49:561566 // Ensure we didn't include the delay in the TTFB time.
1567 EXPECT_EQ(load_timing_info.receive_headers_start,
1568 load_timing_info.connect_timing.connect_end);
1569 // Ensure that the mock clock advanced at all.
1570 EXPECT_EQ(base::TimeTicks::Now() - load_timing_info.receive_headers_start,
1571 kDelayAfter100Response);
Andrew Comminos1f2ff1cc2018-12-14 05:22:381572
1573 std::string response_data;
1574 rv = ReadTransaction(&trans, &response_data);
1575 EXPECT_THAT(rv, IsOk());
1576 EXPECT_EQ("hello world", response_data);
1577}
1578
Andrew Comminos517a92c2019-01-14 17:49:561579TEST_F(HttpNetworkTransactionTest, MeasuresTimeToFirst100ResponseForHttp) {
Andrew Comminos1f2ff1cc2018-12-14 05:22:381580 Check100ResponseTiming(false /* use_spdy */);
1581}
1582
Andrew Comminos517a92c2019-01-14 17:49:561583TEST_F(HttpNetworkTransactionTest, MeasuresTimeToFirst100ResponseForSpdy) {
Andrew Comminos1f2ff1cc2018-12-14 05:22:381584 Check100ResponseTiming(true /* use_spdy */);
1585}
1586
bncd16676a2016-07-20 16:23:011587TEST_F(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
zmo9528c9f42015-08-04 22:12:081588 HttpRequestInfo request;
1589 request.method = "POST";
1590 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101591 request.traffic_annotation =
1592 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
zmo9528c9f42015-08-04 22:12:081593
danakj1fd259a02016-04-16 03:17:091594 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161595 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zmo9528c9f42015-08-04 22:12:081596
1597 MockRead data_reads[] = {
1598 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1599 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381600 };
Ryan Sleevib8d7ea02018-05-07 20:01:011601 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
zmo9528c9f42015-08-04 22:12:081602 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381603
zmo9528c9f42015-08-04 22:12:081604 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381605
tfarina42834112016-09-22 13:38:201606 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011607 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381608
zmo9528c9f42015-08-04 22:12:081609 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011610 EXPECT_THAT(rv, IsOk());
[email protected]ee9410e72010-01-07 01:42:381611
zmo9528c9f42015-08-04 22:12:081612 std::string response_data;
bnc691fda62016-08-12 00:43:161613 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011614 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:081615 EXPECT_EQ("", response_data);
[email protected]ee9410e72010-01-07 01:42:381616}
1617
bncd16676a2016-07-20 16:23:011618TEST_F(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381619 HttpRequestInfo request;
1620 request.method = "POST";
1621 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101622 request.traffic_annotation =
1623 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ee9410e72010-01-07 01:42:381624
danakj1fd259a02016-04-16 03:17:091625 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161626 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271627
[email protected]ee9410e72010-01-07 01:42:381628 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061629 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381630 };
Ryan Sleevib8d7ea02018-05-07 20:01:011631 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071632 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381633
[email protected]49639fa2011-12-20 23:22:411634 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381635
tfarina42834112016-09-22 13:38:201636 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011637 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381638
1639 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011640 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]ee9410e72010-01-07 01:42:381641}
1642
[email protected]23e482282013-06-14 16:08:021643void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511644 const MockWrite* write_failure,
1645 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421646 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521647 request.method = "GET";
1648 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101649 request.traffic_annotation =
1650 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:521651
vishal.b62985ca92015-04-17 08:45:511652 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071653 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091654 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271655
[email protected]202965992011-12-07 23:04:511656 // Written data for successfully sending both requests.
1657 MockWrite data1_writes[] = {
1658 MockWrite("GET / HTTP/1.1\r\n"
1659 "Host: www.foo.com\r\n"
1660 "Connection: keep-alive\r\n\r\n"),
1661 MockWrite("GET / HTTP/1.1\r\n"
1662 "Host: www.foo.com\r\n"
1663 "Connection: keep-alive\r\n\r\n")
1664 };
1665
1666 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521667 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351668 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1669 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061670 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521671 };
[email protected]202965992011-12-07 23:04:511672
1673 if (write_failure) {
[email protected]a34f61ee2014-03-18 20:59:491674 ASSERT_FALSE(read_failure);
[email protected]202965992011-12-07 23:04:511675 data1_writes[1] = *write_failure;
1676 } else {
1677 ASSERT_TRUE(read_failure);
1678 data1_reads[2] = *read_failure;
1679 }
1680
Ryan Sleevib8d7ea02018-05-07 20:01:011681 StaticSocketDataProvider data1(data1_reads, data1_writes);
[email protected]bb88e1d32013-05-03 23:11:071682 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521683
1684 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351685 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1686 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061687 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521688 };
Ryan Sleevib8d7ea02018-05-07 20:01:011689 StaticSocketDataProvider data2(data2_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071690 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521691
thestig9d3bb0c2015-01-24 00:49:511692 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521693 "hello", "world"
1694 };
1695
mikecironef22f9812016-10-04 03:40:191696 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521697 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411698 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521699
bnc691fda62016-08-12 00:43:161700 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
initial.commit586acc5fe2008-07-26 22:42:521701
tfarina42834112016-09-22 13:38:201702 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011703 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521704
1705 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011706 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521707
[email protected]58e32bb2013-01-21 18:23:251708 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161709 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:251710 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1711 if (i == 0) {
1712 first_socket_log_id = load_timing_info.socket_log_id;
1713 } else {
1714 // The second request should be using a new socket.
1715 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1716 }
1717
bnc691fda62016-08-12 00:43:161718 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521719 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521720
wezca1070932016-05-26 20:30:521721 EXPECT_TRUE(response->headers);
tbansal2ecbbc72016-10-06 17:15:471722 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]3d2a59b2008-09-26 19:44:251723 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521724
1725 std::string response_data;
bnc691fda62016-08-12 00:43:161726 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011727 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251728 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521729 }
1730}
[email protected]3d2a59b2008-09-26 19:44:251731
[email protected]a34f61ee2014-03-18 20:59:491732void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1733 const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:101734 const MockRead* read_failure,
1735 bool use_spdy) {
[email protected]a34f61ee2014-03-18 20:59:491736 HttpRequestInfo request;
1737 request.method = "GET";
[email protected]09356c652014-03-25 15:36:101738 request.url = GURL("https://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101739 request.traffic_annotation =
1740 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]a34f61ee2014-03-18 20:59:491741
vishal.b62985ca92015-04-17 08:45:511742 TestNetLog net_log;
[email protected]a34f61ee2014-03-18 20:59:491743 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091744 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a34f61ee2014-03-18 20:59:491745
[email protected]09356c652014-03-25 15:36:101746 SSLSocketDataProvider ssl1(ASYNC, OK);
1747 SSLSocketDataProvider ssl2(ASYNC, OK);
1748 if (use_spdy) {
bnc3cf2a592016-08-11 14:48:361749 ssl1.next_proto = kProtoHTTP2;
1750 ssl2.next_proto = kProtoHTTP2;
[email protected]09356c652014-03-25 15:36:101751 }
1752 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1753 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]a34f61ee2014-03-18 20:59:491754
[email protected]09356c652014-03-25 15:36:101755 // SPDY versions of the request and response.
Ryan Hamilton0239aac2018-05-19 00:03:131756 spdy::SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
bnc38dcd392016-02-09 23:19:491757 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
Ryan Hamilton0239aac2018-05-19 00:03:131758 spdy::SpdySerializedFrame spdy_response(
bnc42331402016-07-25 13:36:151759 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:131760 spdy::SpdySerializedFrame spdy_data(
Bence Békyd74f4382018-02-20 18:26:191761 spdy_util_.ConstructSpdyDataFrame(1, "hello", true));
[email protected]a34f61ee2014-03-18 20:59:491762
[email protected]09356c652014-03-25 15:36:101763 // HTTP/1.1 versions of the request and response.
1764 const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1765 "Host: www.foo.com\r\n"
1766 "Connection: keep-alive\r\n\r\n";
1767 const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1768 const char kHttpData[] = "hello";
1769
1770 std::vector<MockRead> data1_reads;
1771 std::vector<MockWrite> data1_writes;
[email protected]a34f61ee2014-03-18 20:59:491772 if (write_failure) {
1773 ASSERT_FALSE(read_failure);
[email protected]09356c652014-03-25 15:36:101774 data1_writes.push_back(*write_failure);
1775 data1_reads.push_back(MockRead(ASYNC, OK));
[email protected]a34f61ee2014-03-18 20:59:491776 } else {
1777 ASSERT_TRUE(read_failure);
[email protected]09356c652014-03-25 15:36:101778 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411779 data1_writes.push_back(CreateMockWrite(spdy_request));
[email protected]09356c652014-03-25 15:36:101780 } else {
1781 data1_writes.push_back(MockWrite(kHttpRequest));
1782 }
1783 data1_reads.push_back(*read_failure);
[email protected]a34f61ee2014-03-18 20:59:491784 }
1785
Ryan Sleevib8d7ea02018-05-07 20:01:011786 StaticSocketDataProvider data1(data1_reads, data1_writes);
[email protected]a34f61ee2014-03-18 20:59:491787 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1788
[email protected]09356c652014-03-25 15:36:101789 std::vector<MockRead> data2_reads;
1790 std::vector<MockWrite> data2_writes;
1791
1792 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411793 data2_writes.push_back(CreateMockWrite(spdy_request, 0, ASYNC));
[email protected]09356c652014-03-25 15:36:101794
bncdf80d44fd2016-07-15 20:27:411795 data2_reads.push_back(CreateMockRead(spdy_response, 1, ASYNC));
1796 data2_reads.push_back(CreateMockRead(spdy_data, 2, ASYNC));
[email protected]09356c652014-03-25 15:36:101797 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1798 } else {
1799 data2_writes.push_back(
1800 MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1801
1802 data2_reads.push_back(
1803 MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1804 data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1805 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1806 }
Ryan Sleevib8d7ea02018-05-07 20:01:011807 SequencedSocketData data2(data2_reads, data2_writes);
[email protected]a34f61ee2014-03-18 20:59:491808 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1809
1810 // Preconnect a socket.
nharper8cdb0fb2016-04-22 21:34:591811 session->http_stream_factory()->PreconnectStreams(1, request);
[email protected]a34f61ee2014-03-18 20:59:491812 // Wait for the preconnect to complete.
1813 // TODO(davidben): Some way to wait for an idle socket count might be handy.
1814 base::RunLoop().RunUntilIdle();
Matt Menke9d5e2c92019-02-05 01:42:231815 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]a34f61ee2014-03-18 20:59:491816
1817 // Make the request.
1818 TestCompletionCallback callback;
1819
bnc691fda62016-08-12 00:43:161820 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a34f61ee2014-03-18 20:59:491821
tfarina42834112016-09-22 13:38:201822 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011823 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a34f61ee2014-03-18 20:59:491824
1825 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011826 EXPECT_THAT(rv, IsOk());
[email protected]a34f61ee2014-03-18 20:59:491827
1828 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161829 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]09356c652014-03-25 15:36:101830 TestLoadTimingNotReused(
1831 load_timing_info,
1832 CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]a34f61ee2014-03-18 20:59:491833
bnc691fda62016-08-12 00:43:161834 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521835 ASSERT_TRUE(response);
[email protected]a34f61ee2014-03-18 20:59:491836
wezca1070932016-05-26 20:30:521837 EXPECT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:021838 if (response->was_fetched_via_spdy) {
1839 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
1840 } else {
1841 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1842 }
[email protected]a34f61ee2014-03-18 20:59:491843
1844 std::string response_data;
bnc691fda62016-08-12 00:43:161845 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011846 EXPECT_THAT(rv, IsOk());
[email protected]09356c652014-03-25 15:36:101847 EXPECT_EQ(kHttpData, response_data);
[email protected]a34f61ee2014-03-18 20:59:491848}
1849
Biljith Jayan45a41722017-08-16 18:43:141850// Test that we do not retry indefinitely when a server sends an error like
1851// ERR_SPDY_PING_FAILED, ERR_SPDY_SERVER_REFUSED_STREAM,
1852// ERR_QUIC_HANDSHAKE_FAILED or ERR_QUIC_PROTOCOL_ERROR.
1853TEST_F(HttpNetworkTransactionTest, FiniteRetriesOnIOError) {
1854 HttpRequestInfo request;
1855 request.method = "GET";
1856 request.url = GURL("https://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101857 request.traffic_annotation =
1858 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Biljith Jayan45a41722017-08-16 18:43:141859
1860 // Check whether we give up after the third try.
1861
1862 // Construct an HTTP2 request and a "Go away" response.
Ryan Hamilton0239aac2018-05-19 00:03:131863 spdy::SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
Biljith Jayan45a41722017-08-16 18:43:141864 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
Ryan Hamilton0239aac2018-05-19 00:03:131865 spdy::SpdySerializedFrame spdy_response_go_away(
1866 spdy_util_.ConstructSpdyGoAway(0));
Ryan Sleevib8d7ea02018-05-07 20:01:011867 MockRead data_read1[] = {CreateMockRead(spdy_response_go_away)};
1868 MockWrite data_write[] = {CreateMockWrite(spdy_request, 0)};
Biljith Jayan45a41722017-08-16 18:43:141869
1870 // Three go away responses.
Ryan Sleevib8d7ea02018-05-07 20:01:011871 StaticSocketDataProvider data1(data_read1, data_write);
1872 StaticSocketDataProvider data2(data_read1, data_write);
1873 StaticSocketDataProvider data3(data_read1, data_write);
Biljith Jayan45a41722017-08-16 18:43:141874
1875 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1876 AddSSLSocketData();
1877 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1878 AddSSLSocketData();
1879 session_deps_.socket_factory->AddSocketDataProvider(&data3);
1880 AddSSLSocketData();
1881
1882 TestCompletionCallback callback;
1883 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1884 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1885
1886 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1887 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1888
1889 rv = callback.WaitForResult();
1890 EXPECT_THAT(rv, IsError(ERR_SPDY_SERVER_REFUSED_STREAM));
1891}
1892
1893TEST_F(HttpNetworkTransactionTest, RetryTwiceOnIOError) {
1894 HttpRequestInfo request;
1895 request.method = "GET";
1896 request.url = GURL("https://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101897 request.traffic_annotation =
1898 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Biljith Jayan45a41722017-08-16 18:43:141899
1900 // Check whether we try atleast thrice before giving up.
1901
1902 // Construct an HTTP2 request and a "Go away" response.
Ryan Hamilton0239aac2018-05-19 00:03:131903 spdy::SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
Biljith Jayan45a41722017-08-16 18:43:141904 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
Ryan Hamilton0239aac2018-05-19 00:03:131905 spdy::SpdySerializedFrame spdy_response_go_away(
1906 spdy_util_.ConstructSpdyGoAway(0));
Ryan Sleevib8d7ea02018-05-07 20:01:011907 MockRead data_read1[] = {CreateMockRead(spdy_response_go_away)};
1908 MockWrite data_write[] = {CreateMockWrite(spdy_request, 0)};
Biljith Jayan45a41722017-08-16 18:43:141909
1910 // Construct a non error HTTP2 response.
Ryan Hamilton0239aac2018-05-19 00:03:131911 spdy::SpdySerializedFrame spdy_response_no_error(
Biljith Jayan45a41722017-08-16 18:43:141912 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:131913 spdy::SpdySerializedFrame spdy_data(
1914 spdy_util_.ConstructSpdyDataFrame(1, true));
Biljith Jayan45a41722017-08-16 18:43:141915 MockRead data_read2[] = {CreateMockRead(spdy_response_no_error, 1),
1916 CreateMockRead(spdy_data, 2)};
1917
1918 // Two error responses.
Ryan Sleevib8d7ea02018-05-07 20:01:011919 StaticSocketDataProvider data1(data_read1, data_write);
1920 StaticSocketDataProvider data2(data_read1, data_write);
Biljith Jayan45a41722017-08-16 18:43:141921 // Followed by a success response.
Ryan Sleevib8d7ea02018-05-07 20:01:011922 SequencedSocketData data3(data_read2, data_write);
Biljith Jayan45a41722017-08-16 18:43:141923
1924 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1925 AddSSLSocketData();
1926 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1927 AddSSLSocketData();
1928 session_deps_.socket_factory->AddSocketDataProvider(&data3);
1929 AddSSLSocketData();
1930
1931 TestCompletionCallback callback;
1932 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1933 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1934
1935 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1936 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1937
1938 rv = callback.WaitForResult();
1939 EXPECT_THAT(rv, IsOk());
1940}
1941
bncd16676a2016-07-20 16:23:011942TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061943 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]202965992011-12-07 23:04:511944 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1945}
1946
bncd16676a2016-07-20 16:23:011947TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061948 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]202965992011-12-07 23:04:511949 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251950}
1951
bncd16676a2016-07-20 16:23:011952TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061953 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]202965992011-12-07 23:04:511954 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251955}
1956
[email protected]d58ceea82014-06-04 10:55:541957// Make sure that on a 408 response (Request Timeout), the request is retried,
1958// if the socket was a reused keep alive socket.
bncd16676a2016-07-20 16:23:011959TEST_F(HttpNetworkTransactionTest, KeepAlive408) {
[email protected]d58ceea82014-06-04 10:55:541960 MockRead read_failure(SYNCHRONOUS,
1961 "HTTP/1.1 408 Request Timeout\r\n"
1962 "Connection: Keep-Alive\r\n"
1963 "Content-Length: 6\r\n\r\n"
1964 "Pickle");
1965 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1966}
1967
bncd16676a2016-07-20 16:23:011968TEST_F(HttpNetworkTransactionTest, PreconnectErrorNotConnectedOnWrite) {
[email protected]a34f61ee2014-03-18 20:59:491969 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]09356c652014-03-25 15:36:101970 PreconnectErrorResendRequestTest(&write_failure, NULL, false);
[email protected]a34f61ee2014-03-18 20:59:491971}
1972
bncd16676a2016-07-20 16:23:011973TEST_F(HttpNetworkTransactionTest, PreconnectErrorReset) {
[email protected]a34f61ee2014-03-18 20:59:491974 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]09356c652014-03-25 15:36:101975 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
[email protected]a34f61ee2014-03-18 20:59:491976}
1977
bncd16676a2016-07-20 16:23:011978TEST_F(HttpNetworkTransactionTest, PreconnectErrorEOF) {
[email protected]a34f61ee2014-03-18 20:59:491979 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]09356c652014-03-25 15:36:101980 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1981}
1982
bncd16676a2016-07-20 16:23:011983TEST_F(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:101984 MockRead read_failure(ASYNC, OK); // EOF
1985 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1986}
1987
[email protected]d58ceea82014-06-04 10:55:541988// Make sure that on a 408 response (Request Timeout), the request is retried,
1989// if the socket was a preconnected (UNUSED_IDLE) socket.
bncd16676a2016-07-20 16:23:011990TEST_F(HttpNetworkTransactionTest, RetryOnIdle408) {
[email protected]d58ceea82014-06-04 10:55:541991 MockRead read_failure(SYNCHRONOUS,
1992 "HTTP/1.1 408 Request Timeout\r\n"
1993 "Connection: Keep-Alive\r\n"
1994 "Content-Length: 6\r\n\r\n"
1995 "Pickle");
1996 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1997 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1998}
1999
bncd16676a2016-07-20 16:23:012000TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorNotConnectedOnWrite) {
[email protected]09356c652014-03-25 15:36:102001 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
2002 PreconnectErrorResendRequestTest(&write_failure, NULL, true);
2003}
2004
bncd16676a2016-07-20 16:23:012005TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
[email protected]09356c652014-03-25 15:36:102006 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
2007 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
2008}
2009
bncd16676a2016-07-20 16:23:012010TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
[email protected]09356c652014-03-25 15:36:102011 MockRead read_failure(SYNCHRONOUS, OK); // EOF
2012 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
2013}
2014
bncd16676a2016-07-20 16:23:012015TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:102016 MockRead read_failure(ASYNC, OK); // EOF
2017 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
[email protected]a34f61ee2014-03-18 20:59:492018}
2019
bncd16676a2016-07-20 16:23:012020TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:422021 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:252022 request.method = "GET";
bncce36dca22015-04-21 22:11:232023 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102024 request.traffic_annotation =
2025 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3d2a59b2008-09-26 19:44:252026
danakj1fd259a02016-04-16 03:17:092027 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162028 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272029
[email protected]3d2a59b2008-09-26 19:44:252030 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:062031 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:352032 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
2033 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:062034 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:252035 };
Ryan Sleevib8d7ea02018-05-07 20:01:012036 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:072037 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:252038
[email protected]49639fa2011-12-20 23:22:412039 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:252040
tfarina42834112016-09-22 13:38:202041 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012042 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3d2a59b2008-09-26 19:44:252043
2044 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:012045 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:592046
2047 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:162048 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592049 EXPECT_LT(0u, endpoint.address().size());
[email protected]3d2a59b2008-09-26 19:44:252050}
2051
2052// What do various browsers do when the server closes a non-keepalive
2053// connection without sending any response header or body?
2054//
2055// IE7: error page
2056// Safari 3.1.2 (Windows): error page
2057// Firefox 3.0.1: blank page
2058// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:422059// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
2060// Us: error page (EMPTY_RESPONSE)
bncd16676a2016-07-20 16:23:012061TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:252062 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:062063 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:352064 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
2065 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:062066 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:252067 };
Ryan Sleevib8d7ea02018-05-07 20:01:012068 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:012069 EXPECT_THAT(out.rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]3d2a59b2008-09-26 19:44:252070}
[email protected]1826a402014-01-08 15:40:482071
[email protected]7a5378b2012-11-04 03:25:172072// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
2073// tests. There was a bug causing HttpNetworkTransaction to hang in the
2074// destructor in such situations.
2075// See http://crbug.com/154712 and http://crbug.com/156609.
bncd16676a2016-07-20 16:23:012076TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:172077 HttpRequestInfo request;
2078 request.method = "GET";
bncce36dca22015-04-21 22:11:232079 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102080 request.traffic_annotation =
2081 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7a5378b2012-11-04 03:25:172082
danakj1fd259a02016-04-16 03:17:092083 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:582084 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:192085 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:172086
2087 MockRead data_reads[] = {
2088 MockRead("HTTP/1.0 200 OK\r\n"),
2089 MockRead("Connection: keep-alive\r\n"),
2090 MockRead("Content-Length: 100\r\n\r\n"),
2091 MockRead("hello"),
2092 MockRead(SYNCHRONOUS, 0),
2093 };
Ryan Sleevib8d7ea02018-05-07 20:01:012094 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:072095 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:172096
2097 TestCompletionCallback callback;
2098
tfarina42834112016-09-22 13:38:202099 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012100 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:172101
2102 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:012103 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:172104
Victor Costan9c7302b2018-08-27 16:39:442105 scoped_refptr<IOBufferWithSize> io_buf =
2106 base::MakeRefCounted<IOBufferWithSize>(100);
[email protected]90499482013-06-01 00:39:502107 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:172108 if (rv == ERR_IO_PENDING)
2109 rv = callback.WaitForResult();
2110 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:502111 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
robpercival214763f2016-07-01 23:27:012112 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:172113
2114 trans.reset();
fdoray92e35a72016-06-10 15:54:552115 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:172116 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2117}
2118
bncd16676a2016-07-20 16:23:012119TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:172120 HttpRequestInfo request;
2121 request.method = "GET";
bncce36dca22015-04-21 22:11:232122 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102123 request.traffic_annotation =
2124 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7a5378b2012-11-04 03:25:172125
danakj1fd259a02016-04-16 03:17:092126 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:582127 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:192128 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:172129
2130 MockRead data_reads[] = {
2131 MockRead("HTTP/1.0 200 OK\r\n"),
2132 MockRead("Connection: keep-alive\r\n"),
2133 MockRead("Content-Length: 100\r\n\r\n"),
2134 MockRead(SYNCHRONOUS, 0),
2135 };
Ryan Sleevib8d7ea02018-05-07 20:01:012136 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:072137 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:172138
2139 TestCompletionCallback callback;
2140
tfarina42834112016-09-22 13:38:202141 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012142 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:172143
2144 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:012145 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:172146
Victor Costan9c7302b2018-08-27 16:39:442147 scoped_refptr<IOBufferWithSize> io_buf(
2148 base::MakeRefCounted<IOBufferWithSize>(100));
[email protected]90499482013-06-01 00:39:502149 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:172150 if (rv == ERR_IO_PENDING)
2151 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:012152 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:172153
2154 trans.reset();
fdoray92e35a72016-06-10 15:54:552155 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:172156 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2157}
2158
[email protected]0b0bf032010-09-21 18:08:502159// Test that we correctly reuse a keep-alive connection after not explicitly
2160// reading the body.
bncd16676a2016-07-20 16:23:012161TEST_F(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:132162 HttpRequestInfo request;
2163 request.method = "GET";
2164 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:102165 request.traffic_annotation =
2166 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]fc31d6a42010-06-24 18:05:132167
vishal.b62985ca92015-04-17 08:45:512168 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:072169 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:092170 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272171
mmenkecc2298e2015-12-07 18:20:182172 const char* request_data =
2173 "GET / HTTP/1.1\r\n"
2174 "Host: www.foo.com\r\n"
2175 "Connection: keep-alive\r\n\r\n";
2176 MockWrite data_writes[] = {
2177 MockWrite(ASYNC, 0, request_data), MockWrite(ASYNC, 2, request_data),
2178 MockWrite(ASYNC, 4, request_data), MockWrite(ASYNC, 6, request_data),
2179 MockWrite(ASYNC, 8, request_data), MockWrite(ASYNC, 10, request_data),
2180 MockWrite(ASYNC, 12, request_data), MockWrite(ASYNC, 14, request_data),
2181 MockWrite(ASYNC, 17, request_data), MockWrite(ASYNC, 20, request_data),
2182 };
2183
[email protected]0b0bf032010-09-21 18:08:502184 // Note that because all these reads happen in the same
2185 // StaticSocketDataProvider, it shows that the same socket is being reused for
2186 // all transactions.
mmenkecc2298e2015-12-07 18:20:182187 MockRead data_reads[] = {
2188 MockRead(ASYNC, 1, "HTTP/1.1 204 No Content\r\n\r\n"),
2189 MockRead(ASYNC, 3, "HTTP/1.1 205 Reset Content\r\n\r\n"),
2190 MockRead(ASYNC, 5, "HTTP/1.1 304 Not Modified\r\n\r\n"),
2191 MockRead(ASYNC, 7,
2192 "HTTP/1.1 302 Found\r\n"
2193 "Content-Length: 0\r\n\r\n"),
2194 MockRead(ASYNC, 9,
2195 "HTTP/1.1 302 Found\r\n"
2196 "Content-Length: 5\r\n\r\n"
2197 "hello"),
2198 MockRead(ASYNC, 11,
2199 "HTTP/1.1 301 Moved Permanently\r\n"
2200 "Content-Length: 0\r\n\r\n"),
2201 MockRead(ASYNC, 13,
2202 "HTTP/1.1 301 Moved Permanently\r\n"
2203 "Content-Length: 5\r\n\r\n"
2204 "hello"),
[email protected]fc31d6a42010-06-24 18:05:132205
mmenkecc2298e2015-12-07 18:20:182206 // In the next two rounds, IsConnectedAndIdle returns false, due to
2207 // the set_busy_before_sync_reads(true) call, while the
2208 // HttpNetworkTransaction is being shut down, but the socket is still
2209 // reuseable. See http://crbug.com/544255.
2210 MockRead(ASYNC, 15,
2211 "HTTP/1.1 200 Hunky-Dory\r\n"
2212 "Content-Length: 5\r\n\r\n"),
2213 MockRead(SYNCHRONOUS, 16, "hello"),
[email protected]fc31d6a42010-06-24 18:05:132214
mmenkecc2298e2015-12-07 18:20:182215 MockRead(ASYNC, 18,
2216 "HTTP/1.1 200 Hunky-Dory\r\n"
2217 "Content-Length: 5\r\n\r\n"
2218 "he"),
2219 MockRead(SYNCHRONOUS, 19, "llo"),
2220
2221 // The body of the final request is actually read.
2222 MockRead(ASYNC, 21, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
2223 MockRead(ASYNC, 22, "hello"),
2224 };
Ryan Sleevib8d7ea02018-05-07 20:01:012225 SequencedSocketData data(data_reads, data_writes);
mmenkecc2298e2015-12-07 18:20:182226 data.set_busy_before_sync_reads(true);
2227 session_deps_.socket_factory->AddSocketDataProvider(&data);
2228
Avi Drissman4365a4782018-12-28 19:26:242229 const int kNumUnreadBodies = base::size(data_writes) - 1;
[email protected]0b0bf032010-09-21 18:08:502230 std::string response_lines[kNumUnreadBodies];
2231
mikecironef22f9812016-10-04 03:40:192232 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
mmenkecc2298e2015-12-07 18:20:182233 for (size_t i = 0; i < kNumUnreadBodies; ++i) {
[email protected]49639fa2011-12-20 23:22:412234 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:132235
Jeremy Roman0579ed62017-08-29 15:56:192236 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
bnc87dcefc2017-05-25 12:47:582237 session.get());
[email protected]fc31d6a42010-06-24 18:05:132238
tfarina42834112016-09-22 13:38:202239 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012240 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]fc31d6a42010-06-24 18:05:132241
[email protected]58e32bb2013-01-21 18:23:252242 LoadTimingInfo load_timing_info;
2243 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2244 if (i == 0) {
2245 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
2246 first_socket_log_id = load_timing_info.socket_log_id;
2247 } else {
2248 TestLoadTimingReused(load_timing_info);
2249 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
2250 }
2251
[email protected]fc31d6a42010-06-24 18:05:132252 const HttpResponseInfo* response = trans->GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182253 ASSERT_TRUE(response);
[email protected]fc31d6a42010-06-24 18:05:132254
mmenkecc2298e2015-12-07 18:20:182255 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502256 response_lines[i] = response->headers->GetStatusLine();
2257
mmenkecc2298e2015-12-07 18:20:182258 // Delete the transaction without reading the response bodies. Then spin
2259 // the message loop, so the response bodies are drained.
2260 trans.reset();
2261 base::RunLoop().RunUntilIdle();
[email protected]fc31d6a42010-06-24 18:05:132262 }
[email protected]0b0bf032010-09-21 18:08:502263
2264 const char* const kStatusLines[] = {
mmenkecc2298e2015-12-07 18:20:182265 "HTTP/1.1 204 No Content",
2266 "HTTP/1.1 205 Reset Content",
2267 "HTTP/1.1 304 Not Modified",
2268 "HTTP/1.1 302 Found",
2269 "HTTP/1.1 302 Found",
2270 "HTTP/1.1 301 Moved Permanently",
2271 "HTTP/1.1 301 Moved Permanently",
2272 "HTTP/1.1 200 Hunky-Dory",
2273 "HTTP/1.1 200 Hunky-Dory",
[email protected]0b0bf032010-09-21 18:08:502274 };
2275
Avi Drissman4365a4782018-12-28 19:26:242276 static_assert(kNumUnreadBodies == base::size(kStatusLines),
mostynb91e0da982015-01-20 19:17:272277 "forgot to update kStatusLines");
[email protected]0b0bf032010-09-21 18:08:502278
2279 for (int i = 0; i < kNumUnreadBodies; ++i)
2280 EXPECT_EQ(kStatusLines[i], response_lines[i]);
2281
[email protected]49639fa2011-12-20 23:22:412282 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:162283 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202284 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012285 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:162286 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182287 ASSERT_TRUE(response);
2288 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502289 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2290 std::string response_data;
bnc691fda62016-08-12 00:43:162291 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:012292 EXPECT_THAT(rv, IsOk());
[email protected]0b0bf032010-09-21 18:08:502293 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:132294}
2295
mmenke5f94fda2016-06-02 20:54:132296// Sockets that receive extra data after a response is complete should not be
2297// reused.
bncd16676a2016-07-20 16:23:012298TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData1) {
mmenke5f94fda2016-06-02 20:54:132299 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2300 MockWrite data_writes1[] = {
2301 MockWrite("HEAD / HTTP/1.1\r\n"
2302 "Host: www.borked.com\r\n"
2303 "Connection: keep-alive\r\n\r\n"),
2304 };
2305
2306 MockRead data_reads1[] = {
2307 MockRead("HTTP/1.1 200 OK\r\n"
2308 "Connection: keep-alive\r\n"
2309 "Content-Length: 22\r\n\r\n"
2310 "This server is borked."),
2311 };
2312
2313 MockWrite data_writes2[] = {
2314 MockWrite("GET /foo HTTP/1.1\r\n"
2315 "Host: www.borked.com\r\n"
2316 "Connection: keep-alive\r\n\r\n"),
2317 };
2318
2319 MockRead data_reads2[] = {
2320 MockRead("HTTP/1.1 200 OK\r\n"
2321 "Content-Length: 3\r\n\r\n"
2322 "foo"),
2323 };
Ryan Sleevib8d7ea02018-05-07 20:01:012324 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke5f94fda2016-06-02 20:54:132325 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:012326 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke5f94fda2016-06-02 20:54:132327 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2328
2329 TestCompletionCallback callback;
2330 HttpRequestInfo request1;
2331 request1.method = "HEAD";
2332 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e2018-02-07 07:41:102333 request1.traffic_annotation =
2334 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132335
bnc87dcefc2017-05-25 12:47:582336 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192337 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202338 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012339 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132340
2341 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2342 ASSERT_TRUE(response1);
2343 ASSERT_TRUE(response1->headers);
2344 EXPECT_EQ(200, response1->headers->response_code());
2345 EXPECT_TRUE(response1->headers->IsKeepAlive());
2346
2347 std::string response_data1;
robpercival214763f2016-07-01 23:27:012348 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132349 EXPECT_EQ("", response_data1);
2350 // Deleting the transaction attempts to release the socket back into the
2351 // socket pool.
2352 trans1.reset();
2353
2354 HttpRequestInfo request2;
2355 request2.method = "GET";
2356 request2.url = GURL("http://www.borked.com/foo");
Ramin Halavatib5e433e2018-02-07 07:41:102357 request2.traffic_annotation =
2358 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132359
bnc87dcefc2017-05-25 12:47:582360 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192361 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202362 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012363 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132364
2365 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2366 ASSERT_TRUE(response2);
2367 ASSERT_TRUE(response2->headers);
2368 EXPECT_EQ(200, response2->headers->response_code());
2369
2370 std::string response_data2;
robpercival214763f2016-07-01 23:27:012371 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132372 EXPECT_EQ("foo", response_data2);
2373}
2374
bncd16676a2016-07-20 16:23:012375TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData2) {
mmenke5f94fda2016-06-02 20:54:132376 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2377 MockWrite data_writes1[] = {
2378 MockWrite("GET / HTTP/1.1\r\n"
2379 "Host: www.borked.com\r\n"
2380 "Connection: keep-alive\r\n\r\n"),
2381 };
2382
2383 MockRead data_reads1[] = {
2384 MockRead("HTTP/1.1 200 OK\r\n"
2385 "Connection: keep-alive\r\n"
2386 "Content-Length: 22\r\n\r\n"
2387 "This server is borked."
2388 "Bonus data!"),
2389 };
2390
2391 MockWrite data_writes2[] = {
2392 MockWrite("GET /foo HTTP/1.1\r\n"
2393 "Host: www.borked.com\r\n"
2394 "Connection: keep-alive\r\n\r\n"),
2395 };
2396
2397 MockRead data_reads2[] = {
2398 MockRead("HTTP/1.1 200 OK\r\n"
2399 "Content-Length: 3\r\n\r\n"
2400 "foo"),
2401 };
Ryan Sleevib8d7ea02018-05-07 20:01:012402 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke5f94fda2016-06-02 20:54:132403 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:012404 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke5f94fda2016-06-02 20:54:132405 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2406
2407 TestCompletionCallback callback;
2408 HttpRequestInfo request1;
2409 request1.method = "GET";
2410 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e2018-02-07 07:41:102411 request1.traffic_annotation =
2412 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132413
bnc87dcefc2017-05-25 12:47:582414 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192415 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202416 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012417 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132418
2419 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2420 ASSERT_TRUE(response1);
2421 ASSERT_TRUE(response1->headers);
2422 EXPECT_EQ(200, response1->headers->response_code());
2423 EXPECT_TRUE(response1->headers->IsKeepAlive());
2424
2425 std::string response_data1;
robpercival214763f2016-07-01 23:27:012426 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132427 EXPECT_EQ("This server is borked.", response_data1);
2428 // Deleting the transaction attempts to release the socket back into the
2429 // socket pool.
2430 trans1.reset();
2431
2432 HttpRequestInfo request2;
2433 request2.method = "GET";
2434 request2.url = GURL("http://www.borked.com/foo");
Ramin Halavatib5e433e2018-02-07 07:41:102435 request2.traffic_annotation =
2436 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132437
bnc87dcefc2017-05-25 12:47:582438 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192439 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202440 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012441 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132442
2443 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2444 ASSERT_TRUE(response2);
2445 ASSERT_TRUE(response2->headers);
2446 EXPECT_EQ(200, response2->headers->response_code());
2447
2448 std::string response_data2;
robpercival214763f2016-07-01 23:27:012449 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132450 EXPECT_EQ("foo", response_data2);
2451}
2452
bncd16676a2016-07-20 16:23:012453TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData3) {
mmenke5f94fda2016-06-02 20:54:132454 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2455 MockWrite data_writes1[] = {
2456 MockWrite("GET / HTTP/1.1\r\n"
2457 "Host: www.borked.com\r\n"
2458 "Connection: keep-alive\r\n\r\n"),
2459 };
2460
2461 MockRead data_reads1[] = {
2462 MockRead("HTTP/1.1 200 OK\r\n"
2463 "Connection: keep-alive\r\n"
2464 "Transfer-Encoding: chunked\r\n\r\n"),
2465 MockRead("16\r\nThis server is borked.\r\n"),
2466 MockRead("0\r\n\r\nBonus data!"),
2467 };
2468
2469 MockWrite data_writes2[] = {
2470 MockWrite("GET /foo HTTP/1.1\r\n"
2471 "Host: www.borked.com\r\n"
2472 "Connection: keep-alive\r\n\r\n"),
2473 };
2474
2475 MockRead data_reads2[] = {
2476 MockRead("HTTP/1.1 200 OK\r\n"
2477 "Content-Length: 3\r\n\r\n"
2478 "foo"),
2479 };
Ryan Sleevib8d7ea02018-05-07 20:01:012480 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke5f94fda2016-06-02 20:54:132481 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:012482 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke5f94fda2016-06-02 20:54:132483 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2484
2485 TestCompletionCallback callback;
2486 HttpRequestInfo request1;
2487 request1.method = "GET";
2488 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e2018-02-07 07:41:102489 request1.traffic_annotation =
2490 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132491
bnc87dcefc2017-05-25 12:47:582492 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192493 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202494 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012495 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132496
2497 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2498 ASSERT_TRUE(response1);
2499 ASSERT_TRUE(response1->headers);
2500 EXPECT_EQ(200, response1->headers->response_code());
2501 EXPECT_TRUE(response1->headers->IsKeepAlive());
2502
2503 std::string response_data1;
robpercival214763f2016-07-01 23:27:012504 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132505 EXPECT_EQ("This server is borked.", response_data1);
2506 // Deleting the transaction attempts to release the socket back into the
2507 // socket pool.
2508 trans1.reset();
2509
2510 HttpRequestInfo request2;
2511 request2.method = "GET";
2512 request2.url = GURL("http://www.borked.com/foo");
Ramin Halavatib5e433e2018-02-07 07:41:102513 request2.traffic_annotation =
2514 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132515
bnc87dcefc2017-05-25 12:47:582516 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192517 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202518 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012519 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132520
2521 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2522 ASSERT_TRUE(response2);
2523 ASSERT_TRUE(response2->headers);
2524 EXPECT_EQ(200, response2->headers->response_code());
2525
2526 std::string response_data2;
robpercival214763f2016-07-01 23:27:012527 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132528 EXPECT_EQ("foo", response_data2);
2529}
2530
2531// This is a little different from the others - it tests the case that the
2532// HttpStreamParser doesn't know if there's extra data on a socket or not when
2533// the HttpNetworkTransaction is torn down, because the response body hasn't
2534// been read from yet, but the request goes through the HttpResponseBodyDrainer.
bncd16676a2016-07-20 16:23:012535TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData4) {
mmenke5f94fda2016-06-02 20:54:132536 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2537 MockWrite data_writes1[] = {
2538 MockWrite("GET / HTTP/1.1\r\n"
2539 "Host: www.borked.com\r\n"
2540 "Connection: keep-alive\r\n\r\n"),
2541 };
2542
2543 MockRead data_reads1[] = {
2544 MockRead("HTTP/1.1 200 OK\r\n"
2545 "Connection: keep-alive\r\n"
2546 "Transfer-Encoding: chunked\r\n\r\n"),
2547 MockRead("16\r\nThis server is borked.\r\n"),
2548 MockRead("0\r\n\r\nBonus data!"),
2549 };
Ryan Sleevib8d7ea02018-05-07 20:01:012550 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke5f94fda2016-06-02 20:54:132551 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2552
2553 TestCompletionCallback callback;
2554 HttpRequestInfo request1;
2555 request1.method = "GET";
2556 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e2018-02-07 07:41:102557 request1.traffic_annotation =
2558 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132559
bnc87dcefc2017-05-25 12:47:582560 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:192561 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
bnc87dcefc2017-05-25 12:47:582562 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012563 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132564
bnc87dcefc2017-05-25 12:47:582565 const HttpResponseInfo* response1 = trans->GetResponseInfo();
mmenke5f94fda2016-06-02 20:54:132566 ASSERT_TRUE(response1);
2567 ASSERT_TRUE(response1->headers);
2568 EXPECT_EQ(200, response1->headers->response_code());
2569 EXPECT_TRUE(response1->headers->IsKeepAlive());
2570
2571 // Deleting the transaction creates an HttpResponseBodyDrainer to read the
2572 // response body.
bnc87dcefc2017-05-25 12:47:582573 trans.reset();
mmenke5f94fda2016-06-02 20:54:132574
2575 // Let the HttpResponseBodyDrainer drain the socket. It should determine the
2576 // socket can't be reused, rather than returning it to the socket pool.
2577 base::RunLoop().RunUntilIdle();
2578
2579 // There should be no idle sockets in the pool.
2580 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2581}
2582
[email protected]038e9a32008-10-08 22:40:162583// Test the request-challenge-retry sequence for basic auth.
2584// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012585TEST_F(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:422586 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:162587 request.method = "GET";
bncce36dca22015-04-21 22:11:232588 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102589 request.traffic_annotation =
2590 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]038e9a32008-10-08 22:40:162591
vishal.b62985ca92015-04-17 08:45:512592 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072593 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092594 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162595 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272596
[email protected]f9ee6b52008-11-08 06:46:232597 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232598 MockWrite(
2599 "GET / HTTP/1.1\r\n"
2600 "Host: www.example.org\r\n"
2601 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:232602 };
2603
[email protected]038e9a32008-10-08 22:40:162604 MockRead data_reads1[] = {
2605 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2606 // Give a couple authenticate options (only the middle one is actually
2607 // supported).
[email protected]22927ad2009-09-21 19:56:192608 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:162609 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2610 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2611 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2612 // Large content-length -- won't matter, as connection will be reset.
2613 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062614 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:162615 };
2616
2617 // After calling trans->RestartWithAuth(), this is the request we should
2618 // be issuing -- the final header line contains the credentials.
2619 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232620 MockWrite(
2621 "GET / HTTP/1.1\r\n"
2622 "Host: www.example.org\r\n"
2623 "Connection: keep-alive\r\n"
2624 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:162625 };
2626
2627 // Lastly, the server responds with the actual content.
2628 MockRead data_reads2[] = {
2629 MockRead("HTTP/1.0 200 OK\r\n"),
2630 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2631 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062632 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:162633 };
2634
Ryan Sleevib8d7ea02018-05-07 20:01:012635 StaticSocketDataProvider data1(data_reads1, data_writes1);
2636 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:072637 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2638 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:162639
[email protected]49639fa2011-12-20 23:22:412640 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:162641
tfarina42834112016-09-22 13:38:202642 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012643 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162644
2645 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012646 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162647
[email protected]58e32bb2013-01-21 18:23:252648 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162649 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
[email protected]58e32bb2013-01-21 18:23:252650 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2651
Ryan Sleevib8d7ea02018-05-07 20:01:012652 int64_t writes_size1 = CountWriteBytes(data_writes1);
bnc691fda62016-08-12 00:43:162653 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012654 int64_t reads_size1 = CountReadBytes(data_reads1);
bnc691fda62016-08-12 00:43:162655 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192656
bnc691fda62016-08-12 00:43:162657 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522658 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042659 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:162660
[email protected]49639fa2011-12-20 23:22:412661 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:162662
bnc691fda62016-08-12 00:43:162663 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012664 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162665
2666 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012667 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162668
[email protected]58e32bb2013-01-21 18:23:252669 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162670 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
[email protected]58e32bb2013-01-21 18:23:252671 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2672 // The load timing after restart should have a new socket ID, and times after
2673 // those of the first load timing.
2674 EXPECT_LE(load_timing_info1.receive_headers_end,
2675 load_timing_info2.connect_timing.connect_start);
2676 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2677
Ryan Sleevib8d7ea02018-05-07 20:01:012678 int64_t writes_size2 = CountWriteBytes(data_writes2);
bnc691fda62016-08-12 00:43:162679 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012680 int64_t reads_size2 = CountReadBytes(data_reads2);
bnc691fda62016-08-12 00:43:162681 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192682
bnc691fda62016-08-12 00:43:162683 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522684 ASSERT_TRUE(response);
2685 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:162686 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:162687}
2688
ttuttled9dbc652015-09-29 20:00:592689// Test the request-challenge-retry sequence for basic auth.
2690// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012691TEST_F(HttpNetworkTransactionTest, BasicAuthWithAddressChange) {
ttuttled9dbc652015-09-29 20:00:592692 HttpRequestInfo request;
2693 request.method = "GET";
2694 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102695 request.traffic_annotation =
2696 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttled9dbc652015-09-29 20:00:592697
2698 TestNetLog log;
2699 MockHostResolver* resolver = new MockHostResolver();
2700 session_deps_.net_log = &log;
2701 session_deps_.host_resolver.reset(resolver);
danakj1fd259a02016-04-16 03:17:092702 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
bnc691fda62016-08-12 00:43:162703 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttled9dbc652015-09-29 20:00:592704
2705 resolver->rules()->ClearRules();
2706 resolver->rules()->AddRule("www.example.org", "127.0.0.1");
2707
2708 MockWrite data_writes1[] = {
2709 MockWrite("GET / HTTP/1.1\r\n"
2710 "Host: www.example.org\r\n"
2711 "Connection: keep-alive\r\n\r\n"),
2712 };
2713
2714 MockRead data_reads1[] = {
2715 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2716 // Give a couple authenticate options (only the middle one is actually
2717 // supported).
2718 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
2719 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2720 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2721 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2722 // Large content-length -- won't matter, as connection will be reset.
2723 MockRead("Content-Length: 10000\r\n\r\n"),
2724 MockRead(SYNCHRONOUS, ERR_FAILED),
2725 };
2726
2727 // After calling trans->RestartWithAuth(), this is the request we should
2728 // be issuing -- the final header line contains the credentials.
2729 MockWrite data_writes2[] = {
2730 MockWrite("GET / HTTP/1.1\r\n"
2731 "Host: www.example.org\r\n"
2732 "Connection: keep-alive\r\n"
2733 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2734 };
2735
2736 // Lastly, the server responds with the actual content.
2737 MockRead data_reads2[] = {
2738 MockRead("HTTP/1.0 200 OK\r\n"),
2739 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2740 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, OK),
2741 };
2742
Ryan Sleevib8d7ea02018-05-07 20:01:012743 StaticSocketDataProvider data1(data_reads1, data_writes1);
2744 StaticSocketDataProvider data2(data_reads2, data_writes2);
ttuttled9dbc652015-09-29 20:00:592745 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2746 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2747
2748 TestCompletionCallback callback1;
2749
bnc691fda62016-08-12 00:43:162750 EXPECT_EQ(OK, callback1.GetResult(trans.Start(&request, callback1.callback(),
tfarina42834112016-09-22 13:38:202751 NetLogWithSource())));
ttuttled9dbc652015-09-29 20:00:592752
2753 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162754 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
ttuttled9dbc652015-09-29 20:00:592755 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2756
Ryan Sleevib8d7ea02018-05-07 20:01:012757 int64_t writes_size1 = CountWriteBytes(data_writes1);
bnc691fda62016-08-12 00:43:162758 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012759 int64_t reads_size1 = CountReadBytes(data_reads1);
bnc691fda62016-08-12 00:43:162760 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592761
bnc691fda62016-08-12 00:43:162762 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592763 ASSERT_TRUE(response);
2764 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2765
2766 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:162767 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592768 ASSERT_FALSE(endpoint.address().empty());
2769 EXPECT_EQ("127.0.0.1:80", endpoint.ToString());
2770
2771 resolver->rules()->ClearRules();
2772 resolver->rules()->AddRule("www.example.org", "127.0.0.2");
2773
2774 TestCompletionCallback callback2;
2775
bnc691fda62016-08-12 00:43:162776 EXPECT_EQ(OK, callback2.GetResult(trans.RestartWithAuth(
ttuttled9dbc652015-09-29 20:00:592777 AuthCredentials(kFoo, kBar), callback2.callback())));
2778
2779 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162780 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
ttuttled9dbc652015-09-29 20:00:592781 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2782 // The load timing after restart should have a new socket ID, and times after
2783 // those of the first load timing.
2784 EXPECT_LE(load_timing_info1.receive_headers_end,
2785 load_timing_info2.connect_timing.connect_start);
2786 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2787
Ryan Sleevib8d7ea02018-05-07 20:01:012788 int64_t writes_size2 = CountWriteBytes(data_writes2);
bnc691fda62016-08-12 00:43:162789 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012790 int64_t reads_size2 = CountReadBytes(data_reads2);
bnc691fda62016-08-12 00:43:162791 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592792
bnc691fda62016-08-12 00:43:162793 response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592794 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:522795 EXPECT_FALSE(response->auth_challenge);
ttuttled9dbc652015-09-29 20:00:592796 EXPECT_EQ(100, response->headers->GetContentLength());
2797
bnc691fda62016-08-12 00:43:162798 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592799 ASSERT_FALSE(endpoint.address().empty());
2800 EXPECT_EQ("127.0.0.2:80", endpoint.ToString());
2801}
2802
David Benjamin83ddfb32018-03-30 01:07:522803// Test that, if the server requests auth indefinitely, HttpNetworkTransaction
2804// will eventually give up.
2805TEST_F(HttpNetworkTransactionTest, BasicAuthForever) {
2806 HttpRequestInfo request;
2807 request.method = "GET";
2808 request.url = GURL("http://www.example.org/");
2809 request.traffic_annotation =
2810 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2811
2812 TestNetLog log;
2813 session_deps_.net_log = &log;
2814 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2815 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
2816
2817 MockWrite data_writes[] = {
2818 MockWrite("GET / HTTP/1.1\r\n"
2819 "Host: www.example.org\r\n"
2820 "Connection: keep-alive\r\n\r\n"),
2821 };
2822
2823 MockRead data_reads[] = {
2824 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2825 // Give a couple authenticate options (only the middle one is actually
2826 // supported).
2827 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
2828 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2829 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2830 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2831 // Large content-length -- won't matter, as connection will be reset.
2832 MockRead("Content-Length: 10000\r\n\r\n"),
2833 MockRead(SYNCHRONOUS, ERR_FAILED),
2834 };
2835
2836 // After calling trans->RestartWithAuth(), this is the request we should
2837 // be issuing -- the final header line contains the credentials.
2838 MockWrite data_writes_restart[] = {
2839 MockWrite("GET / HTTP/1.1\r\n"
2840 "Host: www.example.org\r\n"
2841 "Connection: keep-alive\r\n"
2842 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2843 };
2844
Ryan Sleevib8d7ea02018-05-07 20:01:012845 StaticSocketDataProvider data(data_reads, data_writes);
David Benjamin83ddfb32018-03-30 01:07:522846 session_deps_.socket_factory->AddSocketDataProvider(&data);
2847
2848 TestCompletionCallback callback;
2849 int rv = callback.GetResult(
2850 trans.Start(&request, callback.callback(), NetLogWithSource()));
2851
2852 std::vector<std::unique_ptr<StaticSocketDataProvider>> data_restarts;
2853 for (int i = 0; i < 32; i++) {
2854 // Check the previous response was a 401.
2855 EXPECT_THAT(rv, IsOk());
2856 const HttpResponseInfo* response = trans.GetResponseInfo();
2857 ASSERT_TRUE(response);
2858 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2859
2860 data_restarts.push_back(std::make_unique<StaticSocketDataProvider>(
Ryan Sleevib8d7ea02018-05-07 20:01:012861 data_reads, data_writes_restart));
David Benjamin83ddfb32018-03-30 01:07:522862 session_deps_.socket_factory->AddSocketDataProvider(
2863 data_restarts.back().get());
2864 rv = callback.GetResult(trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
2865 callback.callback()));
2866 }
2867
2868 // After too many tries, the transaction should have given up.
2869 EXPECT_THAT(rv, IsError(ERR_TOO_MANY_RETRIES));
2870}
2871
bncd16676a2016-07-20 16:23:012872TEST_F(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:462873 HttpRequestInfo request;
2874 request.method = "GET";
bncce36dca22015-04-21 22:11:232875 request.url = GURL("http://www.example.org/");
ttuttle859dc7a2015-04-23 19:42:292876 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:102877 request.traffic_annotation =
2878 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]861fcd52009-08-26 02:33:462879
danakj1fd259a02016-04-16 03:17:092880 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162881 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272882
[email protected]861fcd52009-08-26 02:33:462883 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:232884 MockWrite(
2885 "GET / HTTP/1.1\r\n"
2886 "Host: www.example.org\r\n"
2887 "Connection: keep-alive\r\n\r\n"),
[email protected]861fcd52009-08-26 02:33:462888 };
2889
2890 MockRead data_reads[] = {
2891 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2892 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2893 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2894 // Large content-length -- won't matter, as connection will be reset.
2895 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062896 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:462897 };
2898
Ryan Sleevib8d7ea02018-05-07 20:01:012899 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:072900 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:412901 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:462902
tfarina42834112016-09-22 13:38:202903 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012904 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]861fcd52009-08-26 02:33:462905
2906 rv = callback.WaitForResult();
2907 EXPECT_EQ(0, rv);
2908
Ryan Sleevib8d7ea02018-05-07 20:01:012909 int64_t writes_size = CountWriteBytes(data_writes);
bnc691fda62016-08-12 00:43:162910 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012911 int64_t reads_size = CountReadBytes(data_reads);
bnc691fda62016-08-12 00:43:162912 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192913
bnc691fda62016-08-12 00:43:162914 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522915 ASSERT_TRUE(response);
2916 EXPECT_FALSE(response->auth_challenge);
[email protected]861fcd52009-08-26 02:33:462917}
2918
[email protected]2d2697f92009-02-18 21:00:322919// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2920// connection.
bncd16676a2016-07-20 16:23:012921TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
mmenkecc2298e2015-12-07 18:20:182922 // On the second pass, the body read of the auth challenge is synchronous, so
2923 // IsConnectedAndIdle returns false. The socket should still be drained and
2924 // reused. See http://crbug.com/544255.
2925 for (int i = 0; i < 2; ++i) {
2926 HttpRequestInfo request;
2927 request.method = "GET";
2928 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102929 request.traffic_annotation =
2930 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:322931
mmenkecc2298e2015-12-07 18:20:182932 TestNetLog log;
2933 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092934 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272935
mmenkecc2298e2015-12-07 18:20:182936 MockWrite data_writes[] = {
2937 MockWrite(ASYNC, 0,
2938 "GET / HTTP/1.1\r\n"
2939 "Host: www.example.org\r\n"
2940 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322941
bnc691fda62016-08-12 00:43:162942 // After calling trans.RestartWithAuth(), this is the request we should
mmenkecc2298e2015-12-07 18:20:182943 // be issuing -- the final header line contains the credentials.
2944 MockWrite(ASYNC, 6,
2945 "GET / HTTP/1.1\r\n"
2946 "Host: www.example.org\r\n"
2947 "Connection: keep-alive\r\n"
2948 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2949 };
[email protected]2d2697f92009-02-18 21:00:322950
mmenkecc2298e2015-12-07 18:20:182951 MockRead data_reads[] = {
2952 MockRead(ASYNC, 1, "HTTP/1.1 401 Unauthorized\r\n"),
2953 MockRead(ASYNC, 2, "WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2954 MockRead(ASYNC, 3, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2955 MockRead(ASYNC, 4, "Content-Length: 14\r\n\r\n"),
2956 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 5, "Unauthorized\r\n"),
[email protected]2d2697f92009-02-18 21:00:322957
mmenkecc2298e2015-12-07 18:20:182958 // Lastly, the server responds with the actual content.
2959 MockRead(ASYNC, 7, "HTTP/1.1 200 OK\r\n"),
2960 MockRead(ASYNC, 8, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2961 MockRead(ASYNC, 9, "Content-Length: 5\r\n\r\n"),
2962 MockRead(ASYNC, 10, "Hello"),
2963 };
[email protected]2d2697f92009-02-18 21:00:322964
Ryan Sleevib8d7ea02018-05-07 20:01:012965 SequencedSocketData data(data_reads, data_writes);
mmenkecc2298e2015-12-07 18:20:182966 data.set_busy_before_sync_reads(true);
2967 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]2d0a4f92011-05-05 16:38:462968
mmenkecc2298e2015-12-07 18:20:182969 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322970
bnc691fda62016-08-12 00:43:162971 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202972 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012973 ASSERT_THAT(callback1.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322974
mmenkecc2298e2015-12-07 18:20:182975 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162976 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
mmenkecc2298e2015-12-07 18:20:182977 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
[email protected]2d2697f92009-02-18 21:00:322978
bnc691fda62016-08-12 00:43:162979 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182980 ASSERT_TRUE(response);
2981 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322982
mmenkecc2298e2015-12-07 18:20:182983 TestCompletionCallback callback2;
[email protected]58e32bb2013-01-21 18:23:252984
bnc691fda62016-08-12 00:43:162985 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
2986 callback2.callback());
robpercival214763f2016-07-01 23:27:012987 ASSERT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322988
mmenkecc2298e2015-12-07 18:20:182989 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162990 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
mmenkecc2298e2015-12-07 18:20:182991 TestLoadTimingReused(load_timing_info2);
2992 // The load timing after restart should have the same socket ID, and times
2993 // those of the first load timing.
2994 EXPECT_LE(load_timing_info1.receive_headers_end,
2995 load_timing_info2.send_start);
2996 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]2d2697f92009-02-18 21:00:322997
bnc691fda62016-08-12 00:43:162998 response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182999 ASSERT_TRUE(response);
3000 EXPECT_FALSE(response->auth_challenge);
3001 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:323002
mmenkecc2298e2015-12-07 18:20:183003 std::string response_data;
bnc691fda62016-08-12 00:43:163004 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]2d2697f92009-02-18 21:00:323005
Ryan Sleevib8d7ea02018-05-07 20:01:013006 int64_t writes_size = CountWriteBytes(data_writes);
bnc691fda62016-08-12 00:43:163007 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:013008 int64_t reads_size = CountReadBytes(data_reads);
bnc691fda62016-08-12 00:43:163009 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
mmenkecc2298e2015-12-07 18:20:183010 }
[email protected]2d2697f92009-02-18 21:00:323011}
3012
3013// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3014// connection and with no response body to drain.
bncd16676a2016-07-20 16:23:013015TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:423016 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:323017 request.method = "GET";
bncce36dca22015-04-21 22:11:233018 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:103019 request.traffic_annotation =
3020 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:323021
danakj1fd259a02016-04-16 03:17:093022 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273023
[email protected]2d2697f92009-02-18 21:00:323024 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:163025 MockWrite("GET / HTTP/1.1\r\n"
3026 "Host: www.example.org\r\n"
3027 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323028
bnc691fda62016-08-12 00:43:163029 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:233030 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:163031 MockWrite("GET / HTTP/1.1\r\n"
3032 "Host: www.example.org\r\n"
3033 "Connection: keep-alive\r\n"
3034 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323035 };
3036
[email protected]2d2697f92009-02-18 21:00:323037 MockRead data_reads1[] = {
3038 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
3039 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:313040 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:323041
3042 // Lastly, the server responds with the actual content.
3043 MockRead("HTTP/1.1 200 OK\r\n"),
3044 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:503045 MockRead("Content-Length: 5\r\n\r\n"),
3046 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:323047 };
3048
[email protected]2d0a4f92011-05-05 16:38:463049 // An incorrect reconnect would cause this to be read.
3050 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:063051 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:463052 };
3053
Ryan Sleevib8d7ea02018-05-07 20:01:013054 StaticSocketDataProvider data1(data_reads1, data_writes1);
3055 StaticSocketDataProvider data2(data_reads2, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:073056 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3057 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:323058
[email protected]49639fa2011-12-20 23:22:413059 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323060
bnc691fda62016-08-12 00:43:163061 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:203062 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013063 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:323064
3065 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013066 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:323067
bnc691fda62016-08-12 00:43:163068 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523069 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:043070 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:323071
[email protected]49639fa2011-12-20 23:22:413072 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323073
bnc691fda62016-08-12 00:43:163074 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013075 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:323076
3077 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013078 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:323079
bnc691fda62016-08-12 00:43:163080 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523081 ASSERT_TRUE(response);
3082 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503083 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:323084}
3085
3086// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3087// connection and with a large response body to drain.
bncd16676a2016-07-20 16:23:013088TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:423089 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:323090 request.method = "GET";
bncce36dca22015-04-21 22:11:233091 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:103092 request.traffic_annotation =
3093 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:323094
danakj1fd259a02016-04-16 03:17:093095 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273096
[email protected]2d2697f92009-02-18 21:00:323097 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:163098 MockWrite("GET / HTTP/1.1\r\n"
3099 "Host: www.example.org\r\n"
3100 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323101
bnc691fda62016-08-12 00:43:163102 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:233103 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:163104 MockWrite("GET / HTTP/1.1\r\n"
3105 "Host: www.example.org\r\n"
3106 "Connection: keep-alive\r\n"
3107 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323108 };
3109
3110 // Respond with 5 kb of response body.
3111 std::string large_body_string("Unauthorized");
3112 large_body_string.append(5 * 1024, ' ');
3113 large_body_string.append("\r\n");
3114
3115 MockRead data_reads1[] = {
3116 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
3117 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3118 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3119 // 5134 = 12 + 5 * 1024 + 2
3120 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063121 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:323122
3123 // Lastly, the server responds with the actual content.
3124 MockRead("HTTP/1.1 200 OK\r\n"),
3125 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:503126 MockRead("Content-Length: 5\r\n\r\n"),
3127 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:323128 };
3129
[email protected]2d0a4f92011-05-05 16:38:463130 // An incorrect reconnect would cause this to be read.
3131 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:063132 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:463133 };
3134
Ryan Sleevib8d7ea02018-05-07 20:01:013135 StaticSocketDataProvider data1(data_reads1, data_writes1);
3136 StaticSocketDataProvider data2(data_reads2, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:073137 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3138 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:323139
[email protected]49639fa2011-12-20 23:22:413140 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323141
bnc691fda62016-08-12 00:43:163142 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:203143 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013144 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:323145
3146 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013147 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:323148
bnc691fda62016-08-12 00:43:163149 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523150 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:043151 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:323152
[email protected]49639fa2011-12-20 23:22:413153 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323154
bnc691fda62016-08-12 00:43:163155 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013156 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:323157
3158 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013159 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:323160
bnc691fda62016-08-12 00:43:163161 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523162 ASSERT_TRUE(response);
3163 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503164 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:323165}
3166
3167// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:313168// connection, but the server gets impatient and closes the connection.
bncd16676a2016-07-20 16:23:013169TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:313170 HttpRequestInfo request;
3171 request.method = "GET";
bncce36dca22015-04-21 22:11:233172 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:103173 request.traffic_annotation =
3174 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]11203f012009-11-12 23:02:313175
danakj1fd259a02016-04-16 03:17:093176 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273177
[email protected]11203f012009-11-12 23:02:313178 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233179 MockWrite(
3180 "GET / HTTP/1.1\r\n"
3181 "Host: www.example.org\r\n"
3182 "Connection: keep-alive\r\n\r\n"),
3183 // This simulates the seemingly successful write to a closed connection
3184 // if the bug is not fixed.
3185 MockWrite(
3186 "GET / HTTP/1.1\r\n"
3187 "Host: www.example.org\r\n"
3188 "Connection: keep-alive\r\n"
3189 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:313190 };
3191
3192 MockRead data_reads1[] = {
3193 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
3194 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3195 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3196 MockRead("Content-Length: 14\r\n\r\n"),
3197 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:063198 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:313199 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:063200 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:313201 };
3202
bnc691fda62016-08-12 00:43:163203 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]11203f012009-11-12 23:02:313204 // be issuing -- the final header line contains the credentials.
3205 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:233206 MockWrite(
3207 "GET / HTTP/1.1\r\n"
3208 "Host: www.example.org\r\n"
3209 "Connection: keep-alive\r\n"
3210 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:313211 };
3212
3213 // Lastly, the server responds with the actual content.
3214 MockRead data_reads2[] = {
3215 MockRead("HTTP/1.1 200 OK\r\n"),
3216 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:503217 MockRead("Content-Length: 5\r\n\r\n"),
3218 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:313219 };
3220
Ryan Sleevib8d7ea02018-05-07 20:01:013221 StaticSocketDataProvider data1(data_reads1, data_writes1);
3222 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:073223 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3224 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:313225
[email protected]49639fa2011-12-20 23:22:413226 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:313227
bnc691fda62016-08-12 00:43:163228 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:203229 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013230 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:313231
3232 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013233 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:313234
bnc691fda62016-08-12 00:43:163235 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523236 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:043237 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:313238
[email protected]49639fa2011-12-20 23:22:413239 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:313240
bnc691fda62016-08-12 00:43:163241 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013242 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:313243
3244 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013245 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:313246
bnc691fda62016-08-12 00:43:163247 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523248 ASSERT_TRUE(response);
3249 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503250 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:313251}
3252
[email protected]394816e92010-08-03 07:38:593253// Test the request-challenge-retry sequence for basic auth, over a connection
3254// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013255TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
ttuttle34f63b52015-03-05 04:33:013256 HttpRequestInfo request;
3257 request.method = "GET";
bncce36dca22015-04-21 22:11:233258 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:013259 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293260 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103261 request.traffic_annotation =
3262 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle34f63b52015-03-05 04:33:013263
3264 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593265 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493266 ProxyResolutionService::CreateFixedFromPacResult(
3267 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513268 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:013269 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093270 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013271
3272 // Since we have proxy, should try to establish tunnel.
3273 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543274 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173275 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543276 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013277 };
3278
mmenkee71e15332015-10-07 16:39:543279 // The proxy responds to the connect with a 407, using a non-persistent
ttuttle34f63b52015-03-05 04:33:013280 // connection.
3281 MockRead data_reads1[] = {
3282 // No credentials.
3283 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
3284 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
mmenkee71e15332015-10-07 16:39:543285 };
ttuttle34f63b52015-03-05 04:33:013286
mmenkee71e15332015-10-07 16:39:543287 // Since the first connection couldn't be reused, need to establish another
3288 // once given credentials.
3289 MockWrite data_writes2[] = {
3290 // After calling trans->RestartWithAuth(), this is the request we should
3291 // be issuing -- the final header line contains the credentials.
3292 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173293 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543294 "Proxy-Connection: keep-alive\r\n"
3295 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3296
3297 MockWrite("GET / HTTP/1.1\r\n"
3298 "Host: www.example.org\r\n"
3299 "Connection: keep-alive\r\n\r\n"),
3300 };
3301
3302 MockRead data_reads2[] = {
ttuttle34f63b52015-03-05 04:33:013303 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3304
3305 MockRead("HTTP/1.1 200 OK\r\n"),
3306 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3307 MockRead("Content-Length: 5\r\n\r\n"),
3308 MockRead(SYNCHRONOUS, "hello"),
3309 };
3310
Ryan Sleevib8d7ea02018-05-07 20:01:013311 StaticSocketDataProvider data1(data_reads1, data_writes1);
ttuttle34f63b52015-03-05 04:33:013312 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:013313 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenkee71e15332015-10-07 16:39:543314 session_deps_.socket_factory->AddSocketDataProvider(&data2);
ttuttle34f63b52015-03-05 04:33:013315 SSLSocketDataProvider ssl(ASYNC, OK);
3316 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3317
3318 TestCompletionCallback callback1;
3319
bnc87dcefc2017-05-25 12:47:583320 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193321 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013322
3323 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013324 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:013325
3326 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013327 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463328 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:013329 log.GetEntries(&entries);
3330 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003331 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3332 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013333 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003334 entries, pos,
3335 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3336 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013337
3338 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523339 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013340 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523341 ASSERT_TRUE(response->headers);
ttuttle34f63b52015-03-05 04:33:013342 EXPECT_EQ(407, response->headers->response_code());
3343 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3344 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3345
3346 LoadTimingInfo load_timing_info;
3347 // CONNECT requests and responses are handled at the connect job level, so
3348 // the transaction does not yet have a connection.
3349 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3350
3351 TestCompletionCallback callback2;
3352
3353 rv =
3354 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013355 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:013356
3357 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013358 EXPECT_THAT(rv, IsOk());
ttuttle34f63b52015-03-05 04:33:013359
3360 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523361 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013362
3363 EXPECT_TRUE(response->headers->IsKeepAlive());
3364 EXPECT_EQ(200, response->headers->response_code());
3365 EXPECT_EQ(5, response->headers->GetContentLength());
3366 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3367
3368 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523369 EXPECT_FALSE(response->auth_challenge);
ttuttle34f63b52015-03-05 04:33:013370
3371 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3372 TestLoadTimingNotReusedWithPac(load_timing_info,
3373 CONNECT_TIMING_HAS_SSL_TIMES);
3374
3375 trans.reset();
3376 session->CloseAllConnections();
3377}
3378
3379// Test the request-challenge-retry sequence for basic auth, over a connection
3380// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013381TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) {
[email protected]394816e92010-08-03 07:38:593382 HttpRequestInfo request;
3383 request.method = "GET";
bncce36dca22015-04-21 22:11:233384 request.url = GURL("https://www.example.org/");
[email protected]394816e92010-08-03 07:38:593385 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293386 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103387 request.traffic_annotation =
3388 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]394816e92010-08-03 07:38:593389
[email protected]cb9bf6ca2011-01-28 13:15:273390 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593391 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493392 ProxyResolutionService::CreateFixedFromPacResult(
3393 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513394 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073395 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093396 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273397
[email protected]394816e92010-08-03 07:38:593398 // Since we have proxy, should try to establish tunnel.
3399 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543400 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173401 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543402 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenkee0b5c882015-08-26 20:29:113403 };
3404
mmenkee71e15332015-10-07 16:39:543405 // The proxy responds to the connect with a 407, using a non-persistent
mmenke0fd148d2015-09-30 23:00:083406 // connection.
3407 MockRead data_reads1[] = {
mmenkee71e15332015-10-07 16:39:543408 // No credentials.
3409 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3410 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3411 MockRead("Proxy-Connection: close\r\n\r\n"),
3412 };
mmenkee0b5c882015-08-26 20:29:113413
mmenkee71e15332015-10-07 16:39:543414 MockWrite data_writes2[] = {
3415 // After calling trans->RestartWithAuth(), this is the request we should
3416 // be issuing -- the final header line contains the credentials.
3417 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173418 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543419 "Proxy-Connection: keep-alive\r\n"
3420 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
mmenke0fd148d2015-09-30 23:00:083421
mmenkee71e15332015-10-07 16:39:543422 MockWrite("GET / HTTP/1.1\r\n"
3423 "Host: www.example.org\r\n"
3424 "Connection: keep-alive\r\n\r\n"),
3425 };
3426
3427 MockRead data_reads2[] = {
3428 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3429
3430 MockRead("HTTP/1.1 200 OK\r\n"),
3431 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3432 MockRead("Content-Length: 5\r\n\r\n"),
3433 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:593434 };
3435
Ryan Sleevib8d7ea02018-05-07 20:01:013436 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:073437 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:013438 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenkee71e15332015-10-07 16:39:543439 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8ddf8322012-02-23 18:08:063440 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073441 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:593442
[email protected]49639fa2011-12-20 23:22:413443 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:593444
bnc87dcefc2017-05-25 12:47:583445 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193446 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:503447
[email protected]49639fa2011-12-20 23:22:413448 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013449 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593450
3451 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013452 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463453 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403454 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:593455 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003456 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3457 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593458 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403459 entries, pos,
mikecirone8b85c432016-09-08 19:11:003460 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3461 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593462
3463 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523464 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013465 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523466 ASSERT_TRUE(response->headers);
[email protected]394816e92010-08-03 07:38:593467 EXPECT_EQ(407, response->headers->response_code());
3468 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043469 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:593470
[email protected]029c83b62013-01-24 05:28:203471 LoadTimingInfo load_timing_info;
3472 // CONNECT requests and responses are handled at the connect job level, so
3473 // the transaction does not yet have a connection.
3474 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3475
[email protected]49639fa2011-12-20 23:22:413476 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:593477
[email protected]49639fa2011-12-20 23:22:413478 rv = trans->RestartWithAuth(
3479 AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013480 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593481
3482 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013483 EXPECT_THAT(rv, IsOk());
[email protected]394816e92010-08-03 07:38:593484
3485 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523486 ASSERT_TRUE(response);
[email protected]394816e92010-08-03 07:38:593487
3488 EXPECT_TRUE(response->headers->IsKeepAlive());
3489 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:503490 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:593491 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3492
3493 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523494 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503495
[email protected]029c83b62013-01-24 05:28:203496 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3497 TestLoadTimingNotReusedWithPac(load_timing_info,
3498 CONNECT_TIMING_HAS_SSL_TIMES);
3499
[email protected]0b0bf032010-09-21 18:08:503500 trans.reset();
[email protected]102e27c2011-02-23 01:01:313501 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:593502}
3503
[email protected]11203f012009-11-12 23:02:313504// Test the request-challenge-retry sequence for basic auth, over a keep-alive
ttuttle34f63b52015-03-05 04:33:013505// proxy connection with HTTP/1.0 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013506TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
mmenked39192ee2015-12-09 00:57:233507 // On the second pass, the body read of the auth challenge is synchronous, so
3508 // IsConnectedAndIdle returns false. The socket should still be drained and
3509 // reused. See http://crbug.com/544255.
3510 for (int i = 0; i < 2; ++i) {
3511 HttpRequestInfo request;
3512 request.method = "GET";
3513 request.url = GURL("https://www.example.org/");
3514 // Ensure that proxy authentication is attempted even
3515 // when the no authentication data flag is set.
3516 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103517 request.traffic_annotation =
3518 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle34f63b52015-03-05 04:33:013519
mmenked39192ee2015-12-09 00:57:233520 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593521 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493522 ProxyResolutionService::CreateFixed("myproxy:70",
3523 TRAFFIC_ANNOTATION_FOR_TESTS);
mmenked39192ee2015-12-09 00:57:233524 BoundTestNetLog log;
3525 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093526 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013527
bnc691fda62016-08-12 00:43:163528 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013529
mmenked39192ee2015-12-09 00:57:233530 // Since we have proxy, should try to establish tunnel.
3531 MockWrite data_writes1[] = {
3532 MockWrite(ASYNC, 0,
3533 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3534 "Host: www.example.org:443\r\n"
3535 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013536
bnc691fda62016-08-12 00:43:163537 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233538 // be issuing -- the final header line contains the credentials.
3539 MockWrite(ASYNC, 3,
3540 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3541 "Host: www.example.org:443\r\n"
3542 "Proxy-Connection: keep-alive\r\n"
3543 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3544 };
ttuttle34f63b52015-03-05 04:33:013545
mmenked39192ee2015-12-09 00:57:233546 // The proxy responds to the connect with a 407, using a persistent
3547 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3548 MockRead data_reads1[] = {
3549 // No credentials.
3550 MockRead(ASYNC, 1,
3551 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3552 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3553 "Proxy-Connection: keep-alive\r\n"
3554 "Content-Length: 10\r\n\r\n"),
3555 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
ttuttle34f63b52015-03-05 04:33:013556
mmenked39192ee2015-12-09 00:57:233557 // Wrong credentials (wrong password).
3558 MockRead(ASYNC, 4,
3559 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3560 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3561 "Proxy-Connection: keep-alive\r\n"
3562 "Content-Length: 10\r\n\r\n"),
3563 // No response body because the test stops reading here.
3564 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3565 };
ttuttle34f63b52015-03-05 04:33:013566
Ryan Sleevib8d7ea02018-05-07 20:01:013567 SequencedSocketData data1(data_reads1, data_writes1);
mmenked39192ee2015-12-09 00:57:233568 data1.set_busy_before_sync_reads(true);
3569 session_deps_.socket_factory->AddSocketDataProvider(&data1);
ttuttle34f63b52015-03-05 04:33:013570
mmenked39192ee2015-12-09 00:57:233571 TestCompletionCallback callback1;
ttuttle34f63b52015-03-05 04:33:013572
bnc691fda62016-08-12 00:43:163573 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013574 EXPECT_THAT(callback1.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013575
mmenked39192ee2015-12-09 00:57:233576 TestNetLogEntry::List entries;
3577 log.GetEntries(&entries);
3578 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003579 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3580 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233581 ExpectLogContainsSomewhere(
3582 entries, pos,
mikecirone8b85c432016-09-08 19:11:003583 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3584 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013585
bnc691fda62016-08-12 00:43:163586 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233587 ASSERT_TRUE(response);
3588 ASSERT_TRUE(response->headers);
3589 EXPECT_TRUE(response->headers->IsKeepAlive());
3590 EXPECT_EQ(407, response->headers->response_code());
3591 EXPECT_EQ(10, response->headers->GetContentLength());
3592 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3593 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013594
mmenked39192ee2015-12-09 00:57:233595 TestCompletionCallback callback2;
ttuttle34f63b52015-03-05 04:33:013596
mmenked39192ee2015-12-09 00:57:233597 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163598 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3599 callback2.callback());
robpercival214763f2016-07-01 23:27:013600 EXPECT_THAT(callback2.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013601
bnc691fda62016-08-12 00:43:163602 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233603 ASSERT_TRUE(response);
3604 ASSERT_TRUE(response->headers);
3605 EXPECT_TRUE(response->headers->IsKeepAlive());
3606 EXPECT_EQ(407, response->headers->response_code());
3607 EXPECT_EQ(10, response->headers->GetContentLength());
3608 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3609 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013610
mmenked39192ee2015-12-09 00:57:233611 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3612 // out of scope.
3613 session->CloseAllConnections();
3614 }
ttuttle34f63b52015-03-05 04:33:013615}
3616
3617// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3618// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013619TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
mmenked39192ee2015-12-09 00:57:233620 // On the second pass, the body read of the auth challenge is synchronous, so
3621 // IsConnectedAndIdle returns false. The socket should still be drained and
3622 // reused. See http://crbug.com/544255.
3623 for (int i = 0; i < 2; ++i) {
3624 HttpRequestInfo request;
3625 request.method = "GET";
3626 request.url = GURL("https://www.example.org/");
3627 // Ensure that proxy authentication is attempted even
3628 // when the no authentication data flag is set.
3629 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103630 request.traffic_annotation =
3631 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenked39192ee2015-12-09 00:57:233632
3633 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593634 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493635 ProxyResolutionService::CreateFixed("myproxy:70",
3636 TRAFFIC_ANNOTATION_FOR_TESTS);
mmenked39192ee2015-12-09 00:57:233637 BoundTestNetLog log;
3638 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093639 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenked39192ee2015-12-09 00:57:233640
bnc691fda62016-08-12 00:43:163641 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenked39192ee2015-12-09 00:57:233642
3643 // Since we have proxy, should try to establish tunnel.
3644 MockWrite data_writes1[] = {
3645 MockWrite(ASYNC, 0,
3646 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3647 "Host: www.example.org:443\r\n"
3648 "Proxy-Connection: keep-alive\r\n\r\n"),
3649
bnc691fda62016-08-12 00:43:163650 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233651 // be issuing -- the final header line contains the credentials.
3652 MockWrite(ASYNC, 3,
3653 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3654 "Host: www.example.org:443\r\n"
3655 "Proxy-Connection: keep-alive\r\n"
3656 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3657 };
3658
3659 // The proxy responds to the connect with a 407, using a persistent
3660 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3661 MockRead data_reads1[] = {
3662 // No credentials.
3663 MockRead(ASYNC, 1,
3664 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3665 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3666 "Content-Length: 10\r\n\r\n"),
3667 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
3668
3669 // Wrong credentials (wrong password).
3670 MockRead(ASYNC, 4,
3671 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3672 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3673 "Content-Length: 10\r\n\r\n"),
3674 // No response body because the test stops reading here.
3675 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3676 };
3677
Ryan Sleevib8d7ea02018-05-07 20:01:013678 SequencedSocketData data1(data_reads1, data_writes1);
mmenked39192ee2015-12-09 00:57:233679 data1.set_busy_before_sync_reads(true);
3680 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3681
3682 TestCompletionCallback callback1;
3683
bnc691fda62016-08-12 00:43:163684 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013685 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233686
3687 TestNetLogEntry::List entries;
3688 log.GetEntries(&entries);
3689 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003690 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3691 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233692 ExpectLogContainsSomewhere(
3693 entries, pos,
mikecirone8b85c432016-09-08 19:11:003694 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3695 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233696
bnc691fda62016-08-12 00:43:163697 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233698 ASSERT_TRUE(response);
3699 ASSERT_TRUE(response->headers);
3700 EXPECT_TRUE(response->headers->IsKeepAlive());
3701 EXPECT_EQ(407, response->headers->response_code());
3702 EXPECT_EQ(10, response->headers->GetContentLength());
3703 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3704 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3705
3706 TestCompletionCallback callback2;
3707
3708 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163709 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3710 callback2.callback());
robpercival214763f2016-07-01 23:27:013711 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233712
bnc691fda62016-08-12 00:43:163713 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233714 ASSERT_TRUE(response);
3715 ASSERT_TRUE(response->headers);
3716 EXPECT_TRUE(response->headers->IsKeepAlive());
3717 EXPECT_EQ(407, response->headers->response_code());
3718 EXPECT_EQ(10, response->headers->GetContentLength());
3719 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3720 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3721
3722 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3723 // out of scope.
3724 session->CloseAllConnections();
3725 }
3726}
3727
3728// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3729// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel, in
3730// the case the server sends extra data on the original socket, so it can't be
3731// reused.
bncd16676a2016-07-20 16:23:013732TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveExtraData) {
[email protected]cb9bf6ca2011-01-28 13:15:273733 HttpRequestInfo request;
3734 request.method = "GET";
bncce36dca22015-04-21 22:11:233735 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273736 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293737 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103738 request.traffic_annotation =
3739 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:273740
[email protected]2d2697f92009-02-18 21:00:323741 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593742 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493743 ProxyResolutionService::CreateFixedFromPacResult(
3744 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513745 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073746 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093747 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:323748
[email protected]2d2697f92009-02-18 21:00:323749 // Since we have proxy, should try to establish tunnel.
3750 MockWrite data_writes1[] = {
mmenked39192ee2015-12-09 00:57:233751 MockWrite(ASYNC, 0,
3752 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173753 "Host: www.example.org:443\r\n"
3754 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233755 };
[email protected]2d2697f92009-02-18 21:00:323756
mmenked39192ee2015-12-09 00:57:233757 // The proxy responds to the connect with a 407, using a persistent, but sends
3758 // extra data, so the socket cannot be reused.
3759 MockRead data_reads1[] = {
3760 // No credentials.
3761 MockRead(ASYNC, 1,
3762 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3763 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3764 "Content-Length: 10\r\n\r\n"),
3765 MockRead(SYNCHRONOUS, 2, "0123456789"),
3766 MockRead(SYNCHRONOUS, 3, "I'm broken!"),
3767 };
3768
3769 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:233770 // After calling trans->RestartWithAuth(), this is the request we should
3771 // be issuing -- the final header line contains the credentials.
mmenked39192ee2015-12-09 00:57:233772 MockWrite(ASYNC, 0,
3773 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173774 "Host: www.example.org:443\r\n"
3775 "Proxy-Connection: keep-alive\r\n"
mmenked39192ee2015-12-09 00:57:233776 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3777
3778 MockWrite(ASYNC, 2,
3779 "GET / HTTP/1.1\r\n"
3780 "Host: www.example.org\r\n"
3781 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323782 };
3783
mmenked39192ee2015-12-09 00:57:233784 MockRead data_reads2[] = {
3785 MockRead(ASYNC, 1, "HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323786
mmenked39192ee2015-12-09 00:57:233787 MockRead(ASYNC, 3,
3788 "HTTP/1.1 200 OK\r\n"
3789 "Content-Type: text/html; charset=iso-8859-1\r\n"
3790 "Content-Length: 5\r\n\r\n"),
3791 // No response body because the test stops reading here.
3792 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 4),
[email protected]2d2697f92009-02-18 21:00:323793 };
3794
Ryan Sleevib8d7ea02018-05-07 20:01:013795 SequencedSocketData data1(data_reads1, data_writes1);
mmenked39192ee2015-12-09 00:57:233796 data1.set_busy_before_sync_reads(true);
[email protected]bb88e1d32013-05-03 23:11:073797 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:013798 SequencedSocketData data2(data_reads2, data_writes2);
mmenked39192ee2015-12-09 00:57:233799 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3800 SSLSocketDataProvider ssl(ASYNC, OK);
3801 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d2697f92009-02-18 21:00:323802
[email protected]49639fa2011-12-20 23:22:413803 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323804
bnc87dcefc2017-05-25 12:47:583805 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193806 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d2697f92009-02-18 21:00:323807
mmenked39192ee2015-12-09 00:57:233808 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013809 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233810
mmenke43758e62015-05-04 21:09:463811 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403812 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:393813 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003814 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3815 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:393816 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403817 entries, pos,
mikecirone8b85c432016-09-08 19:11:003818 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3819 NetLogEventPhase::NONE);
[email protected]2d2697f92009-02-18 21:00:323820
[email protected]1c773ea12009-04-28 19:58:423821 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243822 ASSERT_TRUE(response);
3823 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:323824 EXPECT_TRUE(response->headers->IsKeepAlive());
3825 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423826 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043827 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:323828
mmenked39192ee2015-12-09 00:57:233829 LoadTimingInfo load_timing_info;
3830 // CONNECT requests and responses are handled at the connect job level, so
3831 // the transaction does not yet have a connection.
3832 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3833
[email protected]49639fa2011-12-20 23:22:413834 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323835
mmenked39192ee2015-12-09 00:57:233836 rv =
3837 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013838 EXPECT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:323839
[email protected]2d2697f92009-02-18 21:00:323840 EXPECT_TRUE(response->headers->IsKeepAlive());
mmenked39192ee2015-12-09 00:57:233841 EXPECT_EQ(200, response->headers->response_code());
3842 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:423843 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]e772db3f2010-07-12 18:11:133844
mmenked39192ee2015-12-09 00:57:233845 // The password prompt info should not be set.
3846 EXPECT_FALSE(response->auth_challenge);
3847
3848 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3849 TestLoadTimingNotReusedWithPac(load_timing_info,
3850 CONNECT_TIMING_HAS_SSL_TIMES);
3851
3852 trans.reset();
[email protected]102e27c2011-02-23 01:01:313853 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:323854}
3855
mmenkee71e15332015-10-07 16:39:543856// Test the case a proxy closes a socket while the challenge body is being
3857// drained.
bncd16676a2016-07-20 16:23:013858TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHangupDuringBody) {
mmenkee71e15332015-10-07 16:39:543859 HttpRequestInfo request;
3860 request.method = "GET";
3861 request.url = GURL("https://www.example.org/");
3862 // Ensure that proxy authentication is attempted even
3863 // when the no authentication data flag is set.
3864 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103865 request.traffic_annotation =
3866 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenkee71e15332015-10-07 16:39:543867
3868 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:493869 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
3870 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:093871 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenkee71e15332015-10-07 16:39:543872
bnc691fda62016-08-12 00:43:163873 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkee71e15332015-10-07 16:39:543874
3875 // Since we have proxy, should try to establish tunnel.
3876 MockWrite data_writes1[] = {
3877 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173878 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543879 "Proxy-Connection: keep-alive\r\n\r\n"),
3880 };
3881
3882 // The proxy responds to the connect with a 407, using a persistent
3883 // connection.
3884 MockRead data_reads1[] = {
3885 // No credentials.
3886 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3887 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3888 MockRead("Content-Length: 10\r\n\r\n"), MockRead("spam!"),
3889 // Server hands up in the middle of the body.
3890 MockRead(ASYNC, ERR_CONNECTION_CLOSED),
3891 };
3892
3893 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:163894 // After calling trans.RestartWithAuth(), this is the request we should
mmenkee71e15332015-10-07 16:39:543895 // be issuing -- the final header line contains the credentials.
3896 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173897 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543898 "Proxy-Connection: keep-alive\r\n"
3899 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3900
3901 MockWrite("GET / HTTP/1.1\r\n"
3902 "Host: www.example.org\r\n"
3903 "Connection: keep-alive\r\n\r\n"),
3904 };
3905
3906 MockRead data_reads2[] = {
3907 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3908
3909 MockRead("HTTP/1.1 200 OK\r\n"),
3910 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3911 MockRead("Content-Length: 5\r\n\r\n"),
3912 MockRead(SYNCHRONOUS, "hello"),
3913 };
3914
Ryan Sleevib8d7ea02018-05-07 20:01:013915 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenkee71e15332015-10-07 16:39:543916 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:013917 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenkee71e15332015-10-07 16:39:543918 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3919 SSLSocketDataProvider ssl(ASYNC, OK);
3920 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3921
3922 TestCompletionCallback callback;
3923
tfarina42834112016-09-22 13:38:203924 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013925 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543926
bnc691fda62016-08-12 00:43:163927 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543928 ASSERT_TRUE(response);
3929 ASSERT_TRUE(response->headers);
3930 EXPECT_TRUE(response->headers->IsKeepAlive());
3931 EXPECT_EQ(407, response->headers->response_code());
3932 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3933
bnc691fda62016-08-12 00:43:163934 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
robpercival214763f2016-07-01 23:27:013935 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543936
bnc691fda62016-08-12 00:43:163937 response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543938 ASSERT_TRUE(response);
3939 ASSERT_TRUE(response->headers);
3940 EXPECT_TRUE(response->headers->IsKeepAlive());
3941 EXPECT_EQ(200, response->headers->response_code());
3942 std::string body;
bnc691fda62016-08-12 00:43:163943 EXPECT_THAT(ReadTransaction(&trans, &body), IsOk());
mmenkee71e15332015-10-07 16:39:543944 EXPECT_EQ("hello", body);
3945}
3946
[email protected]a8e9b162009-03-12 00:06:443947// Test that we don't read the response body when we fail to establish a tunnel,
3948// even if the user cancels the proxy's auth attempt.
bncd16676a2016-07-20 16:23:013949TEST_F(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:273950 HttpRequestInfo request;
3951 request.method = "GET";
bncce36dca22015-04-21 22:11:233952 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:103953 request.traffic_annotation =
3954 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:273955
[email protected]a8e9b162009-03-12 00:06:443956 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:493957 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
3958 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]a8e9b162009-03-12 00:06:443959
danakj1fd259a02016-04-16 03:17:093960 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:443961
bnc691fda62016-08-12 00:43:163962 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a8e9b162009-03-12 00:06:443963
[email protected]a8e9b162009-03-12 00:06:443964 // Since we have proxy, should try to establish tunnel.
3965 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173966 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3967 "Host: www.example.org:443\r\n"
3968 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:443969 };
3970
3971 // The proxy responds to the connect with a 407.
3972 MockRead data_reads[] = {
ttuttle7933c112015-01-06 00:55:243973 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3974 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3975 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233976 MockRead("0123456789"),
ttuttle7933c112015-01-06 00:55:243977 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]a8e9b162009-03-12 00:06:443978 };
3979
Ryan Sleevib8d7ea02018-05-07 20:01:013980 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:073981 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:443982
[email protected]49639fa2011-12-20 23:22:413983 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:443984
tfarina42834112016-09-22 13:38:203985 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013986 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a8e9b162009-03-12 00:06:443987
3988 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013989 EXPECT_THAT(rv, IsOk());
[email protected]a8e9b162009-03-12 00:06:443990
bnc691fda62016-08-12 00:43:163991 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243992 ASSERT_TRUE(response);
3993 ASSERT_TRUE(response->headers);
[email protected]a8e9b162009-03-12 00:06:443994 EXPECT_TRUE(response->headers->IsKeepAlive());
3995 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423996 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:443997
3998 std::string response_data;
bnc691fda62016-08-12 00:43:163999 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:014000 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]e60e47a2010-07-14 03:37:184001
4002 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:314003 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:444004}
4005
ttuttle7933c112015-01-06 00:55:244006// Test that we don't pass extraneous headers from the proxy's response to the
4007// caller when the proxy responds to CONNECT with 407.
bncd16676a2016-07-20 16:23:014008TEST_F(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
ttuttle7933c112015-01-06 00:55:244009 HttpRequestInfo request;
4010 request.method = "GET";
bncce36dca22015-04-21 22:11:234011 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104012 request.traffic_annotation =
4013 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle7933c112015-01-06 00:55:244014
4015 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:494016 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
4017 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle7933c112015-01-06 00:55:244018
danakj1fd259a02016-04-16 03:17:094019 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle7933c112015-01-06 00:55:244020
bnc691fda62016-08-12 00:43:164021 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle7933c112015-01-06 00:55:244022
4023 // Since we have proxy, should try to establish tunnel.
4024 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:174025 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4026 "Host: www.example.org:443\r\n"
4027 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle7933c112015-01-06 00:55:244028 };
4029
4030 // The proxy responds to the connect with a 407.
4031 MockRead data_reads[] = {
4032 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4033 MockRead("X-Foo: bar\r\n"),
4034 MockRead("Set-Cookie: foo=bar\r\n"),
4035 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4036 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:234037 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
ttuttle7933c112015-01-06 00:55:244038 };
4039
Ryan Sleevib8d7ea02018-05-07 20:01:014040 StaticSocketDataProvider data(data_reads, data_writes);
ttuttle7933c112015-01-06 00:55:244041 session_deps_.socket_factory->AddSocketDataProvider(&data);
4042
4043 TestCompletionCallback callback;
4044
tfarina42834112016-09-22 13:38:204045 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014046 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle7933c112015-01-06 00:55:244047
4048 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:014049 EXPECT_THAT(rv, IsOk());
ttuttle7933c112015-01-06 00:55:244050
bnc691fda62016-08-12 00:43:164051 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:244052 ASSERT_TRUE(response);
4053 ASSERT_TRUE(response->headers);
4054 EXPECT_TRUE(response->headers->IsKeepAlive());
4055 EXPECT_EQ(407, response->headers->response_code());
4056 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4057 EXPECT_FALSE(response->headers->HasHeader("X-Foo"));
4058 EXPECT_FALSE(response->headers->HasHeader("Set-Cookie"));
4059
4060 std::string response_data;
bnc691fda62016-08-12 00:43:164061 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:014062 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
ttuttle7933c112015-01-06 00:55:244063
4064 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
4065 session->CloseAllConnections();
4066}
4067
[email protected]8fdbcd22010-05-05 02:54:524068// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
4069// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
bncd16676a2016-07-20 16:23:014070TEST_F(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:524071 HttpRequestInfo request;
4072 request.method = "GET";
bncce36dca22015-04-21 22:11:234073 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104074 request.traffic_annotation =
4075 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8fdbcd22010-05-05 02:54:524076
[email protected]cb9bf6ca2011-01-28 13:15:274077 // We are using a DIRECT connection (i.e. no proxy) for this session.
danakj1fd259a02016-04-16 03:17:094078 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:164079 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:274080
[email protected]8fdbcd22010-05-05 02:54:524081 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:234082 MockWrite(
4083 "GET / HTTP/1.1\r\n"
4084 "Host: www.example.org\r\n"
4085 "Connection: keep-alive\r\n\r\n"),
[email protected]8fdbcd22010-05-05 02:54:524086 };
4087
4088 MockRead data_reads1[] = {
4089 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
4090 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4091 // Large content-length -- won't matter, as connection will be reset.
4092 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064093 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:524094 };
4095
Ryan Sleevib8d7ea02018-05-07 20:01:014096 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:074097 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:524098
[email protected]49639fa2011-12-20 23:22:414099 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:524100
tfarina42834112016-09-22 13:38:204101 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014102 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8fdbcd22010-05-05 02:54:524103
4104 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:014105 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
[email protected]8fdbcd22010-05-05 02:54:524106}
4107
[email protected]7a67a8152010-11-05 18:31:104108// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
4109// through a non-authenticating proxy. The request should fail with
4110// ERR_UNEXPECTED_PROXY_AUTH.
4111// Note that it is impossible to detect if an HTTP server returns a 407 through
4112// a non-authenticating proxy - there is nothing to indicate whether the
4113// response came from the proxy or the server, so it is treated as if the proxy
4114// issued the challenge.
bncd16676a2016-07-20 16:23:014115TEST_F(HttpNetworkTransactionTest, HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:274116 HttpRequestInfo request;
4117 request.method = "GET";
bncce36dca22015-04-21 22:11:234118 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104119 request.traffic_annotation =
4120 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:274121
Ramin Halavatica8d5252018-03-12 05:33:494122 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
4123 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:514124 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074125 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094126 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:104127
[email protected]7a67a8152010-11-05 18:31:104128 // Since we have proxy, should try to establish tunnel.
4129 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174130 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4131 "Host: www.example.org:443\r\n"
4132 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:104133
rsleevidb16bb02015-11-12 23:47:174134 MockWrite("GET / HTTP/1.1\r\n"
4135 "Host: www.example.org\r\n"
4136 "Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:104137 };
4138
4139 MockRead data_reads1[] = {
4140 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4141
4142 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
4143 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4144 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:064145 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:104146 };
4147
Ryan Sleevib8d7ea02018-05-07 20:01:014148 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:074149 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:064150 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074151 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:104152
[email protected]49639fa2011-12-20 23:22:414153 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:104154
bnc691fda62016-08-12 00:43:164155 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]7a67a8152010-11-05 18:31:104156
bnc691fda62016-08-12 00:43:164157 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014158 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a67a8152010-11-05 18:31:104159
4160 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014161 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
mmenke43758e62015-05-04 21:09:464162 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:404163 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:104164 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:004165 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
4166 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:104167 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:404168 entries, pos,
mikecirone8b85c432016-09-08 19:11:004169 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
4170 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:104171}
[email protected]2df19bb2010-08-25 20:13:464172
mmenke2a1781d2015-10-07 19:25:334173// Test a proxy auth scheme that allows default credentials and a proxy server
4174// that uses non-persistent connections.
bncd16676a2016-07-20 16:23:014175TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334176 AuthAllowsDefaultCredentialsTunnelConnectionClose) {
4177 HttpRequestInfo request;
4178 request.method = "GET";
4179 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104180 request.traffic_annotation =
4181 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334182
4183 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594184 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494185 ProxyResolutionService::CreateFixedFromPacResult(
4186 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334187
Jeremy Roman0579ed62017-08-29 15:56:194188 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334189 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194190 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334191 mock_handler->set_allows_default_credentials(true);
4192 auth_handler_factory->AddMockHandler(mock_handler.release(),
4193 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484194 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334195
4196 // Add NetLog just so can verify load timing information gets a NetLog ID.
4197 NetLog net_log;
4198 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094199 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334200
4201 // Since we have proxy, should try to establish tunnel.
4202 MockWrite data_writes1[] = {
4203 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174204 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334205 "Proxy-Connection: keep-alive\r\n\r\n"),
4206 };
4207
4208 // The proxy responds to the connect with a 407, using a non-persistent
4209 // connection.
4210 MockRead data_reads1[] = {
4211 // No credentials.
4212 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4213 MockRead("Proxy-Authenticate: Mock\r\n"),
4214 MockRead("Proxy-Connection: close\r\n\r\n"),
4215 };
4216
4217 // Since the first connection couldn't be reused, need to establish another
4218 // once given credentials.
4219 MockWrite data_writes2[] = {
4220 // After calling trans->RestartWithAuth(), this is the request we should
4221 // be issuing -- the final header line contains the credentials.
4222 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174223 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334224 "Proxy-Connection: keep-alive\r\n"
4225 "Proxy-Authorization: auth_token\r\n\r\n"),
4226
4227 MockWrite("GET / HTTP/1.1\r\n"
4228 "Host: www.example.org\r\n"
4229 "Connection: keep-alive\r\n\r\n"),
4230 };
4231
4232 MockRead data_reads2[] = {
4233 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
4234
4235 MockRead("HTTP/1.1 200 OK\r\n"),
4236 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4237 MockRead("Content-Length: 5\r\n\r\n"),
4238 MockRead(SYNCHRONOUS, "hello"),
4239 };
4240
Ryan Sleevib8d7ea02018-05-07 20:01:014241 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke2a1781d2015-10-07 19:25:334242 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:014243 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke2a1781d2015-10-07 19:25:334244 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4245 SSLSocketDataProvider ssl(ASYNC, OK);
4246 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4247
bnc87dcefc2017-05-25 12:47:584248 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194249 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334250
4251 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204252 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014253 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334254
4255 const HttpResponseInfo* response = trans->GetResponseInfo();
4256 ASSERT_TRUE(response);
4257 ASSERT_TRUE(response->headers);
4258 EXPECT_FALSE(response->headers->IsKeepAlive());
4259 EXPECT_EQ(407, response->headers->response_code());
4260 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4261 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
wezca1070932016-05-26 20:30:524262 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:334263
4264 LoadTimingInfo load_timing_info;
4265 // CONNECT requests and responses are handled at the connect job level, so
4266 // the transaction does not yet have a connection.
4267 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4268
4269 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014270 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334271 response = trans->GetResponseInfo();
4272 ASSERT_TRUE(response);
4273 ASSERT_TRUE(response->headers);
4274 EXPECT_TRUE(response->headers->IsKeepAlive());
4275 EXPECT_EQ(200, response->headers->response_code());
4276 EXPECT_EQ(5, response->headers->GetContentLength());
4277 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4278
4279 // The password prompt info should not be set.
4280 EXPECT_FALSE(response->auth_challenge);
4281
4282 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4283 TestLoadTimingNotReusedWithPac(load_timing_info,
4284 CONNECT_TIMING_HAS_SSL_TIMES);
4285
4286 trans.reset();
4287 session->CloseAllConnections();
4288}
4289
4290// Test a proxy auth scheme that allows default credentials and a proxy server
4291// that hangs up when credentials are initially sent.
bncd16676a2016-07-20 16:23:014292TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334293 AuthAllowsDefaultCredentialsTunnelServerClosesConnection) {
4294 HttpRequestInfo request;
4295 request.method = "GET";
4296 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104297 request.traffic_annotation =
4298 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334299
4300 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594301 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494302 ProxyResolutionService::CreateFixedFromPacResult(
4303 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334304
Jeremy Roman0579ed62017-08-29 15:56:194305 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334306 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194307 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334308 mock_handler->set_allows_default_credentials(true);
4309 auth_handler_factory->AddMockHandler(mock_handler.release(),
4310 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484311 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334312
4313 // Add NetLog just so can verify load timing information gets a NetLog ID.
4314 NetLog net_log;
4315 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094316 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334317
4318 // Should try to establish tunnel.
4319 MockWrite data_writes1[] = {
4320 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174321 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334322 "Proxy-Connection: keep-alive\r\n\r\n"),
4323
4324 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174325 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334326 "Proxy-Connection: keep-alive\r\n"
4327 "Proxy-Authorization: auth_token\r\n\r\n"),
4328 };
4329
4330 // The proxy responds to the connect with a 407, using a non-persistent
4331 // connection.
4332 MockRead data_reads1[] = {
4333 // No credentials.
4334 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4335 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4336 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4337 };
4338
4339 // Since the first connection was closed, need to establish another once given
4340 // credentials.
4341 MockWrite data_writes2[] = {
4342 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174343 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334344 "Proxy-Connection: keep-alive\r\n"
4345 "Proxy-Authorization: auth_token\r\n\r\n"),
4346
4347 MockWrite("GET / HTTP/1.1\r\n"
4348 "Host: www.example.org\r\n"
4349 "Connection: keep-alive\r\n\r\n"),
4350 };
4351
4352 MockRead data_reads2[] = {
4353 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
4354
4355 MockRead("HTTP/1.1 200 OK\r\n"),
4356 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4357 MockRead("Content-Length: 5\r\n\r\n"),
4358 MockRead(SYNCHRONOUS, "hello"),
4359 };
4360
Ryan Sleevib8d7ea02018-05-07 20:01:014361 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke2a1781d2015-10-07 19:25:334362 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:014363 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke2a1781d2015-10-07 19:25:334364 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4365 SSLSocketDataProvider ssl(ASYNC, OK);
4366 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4367
bnc87dcefc2017-05-25 12:47:584368 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194369 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334370
4371 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204372 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014373 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334374
4375 const HttpResponseInfo* response = trans->GetResponseInfo();
4376 ASSERT_TRUE(response);
4377 ASSERT_TRUE(response->headers);
4378 EXPECT_TRUE(response->headers->IsKeepAlive());
4379 EXPECT_EQ(407, response->headers->response_code());
4380 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4381 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4382 EXPECT_FALSE(response->auth_challenge);
4383
4384 LoadTimingInfo load_timing_info;
4385 // CONNECT requests and responses are handled at the connect job level, so
4386 // the transaction does not yet have a connection.
4387 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4388
4389 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014390 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334391
4392 response = trans->GetResponseInfo();
4393 ASSERT_TRUE(response);
4394 ASSERT_TRUE(response->headers);
4395 EXPECT_TRUE(response->headers->IsKeepAlive());
4396 EXPECT_EQ(200, response->headers->response_code());
4397 EXPECT_EQ(5, response->headers->GetContentLength());
4398 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4399
4400 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524401 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:334402
4403 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4404 TestLoadTimingNotReusedWithPac(load_timing_info,
4405 CONNECT_TIMING_HAS_SSL_TIMES);
4406
4407 trans.reset();
4408 session->CloseAllConnections();
4409}
4410
4411// Test a proxy auth scheme that allows default credentials and a proxy server
4412// that hangs up when credentials are initially sent, and hangs up again when
4413// they are retried.
bncd16676a2016-07-20 16:23:014414TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334415 AuthAllowsDefaultCredentialsTunnelServerClosesConnectionTwice) {
4416 HttpRequestInfo request;
4417 request.method = "GET";
4418 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104419 request.traffic_annotation =
4420 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334421
4422 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594423 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494424 ProxyResolutionService::CreateFixedFromPacResult(
4425 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334426
Jeremy Roman0579ed62017-08-29 15:56:194427 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334428 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194429 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334430 mock_handler->set_allows_default_credentials(true);
4431 auth_handler_factory->AddMockHandler(mock_handler.release(),
4432 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484433 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334434
4435 // Add NetLog just so can verify load timing information gets a NetLog ID.
4436 NetLog net_log;
4437 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094438 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334439
4440 // Should try to establish tunnel.
4441 MockWrite data_writes1[] = {
4442 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174443 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334444 "Proxy-Connection: keep-alive\r\n\r\n"),
4445
4446 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174447 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334448 "Proxy-Connection: keep-alive\r\n"
4449 "Proxy-Authorization: auth_token\r\n\r\n"),
4450 };
4451
4452 // The proxy responds to the connect with a 407, and then hangs up after the
4453 // second request is sent.
4454 MockRead data_reads1[] = {
4455 // No credentials.
4456 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4457 MockRead("Content-Length: 0\r\n"),
4458 MockRead("Proxy-Connection: keep-alive\r\n"),
4459 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4460 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4461 };
4462
4463 // HttpNetworkTransaction sees a reused connection that was closed with
4464 // ERR_CONNECTION_CLOSED, realized it might have been a race, so retries the
4465 // request.
4466 MockWrite data_writes2[] = {
4467 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174468 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334469 "Proxy-Connection: keep-alive\r\n\r\n"),
4470 };
4471
4472 // The proxy, having had more than enough of us, just hangs up.
4473 MockRead data_reads2[] = {
4474 // No credentials.
4475 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4476 };
4477
Ryan Sleevib8d7ea02018-05-07 20:01:014478 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke2a1781d2015-10-07 19:25:334479 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:014480 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke2a1781d2015-10-07 19:25:334481 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4482
bnc87dcefc2017-05-25 12:47:584483 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194484 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334485
4486 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204487 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014488 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334489
4490 const HttpResponseInfo* response = trans->GetResponseInfo();
4491 ASSERT_TRUE(response);
4492 ASSERT_TRUE(response->headers);
4493 EXPECT_TRUE(response->headers->IsKeepAlive());
4494 EXPECT_EQ(407, response->headers->response_code());
4495 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4496 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4497 EXPECT_FALSE(response->auth_challenge);
4498
4499 LoadTimingInfo load_timing_info;
4500 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4501
4502 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014503 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_EMPTY_RESPONSE));
mmenke2a1781d2015-10-07 19:25:334504
4505 trans.reset();
4506 session->CloseAllConnections();
4507}
4508
Asanka Herathbc3f8f62018-11-16 23:08:304509// This test exercises an odd edge case where the proxy closes the connection
4510// after the authentication handshake is complete. Presumably this technique is
4511// used in lieu of returning a 403 or 5xx status code when the authentication
4512// succeeds, but the user is not authorized to connect to the destination
4513// server. There's no standard for what a proxy should do to indicate a blocked
4514// site.
4515TEST_F(HttpNetworkTransactionTest,
4516 AuthAllowsDefaultCredentialsTunnelConnectionClosesBeforeBody) {
4517 HttpRequestInfo request;
4518 request.method = "GET";
4519 request.url = GURL("https://www.example.org/");
4520 request.traffic_annotation =
4521 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4522
4523 // Configure against proxy server "myproxy:70".
4524 session_deps_.proxy_resolution_service =
4525 ProxyResolutionService::CreateFixedFromPacResult(
4526 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
4527
Steven Valdez0ef94d02018-11-19 23:28:134528 // When TLS 1.3 is enabled, spurious connections are made as part of the SSL
4529 // version interference probes.
4530 // TODO(crbug.com/906668): Correctly handle version interference probes to
4531 // test TLS 1.3.
4532 SSLConfig config;
4533 config.version_max = SSL_PROTOCOL_VERSION_TLS1_2;
4534 session_deps_.ssl_config_service =
4535 std::make_unique<TestSSLConfigService>(config);
4536
Asanka Herathbc3f8f62018-11-16 23:08:304537 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
4538 auth_handler_factory->set_do_init_from_challenge(true);
4539
4540 // Create two mock AuthHandlers. This is because the transaction gets retried
4541 // after the first ERR_CONNECTION_CLOSED since it's ambiguous whether there
4542 // was a real network error.
4543 //
4544 // The handlers support both default and explicit credentials. The retry
4545 // mentioned above should be able to reuse the default identity. Thus there
4546 // should never be a need to prompt for explicit credentials.
4547 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
4548 mock_handler->set_allows_default_credentials(true);
4549 mock_handler->set_allows_explicit_credentials(true);
4550 mock_handler->set_connection_based(true);
4551 auth_handler_factory->AddMockHandler(mock_handler.release(),
4552 HttpAuth::AUTH_PROXY);
4553 mock_handler = std::make_unique<HttpAuthHandlerMock>();
4554 mock_handler->set_allows_default_credentials(true);
4555 mock_handler->set_allows_explicit_credentials(true);
4556 mock_handler->set_connection_based(true);
4557 auth_handler_factory->AddMockHandler(mock_handler.release(),
4558 HttpAuth::AUTH_PROXY);
4559 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
4560
4561 NetLog net_log;
4562 session_deps_.net_log = &net_log;
4563 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4564
4565 // Data for both sockets.
4566 //
4567 // Writes are for the tunnel establishment attempts and the
4568 // authentication handshake.
4569 MockWrite data_writes1[] = {
4570 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4571 "Host: www.example.org:443\r\n"
4572 "Proxy-Connection: keep-alive\r\n\r\n"),
4573
4574 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4575 "Host: www.example.org:443\r\n"
4576 "Proxy-Connection: keep-alive\r\n"
4577 "Proxy-Authorization: auth_token\r\n\r\n"),
4578
4579 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4580 "Host: www.example.org:443\r\n"
4581 "Proxy-Connection: keep-alive\r\n"
4582 "Proxy-Authorization: auth_token\r\n\r\n"),
4583 };
4584
4585 // The server side of the authentication handshake. Note that the response to
4586 // the final CONNECT request is ERR_CONNECTION_CLOSED.
4587 MockRead data_reads1[] = {
4588 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4589 MockRead("Content-Length: 0\r\n"),
4590 MockRead("Proxy-Connection: keep-alive\r\n"),
4591 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4592
4593 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4594 MockRead("Content-Length: 0\r\n"),
4595 MockRead("Proxy-Connection: keep-alive\r\n"),
4596 MockRead("Proxy-Authenticate: Mock foo\r\n\r\n"),
4597
4598 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4599 };
4600
4601 StaticSocketDataProvider data1(data_reads1, data_writes1);
4602 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4603
4604 // The second socket is for the reconnection attempt. Data is identical to the
4605 // first attempt.
4606 StaticSocketDataProvider data2(data_reads1, data_writes1);
4607 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4608
4609 auto trans =
4610 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
4611
4612 TestCompletionCallback callback;
4613 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4614
4615 // Two rounds per handshake. After one retry, the error is propagated up the
4616 // stack.
4617 for (int i = 0; i < 4; ++i) {
4618 EXPECT_THAT(callback.GetResult(rv), IsOk());
4619
4620 const HttpResponseInfo* response = trans->GetResponseInfo();
4621 ASSERT_TRUE(response);
4622 ASSERT_TRUE(response->headers);
4623 EXPECT_EQ(407, response->headers->response_code());
4624 ASSERT_TRUE(trans->IsReadyToRestartForAuth());
4625
4626 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4627 }
4628
4629 // One shall be the number thou shalt retry, and the number of the retrying
4630 // shall be one. Two shalt thou not retry, neither retry thou zero, excepting
4631 // that thou then proceed to one. Three is right out. Once the number one,
4632 // being the first number, be reached, then lobbest thou thy
4633 // ERR_CONNECTION_CLOSED towards they network transaction, who shall snuff it.
4634 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.GetResult(rv));
4635
4636 trans.reset();
4637 session->CloseAllConnections();
4638}
4639
mmenke2a1781d2015-10-07 19:25:334640// Test a proxy auth scheme that allows default credentials and a proxy server
4641// that hangs up when credentials are initially sent, and sends a challenge
4642// again they are retried.
bncd16676a2016-07-20 16:23:014643TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334644 AuthAllowsDefaultCredentialsTunnelServerChallengesTwice) {
4645 HttpRequestInfo request;
4646 request.method = "GET";
4647 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104648 request.traffic_annotation =
4649 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334650
4651 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594652 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494653 ProxyResolutionService::CreateFixedFromPacResult(
4654 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334655
Jeremy Roman0579ed62017-08-29 15:56:194656 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334657 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194658 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334659 mock_handler->set_allows_default_credentials(true);
4660 auth_handler_factory->AddMockHandler(mock_handler.release(),
4661 HttpAuth::AUTH_PROXY);
4662 // Add another handler for the second challenge. It supports default
4663 // credentials, but they shouldn't be used, since they were already tried.
Jeremy Roman0579ed62017-08-29 15:56:194664 mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334665 mock_handler->set_allows_default_credentials(true);
4666 auth_handler_factory->AddMockHandler(mock_handler.release(),
4667 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484668 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334669
4670 // Add NetLog just so can verify load timing information gets a NetLog ID.
4671 NetLog net_log;
4672 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094673 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334674
4675 // Should try to establish tunnel.
4676 MockWrite data_writes1[] = {
4677 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174678 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334679 "Proxy-Connection: keep-alive\r\n\r\n"),
4680 };
4681
4682 // The proxy responds to the connect with a 407, using a non-persistent
4683 // connection.
4684 MockRead data_reads1[] = {
4685 // No credentials.
4686 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4687 MockRead("Proxy-Authenticate: Mock\r\n"),
4688 MockRead("Proxy-Connection: close\r\n\r\n"),
4689 };
4690
4691 // Since the first connection was closed, need to establish another once given
4692 // credentials.
4693 MockWrite data_writes2[] = {
4694 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174695 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334696 "Proxy-Connection: keep-alive\r\n"
4697 "Proxy-Authorization: auth_token\r\n\r\n"),
4698 };
4699
4700 MockRead data_reads2[] = {
4701 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4702 MockRead("Proxy-Authenticate: Mock\r\n"),
4703 MockRead("Proxy-Connection: close\r\n\r\n"),
4704 };
4705
Ryan Sleevib8d7ea02018-05-07 20:01:014706 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke2a1781d2015-10-07 19:25:334707 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:014708 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke2a1781d2015-10-07 19:25:334709 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4710 SSLSocketDataProvider ssl(ASYNC, OK);
4711 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4712
bnc87dcefc2017-05-25 12:47:584713 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194714 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334715
4716 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204717 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014718 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334719
4720 const HttpResponseInfo* response = trans->GetResponseInfo();
4721 ASSERT_TRUE(response);
4722 ASSERT_TRUE(response->headers);
4723 EXPECT_EQ(407, response->headers->response_code());
4724 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4725 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4726 EXPECT_FALSE(response->auth_challenge);
4727
4728 LoadTimingInfo load_timing_info;
4729 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4730
4731 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014732 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334733 response = trans->GetResponseInfo();
4734 ASSERT_TRUE(response);
4735 ASSERT_TRUE(response->headers);
4736 EXPECT_EQ(407, response->headers->response_code());
4737 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4738 EXPECT_TRUE(response->auth_challenge);
4739
4740 trans.reset();
4741 session->CloseAllConnections();
4742}
4743
asankae2257db2016-10-11 22:03:164744// A more nuanced test than GenerateAuthToken test which asserts that
4745// ERR_INVALID_AUTH_CREDENTIALS does not cause the auth scheme to be
4746// unnecessarily invalidated, and that if the server co-operates, the
4747// authentication handshake can continue with the same scheme but with a
4748// different identity.
4749TEST_F(HttpNetworkTransactionTest, NonPermanentGenerateAuthTokenError) {
4750 HttpRequestInfo request;
4751 request.method = "GET";
4752 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104753 request.traffic_annotation =
4754 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
asankae2257db2016-10-11 22:03:164755
Jeremy Roman0579ed62017-08-29 15:56:194756 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
asankae2257db2016-10-11 22:03:164757 auth_handler_factory->set_do_init_from_challenge(true);
4758
4759 // First handler. Uses default credentials, but barfs at generate auth token.
Jeremy Roman0579ed62017-08-29 15:56:194760 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164761 mock_handler->set_allows_default_credentials(true);
4762 mock_handler->set_allows_explicit_credentials(true);
4763 mock_handler->set_connection_based(true);
4764 mock_handler->SetGenerateExpectation(true, ERR_INVALID_AUTH_CREDENTIALS);
4765 auth_handler_factory->AddMockHandler(mock_handler.release(),
4766 HttpAuth::AUTH_SERVER);
4767
4768 // Add another handler for the second challenge. It supports default
4769 // credentials, but they shouldn't be used, since they were already tried.
Jeremy Roman0579ed62017-08-29 15:56:194770 mock_handler = std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164771 mock_handler->set_allows_default_credentials(true);
4772 mock_handler->set_allows_explicit_credentials(true);
4773 mock_handler->set_connection_based(true);
4774 auth_handler_factory->AddMockHandler(mock_handler.release(),
4775 HttpAuth::AUTH_SERVER);
4776 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
4777
4778 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4779
4780 MockWrite data_writes1[] = {
4781 MockWrite("GET / HTTP/1.1\r\n"
4782 "Host: www.example.org\r\n"
4783 "Connection: keep-alive\r\n\r\n"),
4784 };
4785
4786 MockRead data_reads1[] = {
4787 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4788 "WWW-Authenticate: Mock\r\n"
4789 "Connection: keep-alive\r\n\r\n"),
4790 };
4791
4792 // Identical to data_writes1[]. The AuthHandler encounters a
4793 // ERR_INVALID_AUTH_CREDENTIALS during the GenerateAuthToken stage, so the
4794 // transaction procceds without an authorization header.
4795 MockWrite data_writes2[] = {
4796 MockWrite("GET / HTTP/1.1\r\n"
4797 "Host: www.example.org\r\n"
4798 "Connection: keep-alive\r\n\r\n"),
4799 };
4800
4801 MockRead data_reads2[] = {
4802 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4803 "WWW-Authenticate: Mock\r\n"
4804 "Connection: keep-alive\r\n\r\n"),
4805 };
4806
4807 MockWrite data_writes3[] = {
4808 MockWrite("GET / HTTP/1.1\r\n"
4809 "Host: www.example.org\r\n"
4810 "Connection: keep-alive\r\n"
4811 "Authorization: auth_token\r\n\r\n"),
4812 };
4813
4814 MockRead data_reads3[] = {
4815 MockRead("HTTP/1.1 200 OK\r\n"
4816 "Content-Length: 5\r\n"
4817 "Content-Type: text/plain\r\n"
4818 "Connection: keep-alive\r\n\r\n"
4819 "Hello"),
4820 };
4821
Ryan Sleevib8d7ea02018-05-07 20:01:014822 StaticSocketDataProvider data1(data_reads1, data_writes1);
asankae2257db2016-10-11 22:03:164823 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4824
Ryan Sleevib8d7ea02018-05-07 20:01:014825 StaticSocketDataProvider data2(data_reads2, data_writes2);
asankae2257db2016-10-11 22:03:164826 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4827
Ryan Sleevib8d7ea02018-05-07 20:01:014828 StaticSocketDataProvider data3(data_reads3, data_writes3);
asankae2257db2016-10-11 22:03:164829 session_deps_.socket_factory->AddSocketDataProvider(&data3);
4830
bnc87dcefc2017-05-25 12:47:584831 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194832 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
asankae2257db2016-10-11 22:03:164833
4834 TestCompletionCallback callback;
4835 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4836 EXPECT_THAT(callback.GetResult(rv), IsOk());
4837
4838 const HttpResponseInfo* response = trans->GetResponseInfo();
4839 ASSERT_TRUE(response);
4840 ASSERT_TRUE(response->headers);
4841 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4842
4843 // The following three tests assert that an authentication challenge was
4844 // received and that the stack is ready to respond to the challenge using
4845 // ambient credentials.
4846 EXPECT_EQ(401, response->headers->response_code());
4847 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4848 EXPECT_FALSE(response->auth_challenge);
4849
4850 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4851 EXPECT_THAT(callback.GetResult(rv), IsOk());
4852 response = trans->GetResponseInfo();
4853 ASSERT_TRUE(response);
4854 ASSERT_TRUE(response->headers);
4855
4856 // The following three tests assert that an authentication challenge was
4857 // received and that the stack needs explicit credentials before it is ready
4858 // to respond to the challenge.
4859 EXPECT_EQ(401, response->headers->response_code());
4860 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4861 EXPECT_TRUE(response->auth_challenge);
4862
4863 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4864 EXPECT_THAT(callback.GetResult(rv), IsOk());
4865 response = trans->GetResponseInfo();
4866 ASSERT_TRUE(response);
4867 ASSERT_TRUE(response->headers);
4868 EXPECT_EQ(200, response->headers->response_code());
4869
4870 trans.reset();
4871 session->CloseAllConnections();
4872}
4873
Matt Menked1eb6d42018-01-17 04:54:064874// Proxy resolver that returns a proxy with the same host and port for different
4875// schemes, based on the path of the URL being requests.
4876class SameProxyWithDifferentSchemesProxyResolver : public ProxyResolver {
4877 public:
4878 SameProxyWithDifferentSchemesProxyResolver() {}
4879 ~SameProxyWithDifferentSchemesProxyResolver() override {}
4880
4881 static std::string ProxyHostPortPairAsString() { return "proxy.test:10000"; }
4882
4883 static HostPortPair ProxyHostPortPair() {
4884 return HostPortPair::FromString(ProxyHostPortPairAsString());
4885 }
4886
4887 // ProxyResolver implementation.
4888 int GetProxyForURL(const GURL& url,
4889 ProxyInfo* results,
Bence Békycc5b88a2018-05-25 20:24:174890 CompletionOnceCallback callback,
Matt Menked1eb6d42018-01-17 04:54:064891 std::unique_ptr<Request>* request,
4892 const NetLogWithSource& /*net_log*/) override {
4893 *results = ProxyInfo();
Ramin Halavati921731ea2018-03-16 08:24:574894 results->set_traffic_annotation(
4895 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
Matt Menked1eb6d42018-01-17 04:54:064896 if (url.path() == "/socks4") {
4897 results->UsePacString("SOCKS " + ProxyHostPortPairAsString());
4898 return OK;
4899 }
4900 if (url.path() == "/socks5") {
4901 results->UsePacString("SOCKS5 " + ProxyHostPortPairAsString());
4902 return OK;
4903 }
4904 if (url.path() == "/http") {
4905 results->UsePacString("PROXY " + ProxyHostPortPairAsString());
4906 return OK;
4907 }
4908 if (url.path() == "/https") {
4909 results->UsePacString("HTTPS " + ProxyHostPortPairAsString());
4910 return OK;
4911 }
Matt Menkee8648fa2019-01-17 16:47:074912 if (url.path() == "/https_trusted") {
4913 results->UseProxyServer(ProxyServer(ProxyServer::SCHEME_HTTPS,
4914 ProxyHostPortPair(),
4915 true /* is_trusted_proxy */));
4916 return OK;
4917 }
Matt Menked1eb6d42018-01-17 04:54:064918 NOTREACHED();
4919 return ERR_NOT_IMPLEMENTED;
4920 }
4921
4922 private:
4923 DISALLOW_COPY_AND_ASSIGN(SameProxyWithDifferentSchemesProxyResolver);
4924};
4925
4926class SameProxyWithDifferentSchemesProxyResolverFactory
4927 : public ProxyResolverFactory {
4928 public:
4929 SameProxyWithDifferentSchemesProxyResolverFactory()
4930 : ProxyResolverFactory(false) {}
4931
Lily Houghton99597862018-03-07 16:40:424932 int CreateProxyResolver(const scoped_refptr<PacFileData>& pac_script,
4933 std::unique_ptr<ProxyResolver>* resolver,
Bence Békycc5b88a2018-05-25 20:24:174934 CompletionOnceCallback callback,
Lily Houghton99597862018-03-07 16:40:424935 std::unique_ptr<Request>* request) override {
Matt Menked1eb6d42018-01-17 04:54:064936 *resolver = std::make_unique<SameProxyWithDifferentSchemesProxyResolver>();
4937 return OK;
4938 }
4939
4940 private:
4941 DISALLOW_COPY_AND_ASSIGN(SameProxyWithDifferentSchemesProxyResolverFactory);
4942};
4943
4944// Check that when different proxy schemes are all applied to a proxy at the
Matt Menkee8648fa2019-01-17 16:47:074945// same address, the connections are not grouped together. i.e., a request to
Matt Menked1eb6d42018-01-17 04:54:064946// foo.com using proxy.com as an HTTPS proxy won't use the same socket as a
4947// request to foo.com using proxy.com as an HTTP proxy.
4948TEST_F(HttpNetworkTransactionTest, SameDestinationForDifferentProxyTypes) {
Ramin Halavatica8d5252018-03-12 05:33:494949 session_deps_.proxy_resolution_service =
4950 std::make_unique<ProxyResolutionService>(
4951 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
4952 ProxyConfig::CreateAutoDetect(), TRAFFIC_ANNOTATION_FOR_TESTS)),
4953 std::make_unique<SameProxyWithDifferentSchemesProxyResolverFactory>(),
4954 nullptr);
Matt Menked1eb6d42018-01-17 04:54:064955
4956 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4957
4958 MockWrite socks_writes[] = {
4959 MockWrite(SYNCHRONOUS, kSOCKS4OkRequestLocalHostPort80,
4960 kSOCKS4OkRequestLocalHostPort80Length),
4961 MockWrite(SYNCHRONOUS,
4962 "GET /socks4 HTTP/1.1\r\n"
4963 "Host: test\r\n"
4964 "Connection: keep-alive\r\n\r\n"),
4965 };
4966 MockRead socks_reads[] = {
4967 MockRead(SYNCHRONOUS, kSOCKS4OkReply, kSOCKS4OkReplyLength),
4968 MockRead("HTTP/1.0 200 OK\r\n"
4969 "Connection: keep-alive\r\n"
4970 "Content-Length: 15\r\n\r\n"
4971 "SOCKS4 Response"),
4972 };
Ryan Sleevib8d7ea02018-05-07 20:01:014973 StaticSocketDataProvider socks_data(socks_reads, socks_writes);
Matt Menked1eb6d42018-01-17 04:54:064974 session_deps_.socket_factory->AddSocketDataProvider(&socks_data);
4975
4976 const char kSOCKS5Request[] = {
4977 0x05, // Version
4978 0x01, // Command (CONNECT)
4979 0x00, // Reserved
4980 0x03, // Address type (DOMAINNAME)
4981 0x04, // Length of domain (4)
4982 't', 'e', 's', 't', // Domain string
4983 0x00, 0x50, // 16-bit port (80)
4984 };
4985 MockWrite socks5_writes[] = {
4986 MockWrite(ASYNC, kSOCKS5GreetRequest, kSOCKS5GreetRequestLength),
Avi Drissman4365a4782018-12-28 19:26:244987 MockWrite(ASYNC, kSOCKS5Request, base::size(kSOCKS5Request)),
Matt Menked1eb6d42018-01-17 04:54:064988 MockWrite(SYNCHRONOUS,
4989 "GET /socks5 HTTP/1.1\r\n"
4990 "Host: test\r\n"
4991 "Connection: keep-alive\r\n\r\n"),
4992 };
4993 MockRead socks5_reads[] = {
4994 MockRead(ASYNC, kSOCKS5GreetResponse, kSOCKS5GreetResponseLength),
4995 MockRead(ASYNC, kSOCKS5OkResponse, kSOCKS5OkResponseLength),
4996 MockRead("HTTP/1.0 200 OK\r\n"
4997 "Connection: keep-alive\r\n"
4998 "Content-Length: 15\r\n\r\n"
4999 "SOCKS5 Response"),
5000 };
Ryan Sleevib8d7ea02018-05-07 20:01:015001 StaticSocketDataProvider socks5_data(socks5_reads, socks5_writes);
Matt Menked1eb6d42018-01-17 04:54:065002 session_deps_.socket_factory->AddSocketDataProvider(&socks5_data);
5003
5004 MockWrite http_writes[] = {
5005 MockWrite(SYNCHRONOUS,
5006 "GET http://test/http HTTP/1.1\r\n"
5007 "Host: test\r\n"
5008 "Proxy-Connection: keep-alive\r\n\r\n"),
5009 };
5010 MockRead http_reads[] = {
5011 MockRead("HTTP/1.1 200 OK\r\n"
5012 "Proxy-Connection: keep-alive\r\n"
5013 "Content-Length: 13\r\n\r\n"
5014 "HTTP Response"),
5015 };
Ryan Sleevib8d7ea02018-05-07 20:01:015016 StaticSocketDataProvider http_data(http_reads, http_writes);
Matt Menked1eb6d42018-01-17 04:54:065017 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
5018
5019 MockWrite https_writes[] = {
5020 MockWrite(SYNCHRONOUS,
5021 "GET http://test/https HTTP/1.1\r\n"
5022 "Host: test\r\n"
5023 "Proxy-Connection: keep-alive\r\n\r\n"),
5024 };
5025 MockRead https_reads[] = {
5026 MockRead("HTTP/1.1 200 OK\r\n"
5027 "Proxy-Connection: keep-alive\r\n"
5028 "Content-Length: 14\r\n\r\n"
5029 "HTTPS Response"),
5030 };
Ryan Sleevib8d7ea02018-05-07 20:01:015031 StaticSocketDataProvider https_data(https_reads, https_writes);
Matt Menked1eb6d42018-01-17 04:54:065032 session_deps_.socket_factory->AddSocketDataProvider(&https_data);
5033 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
5034 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5035
Matt Menkee8648fa2019-01-17 16:47:075036 MockWrite https_trusted_writes[] = {
5037 MockWrite(SYNCHRONOUS,
5038 "GET http://test/https_trusted HTTP/1.1\r\n"
5039 "Host: test\r\n"
5040 "Proxy-Connection: keep-alive\r\n\r\n"),
5041 };
5042 MockRead https_trusted_reads[] = {
5043 MockRead("HTTP/1.1 200 OK\r\n"
5044 "Proxy-Connection: keep-alive\r\n"
5045 "Content-Length: 22\r\n\r\n"
5046 "HTTPS Trusted Response"),
5047 };
5048 StaticSocketDataProvider trusted_https_data(https_trusted_reads,
5049 https_trusted_writes);
5050 session_deps_.socket_factory->AddSocketDataProvider(&trusted_https_data);
5051 SSLSocketDataProvider ssl2(SYNCHRONOUS, OK);
5052 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
5053
Matt Menked1eb6d42018-01-17 04:54:065054 struct TestCase {
5055 GURL url;
5056 std::string expected_response;
Matt Menkee8648fa2019-01-17 16:47:075057 // How many idle sockets there should be in the SOCKS 4/5 proxy socket pools
Matt Menked1eb6d42018-01-17 04:54:065058 // after the test.
Matt Menkee8648fa2019-01-17 16:47:075059 int expected_idle_socks4_sockets;
5060 int expected_idle_socks5_sockets;
5061 // How many idle sockets there should be in the HTTP/HTTPS proxy socket
5062 // pools after the test.
Matt Menked1eb6d42018-01-17 04:54:065063 int expected_idle_http_sockets;
Matt Menkee8648fa2019-01-17 16:47:075064 int expected_idle_https_sockets;
5065 // How many idle sockets there should be in the HTTPS proxy socket pool with
5066 // the ProxyServer's |is_trusted_proxy| bit set after the test.
5067 int expected_idle_trusted_https_sockets;
Matt Menked1eb6d42018-01-17 04:54:065068 } const kTestCases[] = {
Matt Menkee8648fa2019-01-17 16:47:075069 {GURL("http://test/socks4"), "SOCKS4 Response", 1, 0, 0, 0, 0},
5070 {GURL("http://test/socks5"), "SOCKS5 Response", 1, 1, 0, 0, 0},
5071 {GURL("http://test/http"), "HTTP Response", 1, 1, 1, 0, 0},
5072 {GURL("http://test/https"), "HTTPS Response", 1, 1, 1, 1, 0},
5073 {GURL("http://test/https_trusted"), "HTTPS Trusted Response", 1, 1, 1, 1,
5074 1},
Matt Menked1eb6d42018-01-17 04:54:065075 };
5076
5077 for (const auto& test_case : kTestCases) {
5078 HttpRequestInfo request;
5079 request.method = "GET";
5080 request.url = test_case.url;
Ramin Halavatib5e433e2018-02-07 07:41:105081 request.traffic_annotation =
5082 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Matt Menked1eb6d42018-01-17 04:54:065083 std::unique_ptr<HttpNetworkTransaction> trans =
5084 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
5085 session.get());
5086 TestCompletionCallback callback;
5087 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
5088 EXPECT_THAT(callback.GetResult(rv), IsOk());
5089
5090 const HttpResponseInfo* response = trans->GetResponseInfo();
5091 ASSERT_TRUE(response);
5092 ASSERT_TRUE(response->headers);
5093 EXPECT_EQ(200, response->headers->response_code());
5094 std::string response_data;
5095 EXPECT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
5096 EXPECT_EQ(test_case.expected_response, response_data);
5097
5098 // Return the socket to the socket pool, so can make sure it's not used for
5099 // the next requests.
5100 trans.reset();
5101 base::RunLoop().RunUntilIdle();
5102
5103 // Check the number of idle sockets in the pool, to make sure that used
5104 // sockets are indeed being returned to the socket pool. If each request
5105 // doesn't return an idle socket to the pool, the test would incorrectly
5106 // pass.
Matt Menkee8648fa2019-01-17 16:47:075107 EXPECT_EQ(test_case.expected_idle_socks4_sockets,
5108 session
5109 ->GetSocketPoolForSOCKSProxy(
5110 HttpNetworkSession::NORMAL_SOCKET_POOL,
5111 ProxyServer(ProxyServer::SCHEME_SOCKS4,
5112 SameProxyWithDifferentSchemesProxyResolver::
5113 ProxyHostPortPair()))
5114 ->IdleSocketCount());
5115 EXPECT_EQ(test_case.expected_idle_socks5_sockets,
5116 session
5117 ->GetSocketPoolForSOCKSProxy(
5118 HttpNetworkSession::NORMAL_SOCKET_POOL,
5119 ProxyServer(ProxyServer::SCHEME_SOCKS5,
5120 SameProxyWithDifferentSchemesProxyResolver::
5121 ProxyHostPortPair()))
5122 ->IdleSocketCount());
5123 EXPECT_EQ(test_case.expected_idle_http_sockets,
5124 session
5125 ->GetSocketPoolForHTTPLikeProxy(
5126 HttpNetworkSession::NORMAL_SOCKET_POOL,
5127 ProxyServer(ProxyServer::SCHEME_HTTP,
5128 SameProxyWithDifferentSchemesProxyResolver::
5129 ProxyHostPortPair()))
5130 ->IdleSocketCount());
5131 EXPECT_EQ(test_case.expected_idle_https_sockets,
5132 session
5133 ->GetSocketPoolForHTTPLikeProxy(
5134 HttpNetworkSession::NORMAL_SOCKET_POOL,
5135 ProxyServer(ProxyServer::SCHEME_HTTPS,
5136 SameProxyWithDifferentSchemesProxyResolver::
5137 ProxyHostPortPair()))
5138 ->IdleSocketCount());
5139 EXPECT_EQ(test_case.expected_idle_trusted_https_sockets,
5140 session
5141 ->GetSocketPoolForHTTPLikeProxy(
5142 HttpNetworkSession::NORMAL_SOCKET_POOL,
5143 ProxyServer(ProxyServer::SCHEME_HTTPS,
5144 SameProxyWithDifferentSchemesProxyResolver::
5145 ProxyHostPortPair(),
5146 true /* is_trusted_proxy */))
5147 ->IdleSocketCount());
Matt Menked1eb6d42018-01-17 04:54:065148 }
5149}
5150
[email protected]029c83b62013-01-24 05:28:205151// Test the load timing for HTTPS requests with an HTTP proxy.
bncd16676a2016-07-20 16:23:015152TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:205153 HttpRequestInfo request1;
5154 request1.method = "GET";
bncce36dca22015-04-21 22:11:235155 request1.url = GURL("https://www.example.org/1");
Ramin Halavatib5e433e2018-02-07 07:41:105156 request1.traffic_annotation =
5157 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:205158
5159 HttpRequestInfo request2;
5160 request2.method = "GET";
bncce36dca22015-04-21 22:11:235161 request2.url = GURL("https://www.example.org/2");
Ramin Halavatib5e433e2018-02-07 07:41:105162 request2.traffic_annotation =
5163 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:205164
5165 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495166 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5167 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515168 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075169 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095170 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:205171
5172 // Since we have proxy, should try to establish tunnel.
5173 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:175174 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5175 "Host: www.example.org:443\r\n"
5176 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205177
rsleevidb16bb02015-11-12 23:47:175178 MockWrite("GET /1 HTTP/1.1\r\n"
5179 "Host: www.example.org\r\n"
5180 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205181
rsleevidb16bb02015-11-12 23:47:175182 MockWrite("GET /2 HTTP/1.1\r\n"
5183 "Host: www.example.org\r\n"
5184 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205185 };
5186
5187 // The proxy responds to the connect with a 407, using a persistent
5188 // connection.
5189 MockRead data_reads1[] = {
5190 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
5191
5192 MockRead("HTTP/1.1 200 OK\r\n"),
5193 MockRead("Content-Length: 1\r\n\r\n"),
5194 MockRead(SYNCHRONOUS, "1"),
5195
5196 MockRead("HTTP/1.1 200 OK\r\n"),
5197 MockRead("Content-Length: 2\r\n\r\n"),
5198 MockRead(SYNCHRONOUS, "22"),
5199 };
5200
Ryan Sleevib8d7ea02018-05-07 20:01:015201 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:075202 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:205203 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075204 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:205205
5206 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:585207 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:195208 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:205209
5210 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015211 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:205212
5213 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015214 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:205215
5216 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:525217 ASSERT_TRUE(response1);
tbansal2ecbbc72016-10-06 17:15:475218 EXPECT_TRUE(response1->proxy_server.is_http());
wezca1070932016-05-26 20:30:525219 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:205220 EXPECT_EQ(1, response1->headers->GetContentLength());
5221
5222 LoadTimingInfo load_timing_info1;
5223 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
5224 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
5225
5226 trans1.reset();
5227
5228 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:585229 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:195230 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:205231
5232 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015233 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:205234
5235 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015236 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:205237
5238 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:525239 ASSERT_TRUE(response2);
tbansal2ecbbc72016-10-06 17:15:475240 EXPECT_TRUE(response2->proxy_server.is_http());
wezca1070932016-05-26 20:30:525241 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:205242 EXPECT_EQ(2, response2->headers->GetContentLength());
5243
5244 LoadTimingInfo load_timing_info2;
5245 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5246 TestLoadTimingReused(load_timing_info2);
5247
5248 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
5249
5250 trans2.reset();
5251 session->CloseAllConnections();
5252}
5253
5254// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
bncd16676a2016-07-20 16:23:015255TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:205256 HttpRequestInfo request1;
5257 request1.method = "GET";
bncce36dca22015-04-21 22:11:235258 request1.url = GURL("https://www.example.org/1");
Ramin Halavatib5e433e2018-02-07 07:41:105259 request1.traffic_annotation =
5260 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:205261
5262 HttpRequestInfo request2;
5263 request2.method = "GET";
bncce36dca22015-04-21 22:11:235264 request2.url = GURL("https://www.example.org/2");
Ramin Halavatib5e433e2018-02-07 07:41:105265 request2.traffic_annotation =
5266 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:205267
5268 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595269 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:495270 ProxyResolutionService::CreateFixedFromPacResult(
5271 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515272 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075273 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095274 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:205275
5276 // Since we have proxy, should try to establish tunnel.
5277 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:175278 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5279 "Host: www.example.org:443\r\n"
5280 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205281
rsleevidb16bb02015-11-12 23:47:175282 MockWrite("GET /1 HTTP/1.1\r\n"
5283 "Host: www.example.org\r\n"
5284 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205285
rsleevidb16bb02015-11-12 23:47:175286 MockWrite("GET /2 HTTP/1.1\r\n"
5287 "Host: www.example.org\r\n"
5288 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205289 };
5290
5291 // The proxy responds to the connect with a 407, using a persistent
5292 // connection.
5293 MockRead data_reads1[] = {
5294 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
5295
5296 MockRead("HTTP/1.1 200 OK\r\n"),
5297 MockRead("Content-Length: 1\r\n\r\n"),
5298 MockRead(SYNCHRONOUS, "1"),
5299
5300 MockRead("HTTP/1.1 200 OK\r\n"),
5301 MockRead("Content-Length: 2\r\n\r\n"),
5302 MockRead(SYNCHRONOUS, "22"),
5303 };
5304
Ryan Sleevib8d7ea02018-05-07 20:01:015305 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:075306 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:205307 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075308 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:205309
5310 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:585311 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:195312 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:205313
5314 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015315 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:205316
5317 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015318 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:205319
5320 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:525321 ASSERT_TRUE(response1);
5322 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:205323 EXPECT_EQ(1, response1->headers->GetContentLength());
5324
5325 LoadTimingInfo load_timing_info1;
5326 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
5327 TestLoadTimingNotReusedWithPac(load_timing_info1,
5328 CONNECT_TIMING_HAS_SSL_TIMES);
5329
5330 trans1.reset();
5331
5332 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:585333 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:195334 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:205335
5336 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015337 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:205338
5339 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015340 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:205341
5342 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:525343 ASSERT_TRUE(response2);
5344 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:205345 EXPECT_EQ(2, response2->headers->GetContentLength());
5346
5347 LoadTimingInfo load_timing_info2;
5348 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5349 TestLoadTimingReusedWithPac(load_timing_info2);
5350
5351 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
5352
5353 trans2.reset();
5354 session->CloseAllConnections();
5355}
5356
[email protected]2df19bb2010-08-25 20:13:465357// Test a simple get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015358TEST_F(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:275359 HttpRequestInfo request;
5360 request.method = "GET";
bncce36dca22015-04-21 22:11:235361 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105362 request.traffic_annotation =
5363 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275364
[email protected]2df19bb2010-08-25 20:13:465365 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495366 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5367 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515368 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075369 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095370 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:465371
[email protected]2df19bb2010-08-25 20:13:465372 // Since we have proxy, should use full url
5373 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235374 MockWrite(
5375 "GET http://www.example.org/ HTTP/1.1\r\n"
5376 "Host: www.example.org\r\n"
5377 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465378 };
5379
5380 MockRead data_reads1[] = {
5381 MockRead("HTTP/1.1 200 OK\r\n"),
5382 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5383 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065384 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:465385 };
5386
Ryan Sleevib8d7ea02018-05-07 20:01:015387 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:075388 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:065389 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075390 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:465391
[email protected]49639fa2011-12-20 23:22:415392 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:465393
bnc691fda62016-08-12 00:43:165394 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505395
bnc691fda62016-08-12 00:43:165396 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015397 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465398
5399 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015400 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465401
[email protected]58e32bb2013-01-21 18:23:255402 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165403 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255404 TestLoadTimingNotReused(load_timing_info,
5405 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5406
bnc691fda62016-08-12 00:43:165407 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525408 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:465409
tbansal2ecbbc72016-10-06 17:15:475410 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:465411 EXPECT_TRUE(response->headers->IsKeepAlive());
5412 EXPECT_EQ(200, response->headers->response_code());
5413 EXPECT_EQ(100, response->headers->GetContentLength());
5414 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5415
5416 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525417 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:465418}
5419
[email protected]7642b5ae2010-09-01 20:55:175420// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015421TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:275422 HttpRequestInfo request;
5423 request.method = "GET";
bncce36dca22015-04-21 22:11:235424 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105425 request.traffic_annotation =
5426 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275427
[email protected]7642b5ae2010-09-01 20:55:175428 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495429 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5430 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515431 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075432 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095433 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:175434
bncce36dca22015-04-21 22:11:235435 // fetch http://www.example.org/ via SPDY
Ryan Hamilton0239aac2018-05-19 00:03:135436 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:455437 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415438 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]7642b5ae2010-09-01 20:55:175439
Ryan Hamilton0239aac2018-05-19 00:03:135440 spdy::SpdySerializedFrame resp(
5441 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
5442 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:175443 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415444 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]7642b5ae2010-09-01 20:55:175445 };
5446
Ryan Sleevib8d7ea02018-05-07 20:01:015447 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075448 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:175449
[email protected]8ddf8322012-02-23 18:08:065450 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365451 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075452 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:175453
[email protected]49639fa2011-12-20 23:22:415454 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:175455
bnc691fda62016-08-12 00:43:165456 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505457
bnc691fda62016-08-12 00:43:165458 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015459 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7642b5ae2010-09-01 20:55:175460
5461 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015462 EXPECT_THAT(rv, IsOk());
[email protected]7642b5ae2010-09-01 20:55:175463
[email protected]58e32bb2013-01-21 18:23:255464 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165465 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255466 TestLoadTimingNotReused(load_timing_info,
5467 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5468
bnc691fda62016-08-12 00:43:165469 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525470 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:475471 EXPECT_TRUE(response->proxy_server.is_https());
wezca1070932016-05-26 20:30:525472 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025473 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]7642b5ae2010-09-01 20:55:175474
5475 std::string response_data;
bnc691fda62016-08-12 00:43:165476 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235477 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:175478}
5479
[email protected]1c173852014-06-19 12:51:505480// Verifies that a session which races and wins against the owning transaction
5481// (completing prior to host resolution), doesn't fail the transaction.
5482// Regression test for crbug.com/334413.
bncd16676a2016-07-20 16:23:015483TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
[email protected]1c173852014-06-19 12:51:505484 HttpRequestInfo request;
5485 request.method = "GET";
bncce36dca22015-04-21 22:11:235486 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105487 request.traffic_annotation =
5488 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c173852014-06-19 12:51:505489
5490 // Configure SPDY proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495491 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5492 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515493 BoundTestNetLog log;
[email protected]1c173852014-06-19 12:51:505494 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095495 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1c173852014-06-19 12:51:505496
bncce36dca22015-04-21 22:11:235497 // Fetch http://www.example.org/ through the SPDY proxy.
Ryan Hamilton0239aac2018-05-19 00:03:135498 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:455499 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415500 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]1c173852014-06-19 12:51:505501
Ryan Hamilton0239aac2018-05-19 00:03:135502 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
5503 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]1c173852014-06-19 12:51:505504 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415505 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]1c173852014-06-19 12:51:505506 };
5507
Ryan Sleevib8d7ea02018-05-07 20:01:015508 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]1c173852014-06-19 12:51:505509 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
5510
5511 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365512 ssl.next_proto = kProtoHTTP2;
[email protected]1c173852014-06-19 12:51:505513 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5514
5515 TestCompletionCallback callback1;
5516
bnc691fda62016-08-12 00:43:165517 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1c173852014-06-19 12:51:505518
5519 // Stall the hostname resolution begun by the transaction.
[email protected]1c173852014-06-19 12:51:505520 session_deps_.host_resolver->set_ondemand_mode(true);
5521
bnc691fda62016-08-12 00:43:165522 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015523 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c173852014-06-19 12:51:505524
5525 // Race a session to the proxy, which completes first.
5526 session_deps_.host_resolver->set_ondemand_mode(false);
Paul Jensena457017a2018-01-19 23:52:045527 SpdySessionKey key(HostPortPair("proxy", 70), ProxyServer::Direct(),
Matt Menke2436b2f2018-12-11 18:07:115528 PRIVACY_MODE_DISABLED,
5529 SpdySessionKey::IsProxySession::kTrue, SocketTag());
[email protected]1c173852014-06-19 12:51:505530 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:525531 CreateSpdySession(session.get(), key, log.bound());
[email protected]1c173852014-06-19 12:51:505532
5533 // Unstall the resolution begun by the transaction.
5534 session_deps_.host_resolver->set_ondemand_mode(true);
5535 session_deps_.host_resolver->ResolveAllPending();
5536
5537 EXPECT_FALSE(callback1.have_result());
5538 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015539 EXPECT_THAT(rv, IsOk());
[email protected]1c173852014-06-19 12:51:505540
bnc691fda62016-08-12 00:43:165541 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525542 ASSERT_TRUE(response);
5543 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025544 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]1c173852014-06-19 12:51:505545
5546 std::string response_data;
bnc691fda62016-08-12 00:43:165547 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]1c173852014-06-19 12:51:505548 EXPECT_EQ(kUploadData, response_data);
5549}
5550
[email protected]dc7bd1c52010-11-12 00:01:135551// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015552TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:275553 HttpRequestInfo request;
5554 request.method = "GET";
bncce36dca22015-04-21 22:11:235555 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105556 request.traffic_annotation =
5557 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275558
[email protected]79cb5c12011-09-12 13:12:045559 // Configure against https proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495560 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5561 "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515562 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075563 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095564 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:135565
[email protected]dc7bd1c52010-11-12 00:01:135566 // The first request will be a bare GET, the second request will be a
5567 // GET with a Proxy-Authorization header.
bncb26024382016-06-29 02:39:455568 spdy_util_.set_default_url(request.url);
Ryan Hamilton0239aac2018-05-19 00:03:135569 spdy::SpdySerializedFrame req_get(
Bence Béky27ad0a12018-02-08 00:35:485570 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:385571 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]dc7bd1c52010-11-12 00:01:135572 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:465573 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:135574 };
Ryan Hamilton0239aac2018-05-19 00:03:135575 spdy::SpdySerializedFrame req_get_authorization(spdy_util_.ConstructSpdyGet(
Avi Drissman4365a4782018-12-28 19:26:245576 kExtraAuthorizationHeaders, base::size(kExtraAuthorizationHeaders) / 2, 3,
Bence Béky27ad0a12018-02-08 00:35:485577 LOWEST));
[email protected]dc7bd1c52010-11-12 00:01:135578 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415579 CreateMockWrite(req_get, 0), CreateMockWrite(req_get_authorization, 3),
[email protected]dc7bd1c52010-11-12 00:01:135580 };
5581
5582 // The first response is a 407 proxy authentication challenge, and the second
5583 // response will be a 200 response since the second request includes a valid
5584 // Authorization header.
5585 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:465586 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:135587 };
Ryan Hamilton0239aac2018-05-19 00:03:135588 spdy::SpdySerializedFrame resp_authentication(
5589 spdy_util_.ConstructSpdyReplyError(
5590 "407", kExtraAuthenticationHeaders,
Avi Drissman4365a4782018-12-28 19:26:245591 base::size(kExtraAuthenticationHeaders) / 2, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135592 spdy::SpdySerializedFrame body_authentication(
bncdf80d44fd2016-07-15 20:27:415593 spdy_util_.ConstructSpdyDataFrame(1, true));
Ryan Hamilton0239aac2018-05-19 00:03:135594 spdy::SpdySerializedFrame resp_data(
5595 spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
5596 spdy::SpdySerializedFrame body_data(
5597 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:135598 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415599 CreateMockRead(resp_authentication, 1),
bnceb9aa7112017-01-05 01:03:465600 CreateMockRead(body_authentication, 2, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415601 CreateMockRead(resp_data, 4),
5602 CreateMockRead(body_data, 5),
rch8e6c6c42015-05-01 14:05:135603 MockRead(ASYNC, 0, 6),
[email protected]dc7bd1c52010-11-12 00:01:135604 };
5605
Ryan Sleevib8d7ea02018-05-07 20:01:015606 SequencedSocketData data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075607 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:135608
[email protected]8ddf8322012-02-23 18:08:065609 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365610 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075611 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:135612
[email protected]49639fa2011-12-20 23:22:415613 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:135614
bnc691fda62016-08-12 00:43:165615 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]dc7bd1c52010-11-12 00:01:135616
bnc691fda62016-08-12 00:43:165617 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015618 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:135619
5620 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015621 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:135622
bnc691fda62016-08-12 00:43:165623 const HttpResponseInfo* const response = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:135624
wezca1070932016-05-26 20:30:525625 ASSERT_TRUE(response);
5626 ASSERT_TRUE(response->headers);
[email protected]dc7bd1c52010-11-12 00:01:135627 EXPECT_EQ(407, response->headers->response_code());
5628 EXPECT_TRUE(response->was_fetched_via_spdy);
asanka098c0092016-06-16 20:18:435629 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:135630
[email protected]49639fa2011-12-20 23:22:415631 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:135632
bnc691fda62016-08-12 00:43:165633 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015634 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:135635
5636 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015637 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:135638
bnc691fda62016-08-12 00:43:165639 const HttpResponseInfo* const response_restart = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:135640
wezca1070932016-05-26 20:30:525641 ASSERT_TRUE(response_restart);
5642 ASSERT_TRUE(response_restart->headers);
[email protected]dc7bd1c52010-11-12 00:01:135643 EXPECT_EQ(200, response_restart->headers->response_code());
5644 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525645 EXPECT_FALSE(response_restart->auth_challenge);
[email protected]dc7bd1c52010-11-12 00:01:135646}
5647
[email protected]d9da5fe2010-10-13 22:37:165648// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
bncd16676a2016-07-20 16:23:015649TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:275650 HttpRequestInfo request;
5651 request.method = "GET";
bncce36dca22015-04-21 22:11:235652 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105653 request.traffic_annotation =
5654 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275655
[email protected]d9da5fe2010-10-13 22:37:165656 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495657 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5658 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515659 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075660 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095661 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165662
bnc691fda62016-08-12 00:43:165663 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165664
bncce36dca22015-04-21 22:11:235665 // CONNECT to www.example.org:443 via SPDY
Ryan Hamilton0239aac2018-05-19 00:03:135666 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235667 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
5668 // fetch https://www.example.org/ via HTTP
[email protected]d9da5fe2010-10-13 22:37:165669
bncce36dca22015-04-21 22:11:235670 const char get[] =
5671 "GET / HTTP/1.1\r\n"
5672 "Host: www.example.org\r\n"
5673 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:135674 spdy::SpdySerializedFrame wrapped_get(
Bence Békyd74f4382018-02-20 18:26:195675 spdy_util_.ConstructSpdyDataFrame(1, get, false));
Ryan Hamilton0239aac2018-05-19 00:03:135676 spdy::SpdySerializedFrame conn_resp(
5677 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:165678 const char resp[] = "HTTP/1.1 200 OK\r\n"
5679 "Content-Length: 10\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:135680 spdy::SpdySerializedFrame wrapped_get_resp(
Bence Békyd74f4382018-02-20 18:26:195681 spdy_util_.ConstructSpdyDataFrame(1, resp, false));
Ryan Hamilton0239aac2018-05-19 00:03:135682 spdy::SpdySerializedFrame wrapped_body(
Bence Békyd74f4382018-02-20 18:26:195683 spdy_util_.ConstructSpdyDataFrame(1, "1234567890", false));
Ryan Hamilton0239aac2018-05-19 00:03:135684 spdy::SpdySerializedFrame window_update(
bncdf80d44fd2016-07-15 20:27:415685 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
[email protected]8d2f7012012-02-16 00:08:045686
5687 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415688 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
5689 CreateMockWrite(window_update, 6),
[email protected]8d2f7012012-02-16 00:08:045690 };
5691
[email protected]d9da5fe2010-10-13 22:37:165692 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415693 CreateMockRead(conn_resp, 1, ASYNC),
5694 CreateMockRead(wrapped_get_resp, 3, ASYNC),
5695 CreateMockRead(wrapped_body, 4, ASYNC),
5696 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:135697 MockRead(ASYNC, 0, 7),
[email protected]d9da5fe2010-10-13 22:37:165698 };
5699
Ryan Sleevib8d7ea02018-05-07 20:01:015700 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075701 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165702
[email protected]8ddf8322012-02-23 18:08:065703 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365704 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075705 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065706 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075707 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165708
[email protected]49639fa2011-12-20 23:22:415709 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165710
bnc691fda62016-08-12 00:43:165711 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015712 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165713
5714 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015715 ASSERT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:165716
[email protected]58e32bb2013-01-21 18:23:255717 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165718 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255719 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5720
bnc691fda62016-08-12 00:43:165721 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525722 ASSERT_TRUE(response);
5723 ASSERT_TRUE(response->headers);
[email protected]d9da5fe2010-10-13 22:37:165724 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5725
5726 std::string response_data;
bnc691fda62016-08-12 00:43:165727 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]d9da5fe2010-10-13 22:37:165728 EXPECT_EQ("1234567890", response_data);
5729}
5730
5731// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
bncd16676a2016-07-20 16:23:015732TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
5733 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:385734
[email protected]cb9bf6ca2011-01-28 13:15:275735 HttpRequestInfo request;
5736 request.method = "GET";
bncce36dca22015-04-21 22:11:235737 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105738 request.traffic_annotation =
5739 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275740
[email protected]d9da5fe2010-10-13 22:37:165741 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495742 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5743 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515744 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075745 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095746 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165747
bnc691fda62016-08-12 00:43:165748 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165749
bncce36dca22015-04-21 22:11:235750 // CONNECT to www.example.org:443 via SPDY
Ryan Hamilton0239aac2018-05-19 00:03:135751 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235752 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
5753 // fetch https://www.example.org/ via SPDY
5754 const char kMyUrl[] = "https://www.example.org/";
Ryan Hamilton0239aac2018-05-19 00:03:135755 spdy::SpdySerializedFrame get(
bnc38dcd392016-02-09 23:19:495756 spdy_util_wrapped.ConstructSpdyGet(kMyUrl, 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:135757 spdy::SpdySerializedFrame wrapped_get(
5758 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
5759 spdy::SpdySerializedFrame conn_resp(
5760 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
5761 spdy::SpdySerializedFrame get_resp(
bnc42331402016-07-25 13:36:155762 spdy_util_wrapped.ConstructSpdyGetReply(NULL, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135763 spdy::SpdySerializedFrame wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:025764 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135765 spdy::SpdySerializedFrame body(
5766 spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
5767 spdy::SpdySerializedFrame wrapped_body(
[email protected]23e482282013-06-14 16:08:025768 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135769 spdy::SpdySerializedFrame window_update_get_resp(
bncdf80d44fd2016-07-15 20:27:415770 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
Ryan Hamilton0239aac2018-05-19 00:03:135771 spdy::SpdySerializedFrame window_update_body(
bncdf80d44fd2016-07-15 20:27:415772 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
[email protected]8d2f7012012-02-16 00:08:045773
5774 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415775 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
5776 CreateMockWrite(window_update_get_resp, 6),
5777 CreateMockWrite(window_update_body, 7),
[email protected]8d2f7012012-02-16 00:08:045778 };
5779
[email protected]d9da5fe2010-10-13 22:37:165780 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415781 CreateMockRead(conn_resp, 1, ASYNC),
rch32320842015-05-16 15:57:095782 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:415783 CreateMockRead(wrapped_get_resp, 4, ASYNC),
5784 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:135785 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:165786 };
5787
Ryan Sleevib8d7ea02018-05-07 20:01:015788 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075789 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165790
[email protected]8ddf8322012-02-23 18:08:065791 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365792 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075793 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065794 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365795 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075796 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165797
[email protected]49639fa2011-12-20 23:22:415798 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165799
bnc691fda62016-08-12 00:43:165800 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015801 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165802
rch32320842015-05-16 15:57:095803 // Allow the SpdyProxyClientSocket's write callback to complete.
fdoray92e35a72016-06-10 15:54:555804 base::RunLoop().RunUntilIdle();
rch32320842015-05-16 15:57:095805 // Now allow the read of the response to complete.
mmenkee24011922015-12-17 22:12:595806 spdy_data.Resume();
[email protected]d9da5fe2010-10-13 22:37:165807 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015808 EXPECT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:165809
[email protected]58e32bb2013-01-21 18:23:255810 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165811 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255812 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5813
bnc691fda62016-08-12 00:43:165814 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525815 ASSERT_TRUE(response);
5816 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025817 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d9da5fe2010-10-13 22:37:165818
5819 std::string response_data;
bnc691fda62016-08-12 00:43:165820 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235821 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:165822}
5823
5824// Test a SPDY CONNECT failure through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015825TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:275826 HttpRequestInfo request;
5827 request.method = "GET";
bncce36dca22015-04-21 22:11:235828 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105829 request.traffic_annotation =
5830 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275831
[email protected]d9da5fe2010-10-13 22:37:165832 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495833 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5834 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515835 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075836 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095837 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165838
bnc691fda62016-08-12 00:43:165839 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165840
bncce36dca22015-04-21 22:11:235841 // CONNECT to www.example.org:443 via SPDY
Ryan Hamilton0239aac2018-05-19 00:03:135842 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235843 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:135844 spdy::SpdySerializedFrame get(
5845 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:165846
5847 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415848 CreateMockWrite(connect, 0), CreateMockWrite(get, 2),
[email protected]d9da5fe2010-10-13 22:37:165849 };
5850
Ryan Hamilton0239aac2018-05-19 00:03:135851 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(1));
5852 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:165853 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415854 CreateMockRead(resp, 1, ASYNC), MockRead(ASYNC, 0, 3),
[email protected]d9da5fe2010-10-13 22:37:165855 };
5856
Ryan Sleevib8d7ea02018-05-07 20:01:015857 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075858 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165859
[email protected]8ddf8322012-02-23 18:08:065860 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365861 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075862 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065863 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365864 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075865 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165866
[email protected]49639fa2011-12-20 23:22:415867 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165868
bnc691fda62016-08-12 00:43:165869 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015870 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165871
5872 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015873 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]d9da5fe2010-10-13 22:37:165874
ttuttle960fcbf2016-04-19 13:26:325875 // TODO(juliatuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:165876}
5877
Matt Menkecb2cd0982018-12-19 17:54:045878// Test the case where a proxied H2 session doesn't exist when an auth challenge
5879// is observed, but does exist by the time auth credentials are provided.
5880// Proxy-Connection: Close is used so that there's a second DNS lookup, which is
5881// what causes the existing H2 session to be noticed and reused.
5882TEST_F(HttpNetworkTransactionTest, ProxiedH2SessionAppearsDuringAuth) {
5883 ProxyConfig proxy_config;
5884 proxy_config.set_auto_detect(true);
5885 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
5886
5887 CapturingProxyResolver capturing_proxy_resolver;
5888 capturing_proxy_resolver.set_proxy_server(
5889 ProxyServer(ProxyServer::SCHEME_HTTP, HostPortPair("myproxy", 70)));
5890 session_deps_.proxy_resolution_service =
5891 std::make_unique<ProxyResolutionService>(
5892 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
5893 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
5894 std::make_unique<CapturingProxyResolverFactory>(
5895 &capturing_proxy_resolver),
5896 nullptr);
5897
5898 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
5899
5900 const char kMyUrl[] = "https://www.example.org/";
5901 spdy::SpdySerializedFrame get(spdy_util_.ConstructSpdyGet(kMyUrl, 1, LOWEST));
5902 spdy::SpdySerializedFrame get_resp(
5903 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
5904 spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
5905
5906 spdy_util_.UpdateWithStreamDestruction(1);
5907 spdy::SpdySerializedFrame get2(
5908 spdy_util_.ConstructSpdyGet(kMyUrl, 3, LOWEST));
5909 spdy::SpdySerializedFrame get_resp2(
5910 spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
5911 spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
5912
5913 MockWrite auth_challenge_writes[] = {
5914 MockWrite(ASYNC, 0,
5915 "CONNECT www.example.org:443 HTTP/1.1\r\n"
5916 "Host: www.example.org:443\r\n"
5917 "Proxy-Connection: keep-alive\r\n\r\n"),
5918 };
5919
5920 MockRead auth_challenge_reads[] = {
5921 MockRead(ASYNC, 1,
5922 "HTTP/1.1 407 Authentication Required\r\n"
5923 "Content-Length: 0\r\n"
5924 "Proxy-Connection: close\r\n"
5925 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
5926 };
5927
5928 MockWrite spdy_writes[] = {
5929 MockWrite(ASYNC, 0,
5930 "CONNECT www.example.org:443 HTTP/1.1\r\n"
5931 "Host: www.example.org:443\r\n"
5932 "Proxy-Connection: keep-alive\r\n"
5933 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5934 CreateMockWrite(get, 2),
5935 CreateMockWrite(get2, 5),
5936 };
5937
5938 MockRead spdy_reads[] = {
5939 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\n\r\n"),
5940 CreateMockRead(get_resp, 3, ASYNC),
5941 CreateMockRead(body, 4, ASYNC),
5942 CreateMockRead(get_resp2, 6, ASYNC),
5943 CreateMockRead(body2, 7, ASYNC),
5944
5945 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 8),
5946 };
5947
5948 SequencedSocketData auth_challenge1(auth_challenge_reads,
5949 auth_challenge_writes);
5950 session_deps_.socket_factory->AddSocketDataProvider(&auth_challenge1);
5951
5952 SequencedSocketData auth_challenge2(auth_challenge_reads,
5953 auth_challenge_writes);
5954 session_deps_.socket_factory->AddSocketDataProvider(&auth_challenge2);
5955
5956 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
5957 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
5958
5959 SSLSocketDataProvider ssl(ASYNC, OK);
5960 ssl.next_proto = kProtoHTTP2;
5961 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5962
5963 TestCompletionCallback callback;
5964 std::string response_data;
5965
5966 // Run first request until an auth challenge is observed.
5967 HttpRequestInfo request1;
5968 request1.method = "GET";
5969 request1.url = GURL(kMyUrl);
5970 request1.traffic_annotation =
5971 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5972 HttpNetworkTransaction trans1(LOWEST, session.get());
5973 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
5974 EXPECT_THAT(callback.GetResult(rv), IsOk());
5975 const HttpResponseInfo* response = trans1.GetResponseInfo();
5976 ASSERT_TRUE(response);
5977 ASSERT_TRUE(response->headers);
5978 EXPECT_EQ(407, response->headers->response_code());
5979 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5980 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
5981
5982 // Run second request until an auth challenge is observed.
5983 HttpRequestInfo request2;
5984 request2.method = "GET";
5985 request2.url = GURL(kMyUrl);
5986 request2.traffic_annotation =
5987 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5988 HttpNetworkTransaction trans2(LOWEST, session.get());
5989 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
5990 EXPECT_THAT(callback.GetResult(rv), IsOk());
5991 response = trans2.GetResponseInfo();
5992 ASSERT_TRUE(response);
5993 ASSERT_TRUE(response->headers);
5994 EXPECT_EQ(407, response->headers->response_code());
5995 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5996 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
5997
5998 // Now provide credentials for the first request, and wait for it to complete.
5999 rv = trans1.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
6000 rv = callback.GetResult(rv);
6001 EXPECT_THAT(rv, IsOk());
6002 response = trans1.GetResponseInfo();
6003 ASSERT_TRUE(response);
6004 ASSERT_TRUE(response->headers);
6005 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
6006 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
6007 EXPECT_EQ(kUploadData, response_data);
6008
6009 // Now provide credentials for the second request. It should notice the
6010 // existing session, and reuse it.
6011 rv = trans2.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
6012 EXPECT_THAT(callback.GetResult(rv), IsOk());
6013 response = trans2.GetResponseInfo();
6014 ASSERT_TRUE(response);
6015 ASSERT_TRUE(response->headers);
6016 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
6017 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
6018 EXPECT_EQ(kUploadData, response_data);
6019}
6020
[email protected]f6c63db52013-02-02 00:35:226021// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
6022// HTTPS Proxy to different servers.
bncd16676a2016-07-20 16:23:016023TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:226024 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
6025 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496026 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6027 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:516028 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076029 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:096030 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:506031 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:226032
6033 HttpRequestInfo request1;
6034 request1.method = "GET";
bncce36dca22015-04-21 22:11:236035 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:226036 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:106037 request1.traffic_annotation =
6038 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226039
6040 HttpRequestInfo request2;
6041 request2.method = "GET";
bncce36dca22015-04-21 22:11:236042 request2.url = GURL("https://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:226043 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:106044 request2.traffic_annotation =
6045 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226046
bncce36dca22015-04-21 22:11:236047 // CONNECT to www.example.org:443 via SPDY.
Ryan Hamilton0239aac2018-05-19 00:03:136048 spdy::SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:236049 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:136050 spdy::SpdySerializedFrame conn_resp1(
6051 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:226052
bncce36dca22015-04-21 22:11:236053 // Fetch https://www.example.org/ via HTTP.
6054 const char get1[] =
6055 "GET / HTTP/1.1\r\n"
6056 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:226057 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136058 spdy::SpdySerializedFrame wrapped_get1(
Bence Békyd74f4382018-02-20 18:26:196059 spdy_util_.ConstructSpdyDataFrame(1, get1, false));
[email protected]f6c63db52013-02-02 00:35:226060 const char resp1[] = "HTTP/1.1 200 OK\r\n"
6061 "Content-Length: 1\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136062 spdy::SpdySerializedFrame wrapped_get_resp1(
Bence Békyd74f4382018-02-20 18:26:196063 spdy_util_.ConstructSpdyDataFrame(1, resp1, false));
Ryan Hamilton0239aac2018-05-19 00:03:136064 spdy::SpdySerializedFrame wrapped_body1(
Bence Békyd74f4382018-02-20 18:26:196065 spdy_util_.ConstructSpdyDataFrame(1, "1", false));
Ryan Hamilton0239aac2018-05-19 00:03:136066 spdy::SpdySerializedFrame window_update(
bncdf80d44fd2016-07-15 20:27:416067 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:226068
bncce36dca22015-04-21 22:11:236069 // CONNECT to mail.example.org:443 via SPDY.
Ryan Hamilton0239aac2018-05-19 00:03:136070 spdy::SpdyHeaderBlock connect2_block;
6071 connect2_block[spdy::kHttp2MethodHeader] = "CONNECT";
6072 connect2_block[spdy::kHttp2AuthorityHeader] = "mail.example.org:443";
6073 spdy::SpdySerializedFrame connect2(spdy_util_.ConstructSpdyHeaders(
bnc42331402016-07-25 13:36:156074 3, std::move(connect2_block), LOWEST, false));
[email protected]601e03f12014-04-06 16:26:396075
Ryan Hamilton0239aac2018-05-19 00:03:136076 spdy::SpdySerializedFrame conn_resp2(
6077 spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:226078
bncce36dca22015-04-21 22:11:236079 // Fetch https://mail.example.org/ via HTTP.
6080 const char get2[] =
6081 "GET / HTTP/1.1\r\n"
6082 "Host: mail.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:226083 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136084 spdy::SpdySerializedFrame wrapped_get2(
Bence Békyd74f4382018-02-20 18:26:196085 spdy_util_.ConstructSpdyDataFrame(3, get2, false));
[email protected]f6c63db52013-02-02 00:35:226086 const char resp2[] = "HTTP/1.1 200 OK\r\n"
6087 "Content-Length: 2\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136088 spdy::SpdySerializedFrame wrapped_get_resp2(
Bence Békyd74f4382018-02-20 18:26:196089 spdy_util_.ConstructSpdyDataFrame(3, resp2, false));
Ryan Hamilton0239aac2018-05-19 00:03:136090 spdy::SpdySerializedFrame wrapped_body2(
Bence Békyd74f4382018-02-20 18:26:196091 spdy_util_.ConstructSpdyDataFrame(3, "22", false));
[email protected]f6c63db52013-02-02 00:35:226092
6093 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:416094 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
6095 CreateMockWrite(connect2, 5), CreateMockWrite(wrapped_get2, 7),
[email protected]f6c63db52013-02-02 00:35:226096 };
6097
6098 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:416099 CreateMockRead(conn_resp1, 1, ASYNC),
6100 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
6101 CreateMockRead(wrapped_body1, 4, ASYNC),
6102 CreateMockRead(conn_resp2, 6, ASYNC),
6103 CreateMockRead(wrapped_get_resp2, 8, ASYNC),
6104 CreateMockRead(wrapped_body2, 9, ASYNC),
6105 MockRead(ASYNC, 0, 10),
[email protected]f6c63db52013-02-02 00:35:226106 };
6107
Ryan Sleevib8d7ea02018-05-07 20:01:016108 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
mmenke11eb5152015-06-09 14:50:506109 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:226110
6111 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:366112 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:506113 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:226114 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:506115 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:226116 SSLSocketDataProvider ssl3(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:506117 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:226118
6119 TestCompletionCallback callback;
6120
bnc691fda62016-08-12 00:43:166121 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206122 int rv = trans.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016123 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:226124
6125 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:166126 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]f6c63db52013-02-02 00:35:226127 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
6128
bnc691fda62016-08-12 00:43:166129 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526130 ASSERT_TRUE(response);
6131 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:226132 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6133
6134 std::string response_data;
Victor Costan9c7302b2018-08-27 16:39:446135 scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(256);
bnc691fda62016-08-12 00:43:166136 rv = trans.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:506137 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:226138
bnc691fda62016-08-12 00:43:166139 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206140 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016141 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:226142
6143 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:166144 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:226145 // Even though the SPDY connection is reused, a new tunnelled connection has
6146 // to be created, so the socket's load timing looks like a fresh connection.
6147 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
6148
6149 // The requests should have different IDs, since they each are using their own
6150 // separate stream.
6151 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
6152
bnc691fda62016-08-12 00:43:166153 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:506154 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:226155}
6156
6157// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
6158// HTTPS Proxy to the same server.
bncd16676a2016-07-20 16:23:016159TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:226160 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
6161 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496162 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6163 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:516164 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076165 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:096166 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:506167 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:226168
6169 HttpRequestInfo request1;
6170 request1.method = "GET";
bncce36dca22015-04-21 22:11:236171 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:226172 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:106173 request1.traffic_annotation =
6174 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226175
6176 HttpRequestInfo request2;
6177 request2.method = "GET";
bncce36dca22015-04-21 22:11:236178 request2.url = GURL("https://www.example.org/2");
[email protected]f6c63db52013-02-02 00:35:226179 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:106180 request2.traffic_annotation =
6181 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226182
bncce36dca22015-04-21 22:11:236183 // CONNECT to www.example.org:443 via SPDY.
Ryan Hamilton0239aac2018-05-19 00:03:136184 spdy::SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:236185 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:136186 spdy::SpdySerializedFrame conn_resp1(
6187 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:226188
bncce36dca22015-04-21 22:11:236189 // Fetch https://www.example.org/ via HTTP.
6190 const char get1[] =
6191 "GET / HTTP/1.1\r\n"
6192 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:226193 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136194 spdy::SpdySerializedFrame wrapped_get1(
Bence Békyd74f4382018-02-20 18:26:196195 spdy_util_.ConstructSpdyDataFrame(1, get1, false));
[email protected]f6c63db52013-02-02 00:35:226196 const char resp1[] = "HTTP/1.1 200 OK\r\n"
6197 "Content-Length: 1\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136198 spdy::SpdySerializedFrame wrapped_get_resp1(
Bence Békyd74f4382018-02-20 18:26:196199 spdy_util_.ConstructSpdyDataFrame(1, resp1, false));
Ryan Hamilton0239aac2018-05-19 00:03:136200 spdy::SpdySerializedFrame wrapped_body1(
Bence Békyd74f4382018-02-20 18:26:196201 spdy_util_.ConstructSpdyDataFrame(1, "1", false));
Ryan Hamilton0239aac2018-05-19 00:03:136202 spdy::SpdySerializedFrame window_update(
bncdf80d44fd2016-07-15 20:27:416203 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:226204
bncce36dca22015-04-21 22:11:236205 // Fetch https://www.example.org/2 via HTTP.
6206 const char get2[] =
6207 "GET /2 HTTP/1.1\r\n"
6208 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:226209 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136210 spdy::SpdySerializedFrame wrapped_get2(
Bence Békyd74f4382018-02-20 18:26:196211 spdy_util_.ConstructSpdyDataFrame(1, get2, false));
[email protected]f6c63db52013-02-02 00:35:226212 const char resp2[] = "HTTP/1.1 200 OK\r\n"
6213 "Content-Length: 2\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136214 spdy::SpdySerializedFrame wrapped_get_resp2(
Bence Békyd74f4382018-02-20 18:26:196215 spdy_util_.ConstructSpdyDataFrame(1, resp2, false));
Ryan Hamilton0239aac2018-05-19 00:03:136216 spdy::SpdySerializedFrame wrapped_body2(
Bence Békyd74f4382018-02-20 18:26:196217 spdy_util_.ConstructSpdyDataFrame(1, "22", false));
[email protected]f6c63db52013-02-02 00:35:226218
6219 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:416220 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
6221 CreateMockWrite(wrapped_get2, 5),
[email protected]f6c63db52013-02-02 00:35:226222 };
6223
6224 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:416225 CreateMockRead(conn_resp1, 1, ASYNC),
6226 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
bnceb9aa7112017-01-05 01:03:466227 CreateMockRead(wrapped_body1, 4, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:416228 CreateMockRead(wrapped_get_resp2, 6, ASYNC),
bnceb9aa7112017-01-05 01:03:466229 CreateMockRead(wrapped_body2, 7, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:416230 MockRead(ASYNC, 0, 8),
[email protected]f6c63db52013-02-02 00:35:226231 };
6232
Ryan Sleevib8d7ea02018-05-07 20:01:016233 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
mmenke11eb5152015-06-09 14:50:506234 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:226235
6236 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:366237 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:506238 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:226239 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:506240 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:226241
6242 TestCompletionCallback callback;
6243
bnc87dcefc2017-05-25 12:47:586244 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:196245 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206246 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016247 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:226248
6249 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016250 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:226251
6252 LoadTimingInfo load_timing_info;
6253 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6254 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
6255
6256 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526257 ASSERT_TRUE(response);
6258 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:226259 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6260
6261 std::string response_data;
Victor Costan9c7302b2018-08-27 16:39:446262 scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(256);
[email protected]90499482013-06-01 00:39:506263 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:226264 trans.reset();
6265
bnc87dcefc2017-05-25 12:47:586266 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:196267 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206268 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016269 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:226270
[email protected]f6c63db52013-02-02 00:35:226271 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016272 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:226273
6274 LoadTimingInfo load_timing_info2;
6275 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
6276 TestLoadTimingReused(load_timing_info2);
6277
6278 // The requests should have the same ID.
6279 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
6280
[email protected]90499482013-06-01 00:39:506281 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:226282}
6283
6284// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
6285// Proxy to different servers.
bncd16676a2016-07-20 16:23:016286TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) {
[email protected]f6c63db52013-02-02 00:35:226287 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496288 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6289 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:516290 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076291 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:096292 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:506293 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:226294
6295 HttpRequestInfo request1;
6296 request1.method = "GET";
bncce36dca22015-04-21 22:11:236297 request1.url = GURL("http://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:226298 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:106299 request1.traffic_annotation =
6300 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226301
6302 HttpRequestInfo request2;
6303 request2.method = "GET";
bncce36dca22015-04-21 22:11:236304 request2.url = GURL("http://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:226305 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:106306 request2.traffic_annotation =
6307 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226308
bncce36dca22015-04-21 22:11:236309 // http://www.example.org/
Ryan Hamilton0239aac2018-05-19 00:03:136310 spdy::SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:236311 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
Ryan Hamilton0239aac2018-05-19 00:03:136312 spdy::SpdySerializedFrame get1(
bnc42331402016-07-25 13:36:156313 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
Ryan Hamilton0239aac2018-05-19 00:03:136314 spdy::SpdySerializedFrame get_resp1(
6315 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
6316 spdy::SpdySerializedFrame body1(
6317 spdy_util_.ConstructSpdyDataFrame(1, "1", true));
rdsmithebb50aa2015-11-12 03:44:386318 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]f6c63db52013-02-02 00:35:226319
bncce36dca22015-04-21 22:11:236320 // http://mail.example.org/
Ryan Hamilton0239aac2018-05-19 00:03:136321 spdy::SpdyHeaderBlock headers2(
bncce36dca22015-04-21 22:11:236322 spdy_util_.ConstructGetHeaderBlockForProxy("http://mail.example.org/"));
Ryan Hamilton0239aac2018-05-19 00:03:136323 spdy::SpdySerializedFrame get2(
bnc42331402016-07-25 13:36:156324 spdy_util_.ConstructSpdyHeaders(3, std::move(headers2), LOWEST, true));
Ryan Hamilton0239aac2018-05-19 00:03:136325 spdy::SpdySerializedFrame get_resp2(
6326 spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
6327 spdy::SpdySerializedFrame body2(
6328 spdy_util_.ConstructSpdyDataFrame(3, "22", true));
[email protected]f6c63db52013-02-02 00:35:226329
6330 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:416331 CreateMockWrite(get1, 0), CreateMockWrite(get2, 3),
[email protected]f6c63db52013-02-02 00:35:226332 };
6333
6334 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:416335 CreateMockRead(get_resp1, 1, ASYNC),
6336 CreateMockRead(body1, 2, ASYNC),
6337 CreateMockRead(get_resp2, 4, ASYNC),
6338 CreateMockRead(body2, 5, ASYNC),
6339 MockRead(ASYNC, 0, 6),
[email protected]f6c63db52013-02-02 00:35:226340 };
6341
Ryan Sleevib8d7ea02018-05-07 20:01:016342 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
mmenke11eb5152015-06-09 14:50:506343 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:226344
6345 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:366346 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:506347 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:226348
6349 TestCompletionCallback callback;
6350
bnc87dcefc2017-05-25 12:47:586351 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:196352 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206353 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016354 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:226355
6356 LoadTimingInfo load_timing_info;
6357 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6358 TestLoadTimingNotReused(load_timing_info,
6359 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6360
6361 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526362 ASSERT_TRUE(response);
6363 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:026364 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]f6c63db52013-02-02 00:35:226365
6366 std::string response_data;
Victor Costan9c7302b2018-08-27 16:39:446367 scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(256);
mmenke11eb5152015-06-09 14:50:506368 rv = trans->Read(buf.get(), 256, callback.callback());
6369 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:226370 // Delete the first request, so the second one can reuse the socket.
6371 trans.reset();
6372
bnc691fda62016-08-12 00:43:166373 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206374 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016375 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:226376
6377 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:166378 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:226379 TestLoadTimingReused(load_timing_info2);
6380
6381 // The requests should have the same ID.
6382 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
6383
bnc691fda62016-08-12 00:43:166384 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:506385 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:226386}
6387
Matt Menke2436b2f2018-12-11 18:07:116388// Test that an HTTP/2 CONNECT through an HTTPS Proxy to a HTTP/2 server and a
6389// direct (non-proxied) request to the proxy server are not pooled, as that
6390// would break socket pool isolation.
6391TEST_F(HttpNetworkTransactionTest, SpdyProxyIsolation1) {
6392 ProxyConfig proxy_config;
6393 proxy_config.set_auto_detect(true);
6394 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
6395
6396 CapturingProxyResolver capturing_proxy_resolver;
6397 session_deps_.proxy_resolution_service =
6398 std::make_unique<ProxyResolutionService>(
6399 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
6400 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
6401 std::make_unique<CapturingProxyResolverFactory>(
6402 &capturing_proxy_resolver),
6403 nullptr);
6404
6405 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6406
6407 SpdyTestUtil spdy_util1;
6408 // CONNECT to www.example.org:443 via HTTP/2.
6409 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
6410 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
6411 // fetch https://www.example.org/ via HTTP/2.
6412 const char kMyUrl[] = "https://www.example.org/";
6413 spdy::SpdySerializedFrame get(spdy_util1.ConstructSpdyGet(kMyUrl, 1, LOWEST));
6414 spdy::SpdySerializedFrame wrapped_get(
6415 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
6416 spdy::SpdySerializedFrame conn_resp(
6417 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
6418 spdy::SpdySerializedFrame get_resp(
6419 spdy_util1.ConstructSpdyGetReply(NULL, 0, 1));
6420 spdy::SpdySerializedFrame wrapped_get_resp(
6421 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
6422 spdy::SpdySerializedFrame body(spdy_util1.ConstructSpdyDataFrame(1, true));
6423 spdy::SpdySerializedFrame wrapped_body(
6424 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
6425 spdy::SpdySerializedFrame window_update_get_resp(
6426 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
6427 spdy::SpdySerializedFrame window_update_body(
6428 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
6429
6430 MockWrite spdy_writes1[] = {
6431 CreateMockWrite(connect, 0),
6432 CreateMockWrite(wrapped_get, 2),
6433 CreateMockWrite(window_update_get_resp, 6),
6434 CreateMockWrite(window_update_body, 7),
6435 };
6436
6437 MockRead spdy_reads1[] = {
6438 CreateMockRead(conn_resp, 1, ASYNC),
6439 MockRead(ASYNC, ERR_IO_PENDING, 3),
6440 CreateMockRead(wrapped_get_resp, 4, ASYNC),
6441 CreateMockRead(wrapped_body, 5, ASYNC),
6442 MockRead(ASYNC, 0, 8),
6443 };
6444
6445 SequencedSocketData spdy_data1(spdy_reads1, spdy_writes1);
6446 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data1);
6447
6448 // Fetch https://proxy:70/ via HTTP/2. Needs a new SpdyTestUtil, since it uses
6449 // a new pipe.
6450 SpdyTestUtil spdy_util2;
6451 spdy::SpdySerializedFrame req(
6452 spdy_util2.ConstructSpdyGet("https://proxy:70/", 1, LOWEST));
6453 MockWrite spdy_writes2[] = {CreateMockWrite(req, 0)};
6454
6455 spdy::SpdySerializedFrame resp(
6456 spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
6457 spdy::SpdySerializedFrame data(spdy_util2.ConstructSpdyDataFrame(1, true));
6458 MockRead spdy_reads2[] = {
6459 CreateMockRead(resp, 1),
6460 CreateMockRead(data, 2),
6461 MockRead(ASYNC, 0, 3),
6462 };
6463 SequencedSocketData spdy_data2(spdy_reads2, spdy_writes2);
6464 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data2);
6465
6466 SSLSocketDataProvider ssl(ASYNC, OK);
6467 ssl.next_proto = kProtoHTTP2;
6468 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6469 SSLSocketDataProvider ssl2(ASYNC, OK);
6470 ssl2.next_proto = kProtoHTTP2;
6471 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6472 SSLSocketDataProvider ssl3(ASYNC, OK);
6473 ssl3.next_proto = kProtoHTTP2;
6474 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
6475
6476 TestCompletionCallback callback;
6477 std::string response_data;
6478
6479 // Make a request using proxy:70 as a HTTP/2 proxy.
6480 capturing_proxy_resolver.set_proxy_server(
6481 ProxyServer(ProxyServer::SCHEME_HTTPS, HostPortPair("proxy", 70)));
6482 HttpRequestInfo request1;
6483 request1.method = "GET";
6484 request1.url = GURL("https://www.example.org/");
6485 request1.traffic_annotation =
6486 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6487
6488 HttpNetworkTransaction trans1(LOWEST, session.get());
6489 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
6490 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6491
6492 // Allow the SpdyProxyClientSocket's write callback to complete.
6493 base::RunLoop().RunUntilIdle();
6494 // Now allow the read of the response to complete.
6495 spdy_data1.Resume();
6496 rv = callback.WaitForResult();
6497 EXPECT_THAT(rv, IsOk());
6498
6499 const HttpResponseInfo* response = trans1.GetResponseInfo();
6500 ASSERT_TRUE(response);
6501 ASSERT_TRUE(response->headers);
6502 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
6503
6504 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
6505 EXPECT_EQ(kUploadData, response_data);
6506 RunUntilIdle();
6507
6508 // Make a direct HTTP/2 request to proxy:70.
6509 capturing_proxy_resolver.set_proxy_server(ProxyServer::Direct());
6510 HttpRequestInfo request2;
6511 request2.method = "GET";
6512 request2.url = GURL("https://proxy:70/");
6513 request2.traffic_annotation =
6514 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6515 HttpNetworkTransaction trans2(LOWEST, session.get());
6516 EXPECT_THAT(callback.GetResult(trans2.Start(&request2, callback.callback(),
6517 NetLogWithSource())),
6518 IsOk());
6519 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
6520}
6521
6522// Same as above, but reverse request order, since the code to check for an
6523// existing session is different for tunnels and direct connections.
6524TEST_F(HttpNetworkTransactionTest, SpdyProxyIsolation2) {
6525 // Configure against https proxy server "myproxy:80".
6526 ProxyConfig proxy_config;
6527 proxy_config.set_auto_detect(true);
6528 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
6529
6530 CapturingProxyResolver capturing_proxy_resolver;
6531 session_deps_.proxy_resolution_service =
6532 std::make_unique<ProxyResolutionService>(
6533 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
6534 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
6535 std::make_unique<CapturingProxyResolverFactory>(
6536 &capturing_proxy_resolver),
6537 nullptr);
6538
6539 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6540 // Fetch https://proxy:70/ via HTTP/2.
6541 SpdyTestUtil spdy_util1;
6542 spdy::SpdySerializedFrame req(
6543 spdy_util1.ConstructSpdyGet("https://proxy:70/", 1, LOWEST));
6544 MockWrite spdy_writes1[] = {CreateMockWrite(req, 0)};
6545
6546 spdy::SpdySerializedFrame resp(
6547 spdy_util1.ConstructSpdyGetReply(nullptr, 0, 1));
6548 spdy::SpdySerializedFrame data(spdy_util1.ConstructSpdyDataFrame(1, true));
6549 MockRead spdy_reads1[] = {
6550 CreateMockRead(resp, 1),
6551 CreateMockRead(data, 2),
6552 MockRead(ASYNC, 0, 3),
6553 };
6554 SequencedSocketData spdy_data1(spdy_reads1, spdy_writes1);
6555 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data1);
6556
6557 SpdyTestUtil spdy_util2;
6558 // CONNECT to www.example.org:443 via HTTP/2.
6559 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
6560 nullptr, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
6561 // fetch https://www.example.org/ via HTTP/2.
6562 const char kMyUrl[] = "https://www.example.org/";
6563 spdy::SpdySerializedFrame get(spdy_util2.ConstructSpdyGet(kMyUrl, 1, LOWEST));
6564 spdy::SpdySerializedFrame wrapped_get(
6565 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
6566 spdy::SpdySerializedFrame conn_resp(
6567 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
6568 spdy::SpdySerializedFrame get_resp(
6569 spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
6570 spdy::SpdySerializedFrame wrapped_get_resp(
6571 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
6572 spdy::SpdySerializedFrame body(spdy_util2.ConstructSpdyDataFrame(1, true));
6573 spdy::SpdySerializedFrame wrapped_body(
6574 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
6575 spdy::SpdySerializedFrame window_update_get_resp(
6576 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
6577 spdy::SpdySerializedFrame window_update_body(
6578 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
6579
6580 MockWrite spdy_writes2[] = {
6581 CreateMockWrite(connect, 0),
6582 CreateMockWrite(wrapped_get, 2),
6583 CreateMockWrite(window_update_get_resp, 6),
6584 CreateMockWrite(window_update_body, 7),
6585 };
6586
6587 MockRead spdy_reads2[] = {
6588 CreateMockRead(conn_resp, 1, ASYNC),
6589 MockRead(ASYNC, ERR_IO_PENDING, 3),
6590 CreateMockRead(wrapped_get_resp, 4, ASYNC),
6591 CreateMockRead(wrapped_body, 5, ASYNC),
6592 MockRead(ASYNC, 0, 8),
6593 };
6594
6595 SequencedSocketData spdy_data2(spdy_reads2, spdy_writes2);
6596 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data2);
6597
6598 SSLSocketDataProvider ssl(ASYNC, OK);
6599 ssl.next_proto = kProtoHTTP2;
6600 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6601 SSLSocketDataProvider ssl2(ASYNC, OK);
6602 ssl2.next_proto = kProtoHTTP2;
6603 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6604 SSLSocketDataProvider ssl3(ASYNC, OK);
6605 ssl3.next_proto = kProtoHTTP2;
6606 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
6607
6608 TestCompletionCallback callback;
6609 std::string response_data;
6610
6611 // Make a direct HTTP/2 request to proxy:70.
6612 capturing_proxy_resolver.set_proxy_server(ProxyServer::Direct());
6613 HttpRequestInfo request1;
6614 request1.method = "GET";
6615 request1.url = GURL("https://proxy:70/");
6616 request1.traffic_annotation =
6617 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6618 HttpNetworkTransaction trans1(LOWEST, session.get());
6619 EXPECT_THAT(callback.GetResult(trans1.Start(&request1, callback.callback(),
6620 NetLogWithSource())),
6621 IsOk());
6622 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
6623 RunUntilIdle();
6624
6625 // Make a request using proxy:70 as a HTTP/2 proxy.
6626 capturing_proxy_resolver.set_proxy_server(
6627 ProxyServer(ProxyServer::SCHEME_HTTPS, HostPortPair("proxy", 70)));
6628 HttpRequestInfo request2;
6629 request2.method = "GET";
6630 request2.url = GURL("https://www.example.org/");
6631 request2.traffic_annotation =
6632 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6633
6634 HttpNetworkTransaction trans2(LOWEST, session.get());
6635 int rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
6636 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6637
6638 // Allow the SpdyProxyClientSocket's write callback to complete.
6639 base::RunLoop().RunUntilIdle();
6640 // Now allow the read of the response to complete.
6641 spdy_data2.Resume();
6642 rv = callback.WaitForResult();
6643 EXPECT_THAT(rv, IsOk());
6644
6645 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
6646 ASSERT_TRUE(response2);
6647 ASSERT_TRUE(response2->headers);
6648 EXPECT_EQ("HTTP/1.1 200", response2->headers->GetStatusLine());
6649
6650 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
6651 EXPECT_EQ(kUploadData, response_data);
6652}
6653
[email protected]2df19bb2010-08-25 20:13:466654// Test the challenge-response-retry sequence through an HTTPS Proxy
bncd16676a2016-07-20 16:23:016655TEST_F(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:466656 HttpRequestInfo request;
6657 request.method = "GET";
bncce36dca22015-04-21 22:11:236658 request.url = GURL("http://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:466659 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:296660 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:106661 request.traffic_annotation =
6662 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:466663
[email protected]79cb5c12011-09-12 13:12:046664 // Configure against https proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496665 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6666 "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:516667 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076668 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:096669 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276670
[email protected]2df19bb2010-08-25 20:13:466671 // Since we have proxy, should use full url
6672 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:166673 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
6674 "Host: www.example.org\r\n"
6675 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:466676
bnc691fda62016-08-12 00:43:166677 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:236678 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:166679 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
6680 "Host: www.example.org\r\n"
6681 "Proxy-Connection: keep-alive\r\n"
6682 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:466683 };
6684
6685 // The proxy responds to the GET with a 407, using a persistent
6686 // connection.
6687 MockRead data_reads1[] = {
6688 // No credentials.
6689 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
6690 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6691 MockRead("Proxy-Connection: keep-alive\r\n"),
6692 MockRead("Content-Length: 0\r\n\r\n"),
6693
6694 MockRead("HTTP/1.1 200 OK\r\n"),
6695 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6696 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066697 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:466698 };
6699
Ryan Sleevib8d7ea02018-05-07 20:01:016700 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:076701 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:066702 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076703 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:466704
[email protected]49639fa2011-12-20 23:22:416705 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:466706
bnc691fda62016-08-12 00:43:166707 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506708
bnc691fda62016-08-12 00:43:166709 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:016710 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:466711
6712 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016713 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:466714
[email protected]58e32bb2013-01-21 18:23:256715 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:166716 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:256717 TestLoadTimingNotReused(load_timing_info,
6718 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6719
bnc691fda62016-08-12 00:43:166720 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526721 ASSERT_TRUE(response);
6722 ASSERT_TRUE(response->headers);
[email protected]2df19bb2010-08-25 20:13:466723 EXPECT_EQ(407, response->headers->response_code());
6724 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
asanka098c0092016-06-16 20:18:436725 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:466726
[email protected]49639fa2011-12-20 23:22:416727 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:466728
bnc691fda62016-08-12 00:43:166729 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:016730 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:466731
6732 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016733 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:466734
[email protected]58e32bb2013-01-21 18:23:256735 load_timing_info = LoadTimingInfo();
bnc691fda62016-08-12 00:43:166736 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:256737 // Retrying with HTTP AUTH is considered to be reusing a socket.
6738 TestLoadTimingReused(load_timing_info);
6739
bnc691fda62016-08-12 00:43:166740 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526741 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:466742
6743 EXPECT_TRUE(response->headers->IsKeepAlive());
6744 EXPECT_EQ(200, response->headers->response_code());
6745 EXPECT_EQ(100, response->headers->GetContentLength());
6746 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6747
6748 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:526749 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:466750}
6751
[email protected]23e482282013-06-14 16:08:026752void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:086753 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:426754 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:086755 request.method = "GET";
bncce36dca22015-04-21 22:11:236756 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:106757 request.traffic_annotation =
6758 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]c744cf22009-02-27 07:28:086759
[email protected]cb9bf6ca2011-01-28 13:15:276760 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496761 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6762 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:096763 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276764
[email protected]c744cf22009-02-27 07:28:086765 // Since we have proxy, should try to establish tunnel.
6766 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:176767 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
6768 "Host: www.example.org:443\r\n"
6769 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:086770 };
6771
6772 MockRead data_reads[] = {
mmenked39192ee2015-12-09 00:57:236773 status, MockRead("Content-Length: 10\r\n\r\n"),
6774 // No response body because the test stops reading here.
6775 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]c744cf22009-02-27 07:28:086776 };
6777
Ryan Sleevib8d7ea02018-05-07 20:01:016778 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:076779 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:086780
[email protected]49639fa2011-12-20 23:22:416781 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:086782
bnc691fda62016-08-12 00:43:166783 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506784
tfarina42834112016-09-22 13:38:206785 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016786 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]c744cf22009-02-27 07:28:086787
6788 rv = callback.WaitForResult();
6789 EXPECT_EQ(expected_status, rv);
6790}
6791
[email protected]23e482282013-06-14 16:08:026792void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:236793 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:086794 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:426795 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:086796}
6797
bncd16676a2016-07-20 16:23:016798TEST_F(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:086799 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
6800}
6801
bncd16676a2016-07-20 16:23:016802TEST_F(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:086803 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
6804}
6805
bncd16676a2016-07-20 16:23:016806TEST_F(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:086807 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
6808}
6809
bncd16676a2016-07-20 16:23:016810TEST_F(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:086811 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
6812}
6813
bncd16676a2016-07-20 16:23:016814TEST_F(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:086815 ConnectStatusHelper(
6816 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
6817}
6818
bncd16676a2016-07-20 16:23:016819TEST_F(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:086820 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
6821}
6822
bncd16676a2016-07-20 16:23:016823TEST_F(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:086824 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
6825}
6826
bncd16676a2016-07-20 16:23:016827TEST_F(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:086828 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
6829}
6830
bncd16676a2016-07-20 16:23:016831TEST_F(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:086832 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
6833}
6834
bncd16676a2016-07-20 16:23:016835TEST_F(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:086836 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
6837}
6838
bncd16676a2016-07-20 16:23:016839TEST_F(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:086840 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
6841}
6842
bncd16676a2016-07-20 16:23:016843TEST_F(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:086844 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
6845}
6846
bncd16676a2016-07-20 16:23:016847TEST_F(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:086848 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
6849}
6850
bncd16676a2016-07-20 16:23:016851TEST_F(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:086852 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
6853}
6854
bncd16676a2016-07-20 16:23:016855TEST_F(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:086856 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
6857}
6858
bncd16676a2016-07-20 16:23:016859TEST_F(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:086860 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
6861}
6862
bncd16676a2016-07-20 16:23:016863TEST_F(HttpNetworkTransactionTest, ConnectStatus308) {
[email protected]0a17aab32014-04-24 03:32:376864 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
6865}
6866
bncd16676a2016-07-20 16:23:016867TEST_F(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:086868 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
6869}
6870
bncd16676a2016-07-20 16:23:016871TEST_F(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:086872 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
6873}
6874
bncd16676a2016-07-20 16:23:016875TEST_F(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:086876 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
6877}
6878
bncd16676a2016-07-20 16:23:016879TEST_F(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:086880 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
6881}
6882
bncd16676a2016-07-20 16:23:016883TEST_F(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:086884 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
6885}
6886
bncd16676a2016-07-20 16:23:016887TEST_F(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:086888 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
6889}
6890
bncd16676a2016-07-20 16:23:016891TEST_F(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:086892 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
6893}
6894
bncd16676a2016-07-20 16:23:016895TEST_F(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:086896 ConnectStatusHelperWithExpectedStatus(
6897 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:546898 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:086899}
6900
bncd16676a2016-07-20 16:23:016901TEST_F(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:086902 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
6903}
6904
bncd16676a2016-07-20 16:23:016905TEST_F(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:086906 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
6907}
6908
bncd16676a2016-07-20 16:23:016909TEST_F(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:086910 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
6911}
6912
bncd16676a2016-07-20 16:23:016913TEST_F(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:086914 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
6915}
6916
bncd16676a2016-07-20 16:23:016917TEST_F(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:086918 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
6919}
6920
bncd16676a2016-07-20 16:23:016921TEST_F(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:086922 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
6923}
6924
bncd16676a2016-07-20 16:23:016925TEST_F(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:086926 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
6927}
6928
bncd16676a2016-07-20 16:23:016929TEST_F(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:086930 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
6931}
6932
bncd16676a2016-07-20 16:23:016933TEST_F(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:086934 ConnectStatusHelper(
6935 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
6936}
6937
bncd16676a2016-07-20 16:23:016938TEST_F(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:086939 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
6940}
6941
bncd16676a2016-07-20 16:23:016942TEST_F(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:086943 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
6944}
6945
bncd16676a2016-07-20 16:23:016946TEST_F(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:086947 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
6948}
6949
bncd16676a2016-07-20 16:23:016950TEST_F(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:086951 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
6952}
6953
bncd16676a2016-07-20 16:23:016954TEST_F(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:086955 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
6956}
6957
bncd16676a2016-07-20 16:23:016958TEST_F(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:086959 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
6960}
6961
bncd16676a2016-07-20 16:23:016962TEST_F(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:086963 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
6964}
6965
[email protected]038e9a32008-10-08 22:40:166966// Test the flow when both the proxy server AND origin server require
6967// authentication. Again, this uses basic auth for both since that is
6968// the simplest to mock.
bncd16676a2016-07-20 16:23:016969TEST_F(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:276970 HttpRequestInfo request;
6971 request.method = "GET";
bncce36dca22015-04-21 22:11:236972 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:106973 request.traffic_annotation =
6974 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:276975
[email protected]038e9a32008-10-08 22:40:166976 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496977 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6978 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:096979 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:076980
bnc691fda62016-08-12 00:43:166981 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]038e9a32008-10-08 22:40:166982
[email protected]f9ee6b52008-11-08 06:46:236983 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236984 MockWrite(
6985 "GET http://www.example.org/ HTTP/1.1\r\n"
6986 "Host: www.example.org\r\n"
6987 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236988 };
6989
[email protected]038e9a32008-10-08 22:40:166990 MockRead data_reads1[] = {
6991 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
6992 // Give a couple authenticate options (only the middle one is actually
6993 // supported).
[email protected]22927ad2009-09-21 19:56:196994 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:166995 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6996 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
6997 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6998 // Large content-length -- won't matter, as connection will be reset.
6999 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067000 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:167001 };
7002
bnc691fda62016-08-12 00:43:167003 // After calling trans.RestartWithAuth() the first time, this is the
[email protected]038e9a32008-10-08 22:40:167004 // request we should be issuing -- the final header line contains the
7005 // proxy's credentials.
7006 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237007 MockWrite(
7008 "GET http://www.example.org/ HTTP/1.1\r\n"
7009 "Host: www.example.org\r\n"
7010 "Proxy-Connection: keep-alive\r\n"
7011 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:167012 };
7013
7014 // Now the proxy server lets the request pass through to origin server.
7015 // The origin server responds with a 401.
7016 MockRead data_reads2[] = {
7017 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7018 // Note: We are using the same realm-name as the proxy server. This is
7019 // completely valid, as realms are unique across hosts.
7020 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7021 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7022 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067023 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:167024 };
7025
bnc691fda62016-08-12 00:43:167026 // After calling trans.RestartWithAuth() the second time, we should send
[email protected]038e9a32008-10-08 22:40:167027 // the credentials for both the proxy and origin server.
7028 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237029 MockWrite(
7030 "GET http://www.example.org/ HTTP/1.1\r\n"
7031 "Host: www.example.org\r\n"
7032 "Proxy-Connection: keep-alive\r\n"
7033 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
7034 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:167035 };
7036
7037 // Lastly we get the desired content.
7038 MockRead data_reads3[] = {
7039 MockRead("HTTP/1.0 200 OK\r\n"),
7040 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7041 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067042 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:167043 };
7044
Ryan Sleevib8d7ea02018-05-07 20:01:017045 StaticSocketDataProvider data1(data_reads1, data_writes1);
7046 StaticSocketDataProvider data2(data_reads2, data_writes2);
7047 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]bb88e1d32013-05-03 23:11:077048 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7049 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7050 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:167051
[email protected]49639fa2011-12-20 23:22:417052 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:167053
tfarina42834112016-09-22 13:38:207054 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017055 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:167056
7057 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017058 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:167059
bnc691fda62016-08-12 00:43:167060 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527061 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047062 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:167063
[email protected]49639fa2011-12-20 23:22:417064 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:167065
bnc691fda62016-08-12 00:43:167066 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:017067 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:167068
7069 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017070 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:167071
bnc691fda62016-08-12 00:43:167072 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527073 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047074 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:167075
[email protected]49639fa2011-12-20 23:22:417076 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:167077
bnc691fda62016-08-12 00:43:167078 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
7079 callback3.callback());
robpercival214763f2016-07-01 23:27:017080 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:167081
7082 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017083 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:167084
bnc691fda62016-08-12 00:43:167085 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527086 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:167087 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:167088}
[email protected]4ddaf2502008-10-23 18:26:197089
[email protected]ea9dc9a2009-09-05 00:43:327090// For the NTLM implementation using SSPI, we skip the NTLM tests since we
7091// can't hook into its internals to cause it to generate predictable NTLM
7092// authorization headers.
7093#if defined(NTLM_PORTABLE)
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377094// The NTLM authentication unit tests are based on known test data from the
7095// [MS-NLMP] Specification [1]. These tests are primarily of the authentication
7096// flow rather than the implementation of the NTLM protocol. See net/ntlm
7097// for the implementation and testing of the protocol.
7098//
7099// [1] https://msdn.microsoft.com/en-us/library/cc236621.aspx
[email protected]385a4672009-03-11 22:21:297100
7101// Enter the correct password and authenticate successfully.
Zentaro Kavanagh1890a3d2018-01-29 19:52:557102TEST_F(HttpNetworkTransactionTest, NTLMAuthV2) {
[email protected]1c773ea12009-04-28 19:58:427103 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:247104 request.method = "GET";
Zentaro Kavanagh1890a3d2018-01-29 19:52:557105 request.url = GURL("https://server/kids/login.aspx");
Ramin Halavatib5e433e2018-02-07 07:41:107106 request.traffic_annotation =
7107 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2217aa22013-10-11 03:03:547108
7109 // Ensure load is not disrupted by flags which suppress behaviour specific
7110 // to other auth schemes.
7111 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:247112
Zentaro Kavanagh6ccee512017-09-28 18:34:097113 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
7114 MockGetMSTime, MockGenerateRandom, MockGetHostName);
danakj1fd259a02016-04-16 03:17:097115 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277116
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377117 // Generate the NTLM messages based on known test data.
7118 std::string negotiate_msg;
7119 std::string challenge_msg;
7120 std::string authenticate_msg;
7121 base::Base64Encode(
7122 base::StringPiece(
7123 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
Avi Drissman4365a4782018-12-28 19:26:247124 base::size(ntlm::test::kExpectedNegotiateMsg)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377125 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:557126 base::Base64Encode(
7127 base::StringPiece(
7128 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
Avi Drissman4365a4782018-12-28 19:26:247129 base::size(ntlm::test::kChallengeMsgFromSpecV2)),
Zentaro Kavanagh1890a3d2018-01-29 19:52:557130 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377131 base::Base64Encode(
7132 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:097133 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557134 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
Avi Drissman4365a4782018-12-28 19:26:247135 base::size(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557136 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377137 &authenticate_msg);
7138
[email protected]3f918782009-02-28 01:29:247139 MockWrite data_writes1[] = {
Zentaro Kavanagh1890a3d2018-01-29 19:52:557140 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
7141 "Host: server\r\n"
7142 "Connection: keep-alive\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:247143 };
7144
7145 MockRead data_reads1[] = {
7146 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:047147 // Negotiate and NTLM are often requested together. However, we only want
7148 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
7149 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:247150 MockRead("WWW-Authenticate: NTLM\r\n"),
7151 MockRead("Connection: close\r\n"),
7152 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:367153 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:247154 // Missing content -- won't matter, as connection will be reset.
[email protected]3f918782009-02-28 01:29:247155 };
7156
7157 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:167158 // After restarting with a null identity, this is the
7159 // request we should be issuing -- the final header line contains a Type
7160 // 1 message.
7161 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557162 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167163 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377164 "Authorization: NTLM "),
7165 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:247166
bnc691fda62016-08-12 00:43:167167 // After calling trans.RestartWithAuth(), we should send a Type 3 message
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377168 // (using correct credentials). The second request continues on the
7169 // same connection.
bnc691fda62016-08-12 00:43:167170 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557171 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167172 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377173 "Authorization: NTLM "),
7174 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:247175 };
7176
7177 MockRead data_reads2[] = {
Bence Béky1e4ef192017-09-18 19:58:027178 // The origin server responds with a Type 2 message.
7179 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377180 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
7181 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky1e4ef192017-09-18 19:58:027182 MockRead("Content-Type: text/html\r\n\r\n"),
7183 MockRead("You are not authorized to view this page\r\n"),
[email protected]3f918782009-02-28 01:29:247184
Bence Béky1e4ef192017-09-18 19:58:027185 // Lastly we get the desired content.
7186 MockRead("HTTP/1.1 200 OK\r\n"),
7187 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
7188 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
[email protected]3f918782009-02-28 01:29:247189 };
7190
Ryan Sleevib8d7ea02018-05-07 20:01:017191 StaticSocketDataProvider data1(data_reads1, data_writes1);
7192 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:077193 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7194 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:247195
Bence Béky83eb3512017-09-05 12:56:097196 SSLSocketDataProvider ssl1(ASYNC, OK);
7197 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
7198 SSLSocketDataProvider ssl2(ASYNC, OK);
7199 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
7200
[email protected]49639fa2011-12-20 23:22:417201 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:247202
bnc691fda62016-08-12 00:43:167203 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:507204
tfarina42834112016-09-22 13:38:207205 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017206 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:247207
7208 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017209 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:247210
bnc691fda62016-08-12 00:43:167211 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227212
bnc691fda62016-08-12 00:43:167213 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527214 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047215 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:247216
[email protected]49639fa2011-12-20 23:22:417217 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:257218
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377219 rv = trans.RestartWithAuth(
7220 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
7221 callback2.callback());
robpercival214763f2016-07-01 23:27:017222 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:257223
7224 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017225 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:257226
bnc691fda62016-08-12 00:43:167227 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:257228
bnc691fda62016-08-12 00:43:167229 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527230 ASSERT_TRUE(response);
7231 EXPECT_FALSE(response->auth_challenge);
[email protected]10af5fe72011-01-31 16:17:257232
[email protected]49639fa2011-12-20 23:22:417233 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:247234
bnc691fda62016-08-12 00:43:167235 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:017236 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:247237
[email protected]0757e7702009-03-27 04:00:227238 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017239 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:247240
bnc691fda62016-08-12 00:43:167241 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527242 ASSERT_TRUE(response);
7243 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:027244 EXPECT_EQ(14, response->headers->GetContentLength());
7245
7246 std::string response_data;
7247 rv = ReadTransaction(&trans, &response_data);
7248 EXPECT_THAT(rv, IsOk());
7249 EXPECT_EQ("Please Login\r\n", response_data);
7250
7251 EXPECT_TRUE(data1.AllReadDataConsumed());
7252 EXPECT_TRUE(data1.AllWriteDataConsumed());
7253 EXPECT_TRUE(data2.AllReadDataConsumed());
7254 EXPECT_TRUE(data2.AllWriteDataConsumed());
[email protected]3f918782009-02-28 01:29:247255}
7256
[email protected]385a4672009-03-11 22:21:297257// Enter a wrong password, and then the correct one.
Zentaro Kavanagh1890a3d2018-01-29 19:52:557258TEST_F(HttpNetworkTransactionTest, NTLMAuthV2WrongThenRightPassword) {
[email protected]1c773ea12009-04-28 19:58:427259 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:297260 request.method = "GET";
Zentaro Kavanagh1890a3d2018-01-29 19:52:557261 request.url = GURL("https://server/kids/login.aspx");
Ramin Halavatib5e433e2018-02-07 07:41:107262 request.traffic_annotation =
7263 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]385a4672009-03-11 22:21:297264
Zentaro Kavanagh6ccee512017-09-28 18:34:097265 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
7266 MockGetMSTime, MockGenerateRandom, MockGetHostName);
danakj1fd259a02016-04-16 03:17:097267 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277268
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377269 // Generate the NTLM messages based on known test data.
7270 std::string negotiate_msg;
7271 std::string challenge_msg;
7272 std::string authenticate_msg;
7273 base::Base64Encode(
7274 base::StringPiece(
7275 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
Avi Drissman4365a4782018-12-28 19:26:247276 base::size(ntlm::test::kExpectedNegotiateMsg)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377277 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:557278 base::Base64Encode(
7279 base::StringPiece(
7280 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
Avi Drissman4365a4782018-12-28 19:26:247281 base::size(ntlm::test::kChallengeMsgFromSpecV2)),
Zentaro Kavanagh1890a3d2018-01-29 19:52:557282 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377283 base::Base64Encode(
7284 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:097285 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557286 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
Avi Drissman4365a4782018-12-28 19:26:247287 base::size(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557288 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377289 &authenticate_msg);
7290
7291 // The authenticate message when |kWrongPassword| is sent.
7292 std::string wrong_password_authenticate_msg(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557293 "TlRMTVNTUAADAAAAGAAYAFgAAACKAIoAcAAAAAwADAD6AAAACAAIAAYBAAAQABAADgEAAAAA"
7294 "AABYAAAAA4IIAAAAAAAAAAAAAPknEYqtJQtusopDRSfYzAAAAAAAAAAAAAAAAAAAAAAAAAAA"
7295 "AAAAAOtVz38osnFdRRggUQHUJ3EBAQAAAAAAAIALyP0A1NIBqqqqqqqqqqoAAAAAAgAMAEQA"
7296 "bwBtAGEAaQBuAAEADABTAGUAcgB2AGUAcgAGAAQAAgAAAAoAEAAAAAAAAAAAAAAAAAAAAAAA"
7297 "CQAWAEgAVABUAFAALwBzAGUAcgB2AGUAcgAAAAAAAAAAAEQAbwBtAGEAaQBuAFUAcwBlAHIA"
7298 "QwBPAE0AUABVAFQARQBSAA==");
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377299
Zentaro Kavanagh1890a3d2018-01-29 19:52:557300 // Sanity check that it's the same length as the correct authenticate message
7301 // and that it's different.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377302 ASSERT_EQ(authenticate_msg.length(),
7303 wrong_password_authenticate_msg.length());
Zentaro Kavanagh1890a3d2018-01-29 19:52:557304 ASSERT_NE(authenticate_msg, wrong_password_authenticate_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377305
[email protected]385a4672009-03-11 22:21:297306 MockWrite data_writes1[] = {
Zentaro Kavanagh1890a3d2018-01-29 19:52:557307 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
7308 "Host: server\r\n"
7309 "Connection: keep-alive\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297310 };
7311
7312 MockRead data_reads1[] = {
7313 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:047314 // Negotiate and NTLM are often requested together. However, we only want
7315 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
7316 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:297317 MockRead("WWW-Authenticate: NTLM\r\n"),
7318 MockRead("Connection: close\r\n"),
7319 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:367320 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297321 // Missing content -- won't matter, as connection will be reset.
[email protected]385a4672009-03-11 22:21:297322 };
7323
7324 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:167325 // After restarting with a null identity, this is the
7326 // request we should be issuing -- the final header line contains a Type
7327 // 1 message.
7328 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557329 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167330 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377331 "Authorization: NTLM "),
7332 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297333
bnc691fda62016-08-12 00:43:167334 // After calling trans.RestartWithAuth(), we should send a Type 3 message
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377335 // (using incorrect credentials). The second request continues on the
7336 // same connection.
bnc691fda62016-08-12 00:43:167337 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557338 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167339 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377340 "Authorization: NTLM "),
7341 MockWrite(wrong_password_authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297342 };
7343
7344 MockRead data_reads2[] = {
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377345 // The origin server responds with a Type 2 message.
7346 MockRead("HTTP/1.1 401 Access Denied\r\n"),
7347 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
7348 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
7349 MockRead("Content-Type: text/html\r\n\r\n"),
7350 MockRead("You are not authorized to view this page\r\n"),
[email protected]385a4672009-03-11 22:21:297351
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377352 // Wrong password.
7353 MockRead("HTTP/1.1 401 Access Denied\r\n"),
7354 MockRead("WWW-Authenticate: NTLM\r\n"), MockRead("Connection: close\r\n"),
7355 MockRead("Content-Length: 42\r\n"),
7356 MockRead("Content-Type: text/html\r\n\r\n"),
7357 // Missing content -- won't matter, as connection will be reset.
[email protected]385a4672009-03-11 22:21:297358 };
7359
7360 MockWrite data_writes3[] = {
bnc691fda62016-08-12 00:43:167361 // After restarting with a null identity, this is the
7362 // request we should be issuing -- the final header line contains a Type
7363 // 1 message.
7364 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557365 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167366 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377367 "Authorization: NTLM "),
7368 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297369
bnc691fda62016-08-12 00:43:167370 // After calling trans.RestartWithAuth(), we should send a Type 3 message
7371 // (the credentials for the origin server). The second request continues
7372 // on the same connection.
7373 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557374 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167375 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377376 "Authorization: NTLM "),
7377 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297378 };
7379
7380 MockRead data_reads3[] = {
Bence Béky1e4ef192017-09-18 19:58:027381 // The origin server responds with a Type 2 message.
7382 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377383 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
7384 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky1e4ef192017-09-18 19:58:027385 MockRead("Content-Type: text/html\r\n\r\n"),
7386 MockRead("You are not authorized to view this page\r\n"),
[email protected]385a4672009-03-11 22:21:297387
Bence Béky1e4ef192017-09-18 19:58:027388 // Lastly we get the desired content.
7389 MockRead("HTTP/1.1 200 OK\r\n"),
7390 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
7391 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
[email protected]385a4672009-03-11 22:21:297392 };
7393
Ryan Sleevib8d7ea02018-05-07 20:01:017394 StaticSocketDataProvider data1(data_reads1, data_writes1);
7395 StaticSocketDataProvider data2(data_reads2, data_writes2);
7396 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]bb88e1d32013-05-03 23:11:077397 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7398 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7399 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:297400
Bence Béky83eb3512017-09-05 12:56:097401 SSLSocketDataProvider ssl1(ASYNC, OK);
7402 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
7403 SSLSocketDataProvider ssl2(ASYNC, OK);
7404 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
7405 SSLSocketDataProvider ssl3(ASYNC, OK);
7406 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
7407
[email protected]49639fa2011-12-20 23:22:417408 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:297409
bnc691fda62016-08-12 00:43:167410 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:507411
tfarina42834112016-09-22 13:38:207412 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017413 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:297414
7415 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017416 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:297417
bnc691fda62016-08-12 00:43:167418 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:297419
bnc691fda62016-08-12 00:43:167420 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527421 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047422 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:297423
[email protected]49639fa2011-12-20 23:22:417424 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:297425
[email protected]0757e7702009-03-27 04:00:227426 // Enter the wrong password.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377427 rv = trans.RestartWithAuth(
7428 AuthCredentials(ntlm::test::kDomainUserCombined, kWrongPassword),
7429 callback2.callback());
robpercival214763f2016-07-01 23:27:017430 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:297431
[email protected]10af5fe72011-01-31 16:17:257432 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017433 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:297434
bnc691fda62016-08-12 00:43:167435 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:417436 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:167437 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:017438 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:257439 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017440 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167441 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227442
bnc691fda62016-08-12 00:43:167443 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527444 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047445 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:227446
[email protected]49639fa2011-12-20 23:22:417447 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:227448
7449 // Now enter the right password.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377450 rv = trans.RestartWithAuth(
7451 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
7452 callback4.callback());
robpercival214763f2016-07-01 23:27:017453 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:257454
7455 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:017456 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:257457
bnc691fda62016-08-12 00:43:167458 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:257459
[email protected]49639fa2011-12-20 23:22:417460 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:257461
7462 // One more roundtrip
bnc691fda62016-08-12 00:43:167463 rv = trans.RestartWithAuth(AuthCredentials(), callback5.callback());
robpercival214763f2016-07-01 23:27:017464 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:227465
7466 rv = callback5.WaitForResult();
robpercival214763f2016-07-01 23:27:017467 EXPECT_THAT(rv, IsOk());
[email protected]0757e7702009-03-27 04:00:227468
bnc691fda62016-08-12 00:43:167469 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527470 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:027471 EXPECT_EQ(14, response->headers->GetContentLength());
7472
7473 std::string response_data;
7474 rv = ReadTransaction(&trans, &response_data);
7475 EXPECT_THAT(rv, IsOk());
7476 EXPECT_EQ("Please Login\r\n", response_data);
7477
7478 EXPECT_TRUE(data1.AllReadDataConsumed());
7479 EXPECT_TRUE(data1.AllWriteDataConsumed());
7480 EXPECT_TRUE(data2.AllReadDataConsumed());
7481 EXPECT_TRUE(data2.AllWriteDataConsumed());
7482 EXPECT_TRUE(data3.AllReadDataConsumed());
7483 EXPECT_TRUE(data3.AllWriteDataConsumed());
[email protected]385a4672009-03-11 22:21:297484}
Bence Béky83eb3512017-09-05 12:56:097485
Bence Béky3238f2e12017-09-22 22:44:497486// Server requests NTLM authentication, which is not supported over HTTP/2.
7487// Subsequent request with authorization header should be sent over HTTP/1.1.
Bence Béky83eb3512017-09-05 12:56:097488TEST_F(HttpNetworkTransactionTest, NTLMOverHttp2) {
Zentaro Kavanagh6ccee512017-09-28 18:34:097489 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
7490 MockGetMSTime, MockGenerateRandom, MockGetHostName);
Bence Béky83eb3512017-09-05 12:56:097491
Zentaro Kavanagh1890a3d2018-01-29 19:52:557492 const char* kUrl = "https://server/kids/login.aspx";
Bence Béky83eb3512017-09-05 12:56:097493
7494 HttpRequestInfo request;
7495 request.method = "GET";
7496 request.url = GURL(kUrl);
Ramin Halavatib5e433e2018-02-07 07:41:107497 request.traffic_annotation =
7498 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Béky83eb3512017-09-05 12:56:097499
7500 // First request without credentials.
Ryan Hamilton0239aac2018-05-19 00:03:137501 spdy::SpdyHeaderBlock request_headers0(
7502 spdy_util_.ConstructGetHeaderBlock(kUrl));
7503 spdy::SpdySerializedFrame request0(spdy_util_.ConstructSpdyHeaders(
Bence Béky83eb3512017-09-05 12:56:097504 1, std::move(request_headers0), LOWEST, true));
7505
Ryan Hamilton0239aac2018-05-19 00:03:137506 spdy::SpdyHeaderBlock response_headers0;
7507 response_headers0[spdy::kHttp2StatusHeader] = "401";
Bence Béky83eb3512017-09-05 12:56:097508 response_headers0["www-authenticate"] = "NTLM";
Ryan Hamilton0239aac2018-05-19 00:03:137509 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyResponseHeaders(
Bence Béky83eb3512017-09-05 12:56:097510 1, std::move(response_headers0), true));
7511
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377512 // Stream 1 is closed.
7513 spdy_util_.UpdateWithStreamDestruction(1);
7514
7515 // Generate the NTLM messages based on known test data.
7516 std::string negotiate_msg;
7517 std::string challenge_msg;
7518 std::string authenticate_msg;
7519 base::Base64Encode(
7520 base::StringPiece(
7521 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
Avi Drissman4365a4782018-12-28 19:26:247522 base::size(ntlm::test::kExpectedNegotiateMsg)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377523 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:557524 base::Base64Encode(
7525 base::StringPiece(
7526 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
Avi Drissman4365a4782018-12-28 19:26:247527 base::size(ntlm::test::kChallengeMsgFromSpecV2)),
Zentaro Kavanagh1890a3d2018-01-29 19:52:557528 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377529 base::Base64Encode(
7530 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:097531 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557532 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
Avi Drissman4365a4782018-12-28 19:26:247533 base::size(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557534 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377535 &authenticate_msg);
7536
7537 // Retry with authorization header.
Ryan Hamilton0239aac2018-05-19 00:03:137538 spdy::SpdyHeaderBlock request_headers1(
7539 spdy_util_.ConstructGetHeaderBlock(kUrl));
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377540 request_headers1["authorization"] = std::string("NTLM ") + negotiate_msg;
Ryan Hamilton0239aac2018-05-19 00:03:137541 spdy::SpdySerializedFrame request1(spdy_util_.ConstructSpdyHeaders(
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377542 3, std::move(request_headers1), LOWEST, true));
7543
Ryan Hamilton0239aac2018-05-19 00:03:137544 spdy::SpdySerializedFrame rst(
7545 spdy_util_.ConstructSpdyRstStream(3, spdy::ERROR_CODE_HTTP_1_1_REQUIRED));
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377546
Bence Béky3238f2e12017-09-22 22:44:497547 MockWrite writes0[] = {CreateMockWrite(request0, 0)};
7548 MockRead reads0[] = {CreateMockRead(resp, 1), MockRead(ASYNC, 0, 2)};
Bence Béky83eb3512017-09-05 12:56:097549
7550 // Retry yet again using HTTP/1.1.
7551 MockWrite writes1[] = {
7552 // After restarting with a null identity, this is the
7553 // request we should be issuing -- the final header line contains a Type
7554 // 1 message.
7555 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557556 "Host: server\r\n"
Bence Béky83eb3512017-09-05 12:56:097557 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377558 "Authorization: NTLM "),
7559 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
Bence Béky83eb3512017-09-05 12:56:097560
7561 // After calling trans.RestartWithAuth(), we should send a Type 3 message
7562 // (the credentials for the origin server). The second request continues
7563 // on the same connection.
7564 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557565 "Host: server\r\n"
Bence Béky83eb3512017-09-05 12:56:097566 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377567 "Authorization: NTLM "),
7568 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
Bence Béky83eb3512017-09-05 12:56:097569 };
7570
7571 MockRead reads1[] = {
7572 // The origin server responds with a Type 2 message.
7573 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377574 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
7575 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky83eb3512017-09-05 12:56:097576 MockRead("Content-Type: text/html\r\n\r\n"),
7577 MockRead("You are not authorized to view this page\r\n"),
7578
7579 // Lastly we get the desired content.
7580 MockRead("HTTP/1.1 200 OK\r\n"),
7581 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
Bence Béky1e4ef192017-09-18 19:58:027582 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
Bence Béky83eb3512017-09-05 12:56:097583 };
Ryan Sleevib8d7ea02018-05-07 20:01:017584 SequencedSocketData data0(reads0, writes0);
7585 StaticSocketDataProvider data1(reads1, writes1);
Bence Béky83eb3512017-09-05 12:56:097586 session_deps_.socket_factory->AddSocketDataProvider(&data0);
7587 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7588
7589 SSLSocketDataProvider ssl0(ASYNC, OK);
7590 ssl0.next_proto = kProtoHTTP2;
7591 SSLSocketDataProvider ssl1(ASYNC, OK);
7592 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl0);
7593 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
7594
7595 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7596 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
7597
7598 TestCompletionCallback callback1;
7599 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
7600 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7601
7602 rv = callback1.WaitForResult();
7603 EXPECT_THAT(rv, IsOk());
7604
7605 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
7606
7607 const HttpResponseInfo* response = trans.GetResponseInfo();
7608 ASSERT_TRUE(response);
7609 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
7610
7611 TestCompletionCallback callback2;
7612
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377613 rv = trans.RestartWithAuth(
7614 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
7615 callback2.callback());
Bence Béky83eb3512017-09-05 12:56:097616 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7617
7618 rv = callback2.WaitForResult();
7619 EXPECT_THAT(rv, IsOk());
7620
7621 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
7622
7623 response = trans.GetResponseInfo();
7624 ASSERT_TRUE(response);
7625 EXPECT_FALSE(response->auth_challenge);
7626
7627 TestCompletionCallback callback3;
7628
7629 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
7630 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7631
7632 rv = callback3.WaitForResult();
7633 EXPECT_THAT(rv, IsOk());
7634
7635 response = trans.GetResponseInfo();
7636 ASSERT_TRUE(response);
7637 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:027638 EXPECT_EQ(14, response->headers->GetContentLength());
7639
7640 std::string response_data;
7641 rv = ReadTransaction(&trans, &response_data);
7642 EXPECT_THAT(rv, IsOk());
7643 EXPECT_EQ("Please Login\r\n", response_data);
7644
7645 EXPECT_TRUE(data0.AllReadDataConsumed());
7646 EXPECT_TRUE(data0.AllWriteDataConsumed());
7647 EXPECT_TRUE(data1.AllReadDataConsumed());
7648 EXPECT_TRUE(data1.AllWriteDataConsumed());
Bence Béky83eb3512017-09-05 12:56:097649}
David Benjamin5cb91132018-04-06 05:54:497650
7651// Test that, if we have an NTLM proxy and the origin resets the connection, we
7652// do no retry forever checking for TLS version interference. This is a
7653// regression test for https://crbug.com/823387.
7654TEST_F(HttpNetworkTransactionTest, NTLMProxyTLSHandshakeReset) {
7655 // The NTLM test data expects the proxy to be named 'server'. The origin is
7656 // https://origin/.
7657 session_deps_.proxy_resolution_service =
7658 ProxyResolutionService::CreateFixedFromPacResult(
7659 "PROXY server", TRAFFIC_ANNOTATION_FOR_TESTS);
7660
7661 SSLConfig config;
David Benjamin5cb91132018-04-06 05:54:497662 session_deps_.ssl_config_service =
Ryan Sleevib8449e02018-07-15 04:31:077663 std::make_unique<TestSSLConfigService>(config);
David Benjamin5cb91132018-04-06 05:54:497664
7665 HttpRequestInfo request;
7666 request.method = "GET";
7667 request.url = GURL("https://origin/");
7668 request.traffic_annotation =
7669 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7670
7671 // Ensure load is not disrupted by flags which suppress behaviour specific
7672 // to other auth schemes.
7673 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
7674
7675 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
7676 MockGetMSTime, MockGenerateRandom, MockGetHostName);
7677 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7678
7679 // Generate the NTLM messages based on known test data.
7680 std::string negotiate_msg;
7681 std::string challenge_msg;
7682 std::string authenticate_msg;
7683 base::Base64Encode(
7684 base::StringPiece(
7685 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
Avi Drissman4365a4782018-12-28 19:26:247686 base::size(ntlm::test::kExpectedNegotiateMsg)),
David Benjamin5cb91132018-04-06 05:54:497687 &negotiate_msg);
7688 base::Base64Encode(
7689 base::StringPiece(
7690 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
Avi Drissman4365a4782018-12-28 19:26:247691 base::size(ntlm::test::kChallengeMsgFromSpecV2)),
David Benjamin5cb91132018-04-06 05:54:497692 &challenge_msg);
7693 base::Base64Encode(
7694 base::StringPiece(
7695 reinterpret_cast<const char*>(
7696 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
Avi Drissman4365a4782018-12-28 19:26:247697 base::size(
David Benjamin5cb91132018-04-06 05:54:497698 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
7699 &authenticate_msg);
7700
7701 MockWrite data_writes[] = {
7702 // The initial CONNECT request.
7703 MockWrite("CONNECT origin:443 HTTP/1.1\r\n"
7704 "Host: origin:443\r\n"
7705 "Proxy-Connection: keep-alive\r\n\r\n"),
7706
7707 // After restarting with an identity.
7708 MockWrite("CONNECT origin:443 HTTP/1.1\r\n"
7709 "Host: origin:443\r\n"
7710 "Proxy-Connection: keep-alive\r\n"
7711 "Proxy-Authorization: NTLM "),
7712 MockWrite(negotiate_msg.c_str()),
7713 // End headers.
7714 MockWrite("\r\n\r\n"),
7715
7716 // The second restart.
7717 MockWrite("CONNECT origin:443 HTTP/1.1\r\n"
7718 "Host: origin:443\r\n"
7719 "Proxy-Connection: keep-alive\r\n"
7720 "Proxy-Authorization: NTLM "),
7721 MockWrite(authenticate_msg.c_str()),
7722 // End headers.
7723 MockWrite("\r\n\r\n"),
7724 };
7725
7726 MockRead data_reads[] = {
7727 // The initial NTLM response.
7728 MockRead("HTTP/1.1 407 Access Denied\r\n"
7729 "Content-Length: 0\r\n"
7730 "Proxy-Authenticate: NTLM\r\n\r\n"),
7731
7732 // The NTLM challenge message.
7733 MockRead("HTTP/1.1 407 Access Denied\r\n"
7734 "Content-Length: 0\r\n"
7735 "Proxy-Authenticate: NTLM "),
7736 MockRead(challenge_msg.c_str()),
7737 // End headers.
7738 MockRead("\r\n\r\n"),
7739
7740 // Finally the tunnel is established.
7741 MockRead("HTTP/1.1 200 Connected\r\n\r\n"),
7742 };
7743
Ryan Sleevib8d7ea02018-05-07 20:01:017744 StaticSocketDataProvider data(data_reads, data_writes);
David Benjamin5cb91132018-04-06 05:54:497745 SSLSocketDataProvider data_ssl(ASYNC, ERR_CONNECTION_RESET);
Ryan Sleevib8d7ea02018-05-07 20:01:017746 StaticSocketDataProvider data2(data_reads, data_writes);
David Benjamin5cb91132018-04-06 05:54:497747 SSLSocketDataProvider data_ssl2(ASYNC, ERR_CONNECTION_RESET);
Steven Valdez0ef94d02018-11-19 23:28:137748 data_ssl2.expected_ssl_version_max = SSL_PROTOCOL_VERSION_TLS1_2;
David Benjamin5cb91132018-04-06 05:54:497749 session_deps_.socket_factory->AddSocketDataProvider(&data);
7750 session_deps_.socket_factory->AddSSLSocketDataProvider(&data_ssl);
7751 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7752 session_deps_.socket_factory->AddSSLSocketDataProvider(&data_ssl2);
7753
7754 // Start the transaction. The proxy responds with an NTLM authentication
7755 // request.
7756 TestCompletionCallback callback;
7757 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
7758 int rv = callback.GetResult(
7759 trans.Start(&request, callback.callback(), NetLogWithSource()));
7760
7761 EXPECT_THAT(rv, IsOk());
7762 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
7763 const HttpResponseInfo* response = trans.GetResponseInfo();
7764 ASSERT_TRUE(response);
7765 EXPECT_TRUE(CheckNTLMProxyAuth(response->auth_challenge.get()));
7766
7767 // Configure credentials. The proxy responds with the challenge message.
7768 rv = callback.GetResult(trans.RestartWithAuth(
7769 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
7770 callback.callback()));
7771 EXPECT_THAT(rv, IsOk());
7772 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
7773 response = trans.GetResponseInfo();
7774 ASSERT_TRUE(response);
7775 EXPECT_FALSE(response->auth_challenge);
7776
7777 // Restart once more. The tunnel will be established and the the SSL handshake
7778 // will reset. The TLS 1.3 version interference probe will then kick in and
7779 // restart the process. The proxy responds with another NTLM authentiation
7780 // request, but we don't need to provide credentials as the cached ones work/
7781 rv = callback.GetResult(
7782 trans.RestartWithAuth(AuthCredentials(), callback.callback()));
7783 EXPECT_THAT(rv, IsOk());
7784 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
7785 response = trans.GetResponseInfo();
7786 ASSERT_TRUE(response);
7787 EXPECT_FALSE(response->auth_challenge);
7788
7789 // The proxy responds with the NTLM challenge message.
7790 rv = callback.GetResult(
7791 trans.RestartWithAuth(AuthCredentials(), callback.callback()));
7792 EXPECT_THAT(rv, IsOk());
7793 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
7794 response = trans.GetResponseInfo();
7795 ASSERT_TRUE(response);
7796 EXPECT_FALSE(response->auth_challenge);
7797
7798 // Send the NTLM authenticate message. The tunnel is established and the
7799 // handshake resets again. We should not retry again.
7800 rv = callback.GetResult(
7801 trans.RestartWithAuth(AuthCredentials(), callback.callback()));
7802 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
7803}
7804
[email protected]ea9dc9a2009-09-05 00:43:327805#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:297806
[email protected]4ddaf2502008-10-23 18:26:197807// Test reading a server response which has only headers, and no body.
7808// After some maximum number of bytes is consumed, the transaction should
7809// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
bncd16676a2016-07-20 16:23:017810TEST_F(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:427811 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:197812 request.method = "GET";
bncce36dca22015-04-21 22:11:237813 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:107814 request.traffic_annotation =
7815 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]4ddaf2502008-10-23 18:26:197816
danakj1fd259a02016-04-16 03:17:097817 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167818 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277819
[email protected]b75b7b2f2009-10-06 00:54:537820 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:437821 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:537822 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:197823
7824 MockRead data_reads[] = {
7825 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:067826 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:197827 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:067828 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:197829 };
Ryan Sleevib8d7ea02018-05-07 20:01:017830 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:077831 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:197832
[email protected]49639fa2011-12-20 23:22:417833 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:197834
tfarina42834112016-09-22 13:38:207835 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017836 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]4ddaf2502008-10-23 18:26:197837
7838 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017839 EXPECT_THAT(rv, IsError(ERR_RESPONSE_HEADERS_TOO_BIG));
[email protected]4ddaf2502008-10-23 18:26:197840}
[email protected]f4e426b2008-11-05 00:24:497841
7842// Make sure that we don't try to reuse a TCPClientSocket when failing to
7843// establish tunnel.
7844// http://code.google.com/p/chromium/issues/detail?id=3772
bncd16676a2016-07-20 16:23:017845TEST_F(HttpNetworkTransactionTest, DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:277846 HttpRequestInfo request;
7847 request.method = "GET";
bncce36dca22015-04-21 22:11:237848 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:107849 request.traffic_annotation =
7850 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:277851
[email protected]f4e426b2008-11-05 00:24:497852 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:497853 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
7854 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]db8f44c2008-12-13 04:52:017855
danakj1fd259a02016-04-16 03:17:097856 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:497857
bnc87dcefc2017-05-25 12:47:587858 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:197859 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]f4e426b2008-11-05 00:24:497860
[email protected]f4e426b2008-11-05 00:24:497861 // Since we have proxy, should try to establish tunnel.
7862 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:177863 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7864 "Host: www.example.org:443\r\n"
7865 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:497866 };
7867
[email protected]77848d12008-11-14 00:00:227868 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:497869 // connection. Usually a proxy would return 501 (not implemented),
7870 // or 200 (tunnel established).
7871 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:237872 MockRead("HTTP/1.1 404 Not Found\r\n"),
7873 MockRead("Content-Length: 10\r\n\r\n"),
7874 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]f4e426b2008-11-05 00:24:497875 };
7876
Ryan Sleevib8d7ea02018-05-07 20:01:017877 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:077878 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:497879
[email protected]49639fa2011-12-20 23:22:417880 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:497881
tfarina42834112016-09-22 13:38:207882 int rv = trans->Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017883 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f4e426b2008-11-05 00:24:497884
7885 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017886 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]f4e426b2008-11-05 00:24:497887
[email protected]b4404c02009-04-10 16:38:527888 // Empty the current queue. This is necessary because idle sockets are
7889 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557890 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:527891
[email protected]f4e426b2008-11-05 00:24:497892 // We now check to make sure the TCPClientSocket was not added back to
7893 // the pool.
[email protected]90499482013-06-01 00:39:507894 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:497895 trans.reset();
fdoray92e35a72016-06-10 15:54:557896 base::RunLoop().RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:497897 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:507898 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:497899}
[email protected]372d34a2008-11-05 21:30:517900
[email protected]1b157c02009-04-21 01:55:407901// Make sure that we recycle a socket after reading all of the response body.
bncd16676a2016-07-20 16:23:017902TEST_F(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:427903 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:407904 request.method = "GET";
bncce36dca22015-04-21 22:11:237905 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:107906 request.traffic_annotation =
7907 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1b157c02009-04-21 01:55:407908
danakj1fd259a02016-04-16 03:17:097909 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277910
bnc691fda62016-08-12 00:43:167911 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277912
[email protected]1b157c02009-04-21 01:55:407913 MockRead data_reads[] = {
7914 // A part of the response body is received with the response headers.
7915 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
7916 // The rest of the response body is received in two parts.
7917 MockRead("lo"),
7918 MockRead(" world"),
7919 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:067920 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:407921 };
7922
Ryan Sleevib8d7ea02018-05-07 20:01:017923 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:077924 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:407925
[email protected]49639fa2011-12-20 23:22:417926 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:407927
tfarina42834112016-09-22 13:38:207928 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017929 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1b157c02009-04-21 01:55:407930
7931 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017932 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:407933
bnc691fda62016-08-12 00:43:167934 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527935 ASSERT_TRUE(response);
[email protected]1b157c02009-04-21 01:55:407936
wezca1070932016-05-26 20:30:527937 EXPECT_TRUE(response->headers);
[email protected]1b157c02009-04-21 01:55:407938 std::string status_line = response->headers->GetStatusLine();
7939 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
7940
[email protected]90499482013-06-01 00:39:507941 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:407942
7943 std::string response_data;
bnc691fda62016-08-12 00:43:167944 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017945 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:407946 EXPECT_EQ("hello world", response_data);
7947
7948 // Empty the current queue. This is necessary because idle sockets are
7949 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557950 base::RunLoop().RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:407951
7952 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507953 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:407954}
7955
[email protected]76a505b2010-08-25 06:23:007956// Make sure that we recycle a SSL socket after reading all of the response
7957// body.
bncd16676a2016-07-20 16:23:017958TEST_F(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:007959 HttpRequestInfo request;
7960 request.method = "GET";
bncce36dca22015-04-21 22:11:237961 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:107962 request.traffic_annotation =
7963 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:007964
7965 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237966 MockWrite(
7967 "GET / HTTP/1.1\r\n"
7968 "Host: www.example.org\r\n"
7969 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:007970 };
7971
7972 MockRead data_reads[] = {
7973 MockRead("HTTP/1.1 200 OK\r\n"),
7974 MockRead("Content-Length: 11\r\n\r\n"),
7975 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:067976 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:007977 };
7978
[email protected]8ddf8322012-02-23 18:08:067979 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077980 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:007981
Ryan Sleevib8d7ea02018-05-07 20:01:017982 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:077983 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:007984
[email protected]49639fa2011-12-20 23:22:417985 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:007986
danakj1fd259a02016-04-16 03:17:097987 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167988 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:007989
tfarina42834112016-09-22 13:38:207990 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:007991
robpercival214763f2016-07-01 23:27:017992 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7993 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:007994
bnc691fda62016-08-12 00:43:167995 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527996 ASSERT_TRUE(response);
7997 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:007998 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7999
[email protected]90499482013-06-01 00:39:508000 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008001
8002 std::string response_data;
bnc691fda62016-08-12 00:43:168003 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:018004 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:008005 EXPECT_EQ("hello world", response_data);
8006
8007 // Empty the current queue. This is necessary because idle sockets are
8008 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:558009 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:008010
8011 // We now check to make sure the socket was added back to the pool.
Matt Menke9d5e2c92019-02-05 01:42:238012 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008013}
8014
8015// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
8016// from the pool and make sure that we recover okay.
bncd16676a2016-07-20 16:23:018017TEST_F(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:008018 HttpRequestInfo request;
8019 request.method = "GET";
bncce36dca22015-04-21 22:11:238020 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:108021 request.traffic_annotation =
8022 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:008023
8024 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238025 MockWrite(
8026 "GET / HTTP/1.1\r\n"
8027 "Host: www.example.org\r\n"
8028 "Connection: keep-alive\r\n\r\n"),
8029 MockWrite(
8030 "GET / HTTP/1.1\r\n"
8031 "Host: www.example.org\r\n"
8032 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:008033 };
8034
8035 MockRead data_reads[] = {
mmenke911ee0222015-12-04 03:58:428036 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
8037 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
[email protected]76a505b2010-08-25 06:23:008038
[email protected]8ddf8322012-02-23 18:08:068039 SSLSocketDataProvider ssl(ASYNC, OK);
8040 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078041 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8042 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:008043
Ryan Sleevib8d7ea02018-05-07 20:01:018044 StaticSocketDataProvider data(data_reads, data_writes);
8045 StaticSocketDataProvider data2(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:078046 session_deps_.socket_factory->AddSocketDataProvider(&data);
8047 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:008048
[email protected]49639fa2011-12-20 23:22:418049 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:008050
danakj1fd259a02016-04-16 03:17:098051 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:588052 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:198053 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:008054
tfarina42834112016-09-22 13:38:208055 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:008056
robpercival214763f2016-07-01 23:27:018057 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8058 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:008059
8060 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528061 ASSERT_TRUE(response);
8062 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:008063 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8064
[email protected]90499482013-06-01 00:39:508065 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008066
8067 std::string response_data;
8068 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018069 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:008070 EXPECT_EQ("hello world", response_data);
8071
8072 // Empty the current queue. This is necessary because idle sockets are
8073 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:558074 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:008075
8076 // We now check to make sure the socket was added back to the pool.
Matt Menke9d5e2c92019-02-05 01:42:238077 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008078
8079 // Now start the second transaction, which should reuse the previous socket.
8080
bnc87dcefc2017-05-25 12:47:588081 trans =
Jeremy Roman0579ed62017-08-29 15:56:198082 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:008083
tfarina42834112016-09-22 13:38:208084 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:008085
robpercival214763f2016-07-01 23:27:018086 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8087 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:008088
8089 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528090 ASSERT_TRUE(response);
8091 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:008092 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8093
[email protected]90499482013-06-01 00:39:508094 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008095
8096 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018097 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:008098 EXPECT_EQ("hello world", response_data);
8099
8100 // Empty the current queue. This is necessary because idle sockets are
8101 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:558102 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:008103
8104 // We now check to make sure the socket was added back to the pool.
Matt Menke9d5e2c92019-02-05 01:42:238105 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008106}
8107
maksim.sisov0adf8592016-07-15 06:25:568108// Grab a socket, use it, and put it back into the pool. Then, make
8109// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:018110TEST_F(HttpNetworkTransactionTest, FlushSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:568111 HttpRequestInfo request;
8112 request.method = "GET";
8113 request.url = GURL("http://www.example.org/");
8114 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:108115 request.traffic_annotation =
8116 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
maksim.sisov0adf8592016-07-15 06:25:568117
8118 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8119
bnc691fda62016-08-12 00:43:168120 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:568121
8122 MockRead data_reads[] = {
8123 // A part of the response body is received with the response headers.
8124 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
8125 // The rest of the response body is received in two parts.
8126 MockRead("lo"), MockRead(" world"),
8127 MockRead("junk"), // Should not be read!!
8128 MockRead(SYNCHRONOUS, OK),
8129 };
8130
Ryan Sleevib8d7ea02018-05-07 20:01:018131 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
maksim.sisov0adf8592016-07-15 06:25:568132 session_deps_.socket_factory->AddSocketDataProvider(&data);
8133
8134 TestCompletionCallback callback;
8135
tfarina42834112016-09-22 13:38:208136 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:568137 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8138
8139 EXPECT_THAT(callback.GetResult(rv), IsOk());
8140
bnc691fda62016-08-12 00:43:168141 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:568142 ASSERT_TRUE(response);
8143 EXPECT_TRUE(response->headers);
8144 std::string status_line = response->headers->GetStatusLine();
8145 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
8146
8147 // Make memory critical notification and ensure the transaction still has been
8148 // operating right.
8149 base::MemoryPressureListener::NotifyMemoryPressure(
8150 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8151 base::RunLoop().RunUntilIdle();
8152
8153 // Socket should not be flushed as long as it is not idle.
8154 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
8155
8156 std::string response_data;
bnc691fda62016-08-12 00:43:168157 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:568158 EXPECT_THAT(rv, IsOk());
8159 EXPECT_EQ("hello world", response_data);
8160
8161 // Empty the current queue. This is necessary because idle sockets are
8162 // added to the connection pool asynchronously with a PostTask.
8163 base::RunLoop().RunUntilIdle();
8164
8165 // We now check to make sure the socket was added back to the pool.
8166 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
8167
8168 // Idle sockets should be flushed now.
8169 base::MemoryPressureListener::NotifyMemoryPressure(
8170 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8171 base::RunLoop().RunUntilIdle();
8172
8173 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
8174}
8175
yucliu48f235d2018-01-11 00:59:558176// Disable idle socket closing on memory pressure.
8177// Grab a socket, use it, and put it back into the pool. Then, make
8178// low memory notification and ensure the socket pool is NOT flushed.
8179TEST_F(HttpNetworkTransactionTest, NoFlushSocketPoolOnLowMemoryNotifications) {
8180 HttpRequestInfo request;
8181 request.method = "GET";
8182 request.url = GURL("http://www.example.org/");
8183 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:108184 request.traffic_annotation =
8185 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
yucliu48f235d2018-01-11 00:59:558186
8187 // Disable idle socket closing on memory pressure.
8188 session_deps_.disable_idle_sockets_close_on_memory_pressure = true;
8189 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8190
8191 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
8192
8193 MockRead data_reads[] = {
8194 // A part of the response body is received with the response headers.
8195 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
8196 // The rest of the response body is received in two parts.
8197 MockRead("lo"), MockRead(" world"),
8198 MockRead("junk"), // Should not be read!!
8199 MockRead(SYNCHRONOUS, OK),
8200 };
8201
Ryan Sleevib8d7ea02018-05-07 20:01:018202 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
yucliu48f235d2018-01-11 00:59:558203 session_deps_.socket_factory->AddSocketDataProvider(&data);
8204
8205 TestCompletionCallback callback;
8206
8207 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
8208 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8209
8210 EXPECT_THAT(callback.GetResult(rv), IsOk());
8211
8212 const HttpResponseInfo* response = trans.GetResponseInfo();
8213 ASSERT_TRUE(response);
8214 EXPECT_TRUE(response->headers);
8215 std::string status_line = response->headers->GetStatusLine();
8216 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
8217
8218 // Make memory critical notification and ensure the transaction still has been
8219 // operating right.
8220 base::MemoryPressureListener::NotifyMemoryPressure(
8221 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8222 base::RunLoop().RunUntilIdle();
8223
8224 // Socket should not be flushed as long as it is not idle.
8225 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
8226
8227 std::string response_data;
8228 rv = ReadTransaction(&trans, &response_data);
8229 EXPECT_THAT(rv, IsOk());
8230 EXPECT_EQ("hello world", response_data);
8231
8232 // Empty the current queue. This is necessary because idle sockets are
8233 // added to the connection pool asynchronously with a PostTask.
8234 base::RunLoop().RunUntilIdle();
8235
8236 // We now check to make sure the socket was added back to the pool.
8237 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
8238
8239 // Idle sockets should NOT be flushed on moderate memory pressure.
8240 base::MemoryPressureListener::NotifyMemoryPressure(
8241 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE);
8242 base::RunLoop().RunUntilIdle();
8243
8244 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
8245
8246 // Idle sockets should NOT be flushed on critical memory pressure.
8247 base::MemoryPressureListener::NotifyMemoryPressure(
8248 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8249 base::RunLoop().RunUntilIdle();
8250
8251 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
8252}
8253
maksim.sisov0adf8592016-07-15 06:25:568254// Grab an SSL socket, use it, and put it back into the pool. Then, make
8255// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:018256TEST_F(HttpNetworkTransactionTest, FlushSSLSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:568257 HttpRequestInfo request;
8258 request.method = "GET";
8259 request.url = GURL("https://www.example.org/");
8260 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:108261 request.traffic_annotation =
8262 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
maksim.sisov0adf8592016-07-15 06:25:568263
8264 MockWrite data_writes[] = {
8265 MockWrite("GET / HTTP/1.1\r\n"
8266 "Host: www.example.org\r\n"
8267 "Connection: keep-alive\r\n\r\n"),
8268 };
8269
8270 MockRead data_reads[] = {
8271 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
8272 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
8273
8274 SSLSocketDataProvider ssl(ASYNC, OK);
8275 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8276
Ryan Sleevib8d7ea02018-05-07 20:01:018277 StaticSocketDataProvider data(data_reads, data_writes);
maksim.sisov0adf8592016-07-15 06:25:568278 session_deps_.socket_factory->AddSocketDataProvider(&data);
8279
8280 TestCompletionCallback callback;
8281
8282 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168283 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:568284
Matt Menke9d5e2c92019-02-05 01:42:238285 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
tfarina42834112016-09-22 13:38:208286 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:568287
8288 EXPECT_THAT(callback.GetResult(rv), IsOk());
8289
bnc691fda62016-08-12 00:43:168290 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:568291 ASSERT_TRUE(response);
8292 ASSERT_TRUE(response->headers);
8293 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8294
8295 // Make memory critical notification and ensure the transaction still has been
8296 // operating right.
8297 base::MemoryPressureListener::NotifyMemoryPressure(
8298 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8299 base::RunLoop().RunUntilIdle();
8300
Matt Menke9d5e2c92019-02-05 01:42:238301 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
maksim.sisov0adf8592016-07-15 06:25:568302
8303 std::string response_data;
bnc691fda62016-08-12 00:43:168304 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:568305 EXPECT_THAT(rv, IsOk());
8306 EXPECT_EQ("hello world", response_data);
8307
8308 // Empty the current queue. This is necessary because idle sockets are
8309 // added to the connection pool asynchronously with a PostTask.
8310 base::RunLoop().RunUntilIdle();
8311
8312 // We now check to make sure the socket was added back to the pool.
Matt Menke9d5e2c92019-02-05 01:42:238313 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
maksim.sisov0adf8592016-07-15 06:25:568314
8315 // Make memory notification once again and ensure idle socket is closed.
8316 base::MemoryPressureListener::NotifyMemoryPressure(
8317 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8318 base::RunLoop().RunUntilIdle();
8319
Matt Menke9d5e2c92019-02-05 01:42:238320 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
maksim.sisov0adf8592016-07-15 06:25:568321}
8322
[email protected]b4404c02009-04-10 16:38:528323// Make sure that we recycle a socket after a zero-length response.
8324// http://crbug.com/9880
bncd16676a2016-07-20 16:23:018325TEST_F(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:428326 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:528327 request.method = "GET";
bncce36dca22015-04-21 22:11:238328 request.url = GURL(
8329 "http://www.example.org/csi?v=3&s=web&action=&"
8330 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
8331 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
8332 "rt=prt.2642,ol.2649,xjs.2951");
Ramin Halavatib5e433e2018-02-07 07:41:108333 request.traffic_annotation =
8334 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]b4404c02009-04-10 16:38:528335
danakj1fd259a02016-04-16 03:17:098336 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:278337
[email protected]b4404c02009-04-10 16:38:528338 MockRead data_reads[] = {
8339 MockRead("HTTP/1.1 204 No Content\r\n"
8340 "Content-Length: 0\r\n"
8341 "Content-Type: text/html\r\n\r\n"),
8342 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:068343 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:528344 };
8345
Ryan Sleevib8d7ea02018-05-07 20:01:018346 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:078347 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:528348
mmenkecc2298e2015-12-07 18:20:188349 // Transaction must be created after the MockReads, so it's destroyed before
8350 // them.
bnc691fda62016-08-12 00:43:168351 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkecc2298e2015-12-07 18:20:188352
[email protected]49639fa2011-12-20 23:22:418353 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:528354
tfarina42834112016-09-22 13:38:208355 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018356 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]b4404c02009-04-10 16:38:528357
8358 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018359 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:528360
bnc691fda62016-08-12 00:43:168361 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528362 ASSERT_TRUE(response);
[email protected]b4404c02009-04-10 16:38:528363
wezca1070932016-05-26 20:30:528364 EXPECT_TRUE(response->headers);
[email protected]b4404c02009-04-10 16:38:528365 std::string status_line = response->headers->GetStatusLine();
8366 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
8367
[email protected]90499482013-06-01 00:39:508368 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:528369
8370 std::string response_data;
bnc691fda62016-08-12 00:43:168371 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:018372 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:528373 EXPECT_EQ("", response_data);
8374
8375 // Empty the current queue. This is necessary because idle sockets are
8376 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:558377 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:528378
8379 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:508380 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:528381}
8382
bncd16676a2016-07-20 16:23:018383TEST_F(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
danakj1fd259a02016-04-16 03:17:098384 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:228385 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:198386 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:228387 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:278388
[email protected]1c773ea12009-04-28 19:58:428389 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:518390 // Transaction 1: a GET request that succeeds. The socket is recycled
8391 // after use.
8392 request[0].method = "GET";
8393 request[0].url = GURL("http://www.google.com/");
8394 request[0].load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:108395 request[0].traffic_annotation =
8396 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]372d34a2008-11-05 21:30:518397 // Transaction 2: a POST request. Reuses the socket kept alive from
8398 // transaction 1. The first attempts fails when writing the POST data.
8399 // This causes the transaction to retry with a new socket. The second
8400 // attempt succeeds.
8401 request[1].method = "POST";
8402 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:278403 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:518404 request[1].load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:108405 request[1].traffic_annotation =
8406 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]372d34a2008-11-05 21:30:518407
danakj1fd259a02016-04-16 03:17:098408 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:518409
8410 // The first socket is used for transaction 1 and the first attempt of
8411 // transaction 2.
8412
8413 // The response of transaction 1.
8414 MockRead data_reads1[] = {
8415 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
8416 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068417 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:518418 };
8419 // The mock write results of transaction 1 and the first attempt of
8420 // transaction 2.
8421 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:068422 MockWrite(SYNCHRONOUS, 64), // GET
8423 MockWrite(SYNCHRONOUS, 93), // POST
8424 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:518425 };
Ryan Sleevib8d7ea02018-05-07 20:01:018426 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]372d34a2008-11-05 21:30:518427
8428 // The second socket is used for the second attempt of transaction 2.
8429
8430 // The response of transaction 2.
8431 MockRead data_reads2[] = {
8432 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
8433 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:068434 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:518435 };
8436 // The mock write results of the second attempt of transaction 2.
8437 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:068438 MockWrite(SYNCHRONOUS, 93), // POST
8439 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:518440 };
Ryan Sleevib8d7ea02018-05-07 20:01:018441 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]372d34a2008-11-05 21:30:518442
[email protected]bb88e1d32013-05-03 23:11:078443 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8444 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:518445
thestig9d3bb0c2015-01-24 00:49:518446 const char* const kExpectedResponseData[] = {
[email protected]372d34a2008-11-05 21:30:518447 "hello world", "welcome"
8448 };
8449
8450 for (int i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:168451 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]372d34a2008-11-05 21:30:518452
[email protected]49639fa2011-12-20 23:22:418453 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:518454
tfarina42834112016-09-22 13:38:208455 int rv = trans.Start(&request[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018456 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]372d34a2008-11-05 21:30:518457
8458 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018459 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:518460
bnc691fda62016-08-12 00:43:168461 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528462 ASSERT_TRUE(response);
[email protected]372d34a2008-11-05 21:30:518463
wezca1070932016-05-26 20:30:528464 EXPECT_TRUE(response->headers);
[email protected]372d34a2008-11-05 21:30:518465 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8466
8467 std::string response_data;
bnc691fda62016-08-12 00:43:168468 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:018469 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:518470 EXPECT_EQ(kExpectedResponseData[i], response_data);
8471 }
8472}
[email protected]f9ee6b52008-11-08 06:46:238473
8474// Test the request-challenge-retry sequence for basic auth when there is
8475// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:168476// it fails the identity from the URL is used to answer the challenge.
bncd16676a2016-07-20 16:23:018477TEST_F(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:428478 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238479 request.method = "GET";
bncce36dca22015-04-21 22:11:238480 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:418481 request.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:108482 request.traffic_annotation =
8483 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]a97cca42009-08-14 01:00:298484
danakj1fd259a02016-04-16 03:17:098485 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168486 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278487
[email protected]a97cca42009-08-14 01:00:298488 // The password contains an escaped character -- for this test to pass it
8489 // will need to be unescaped by HttpNetworkTransaction.
8490 EXPECT_EQ("b%40r", request.url.password());
8491
[email protected]f9ee6b52008-11-08 06:46:238492 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238493 MockWrite(
8494 "GET / HTTP/1.1\r\n"
8495 "Host: www.example.org\r\n"
8496 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238497 };
8498
8499 MockRead data_reads1[] = {
8500 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8501 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8502 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068503 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238504 };
8505
[email protected]2262e3a2012-05-22 16:08:168506 // After the challenge above, the transaction will be restarted using the
8507 // identity from the url (foo, b@r) to answer the challenge.
8508 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238509 MockWrite(
8510 "GET / HTTP/1.1\r\n"
8511 "Host: www.example.org\r\n"
8512 "Connection: keep-alive\r\n"
8513 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:168514 };
8515
8516 MockRead data_reads2[] = {
8517 MockRead("HTTP/1.0 200 OK\r\n"),
8518 MockRead("Content-Length: 100\r\n\r\n"),
8519 MockRead(SYNCHRONOUS, OK),
8520 };
8521
Ryan Sleevib8d7ea02018-05-07 20:01:018522 StaticSocketDataProvider data1(data_reads1, data_writes1);
8523 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:078524 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8525 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:238526
[email protected]49639fa2011-12-20 23:22:418527 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:208528 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018529 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238530 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018531 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168532 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:168533
8534 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:168535 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:018536 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:168537 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018538 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168539 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:228540
bnc691fda62016-08-12 00:43:168541 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528542 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:168543
8544 // There is no challenge info, since the identity in URL worked.
wezca1070932016-05-26 20:30:528545 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:168546
8547 EXPECT_EQ(100, response->headers->GetContentLength());
8548
8549 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:558550 base::RunLoop().RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:168551}
8552
8553// Test the request-challenge-retry sequence for basic auth when there is an
8554// incorrect identity in the URL. The identity from the URL should be used only
8555// once.
bncd16676a2016-07-20 16:23:018556TEST_F(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:168557 HttpRequestInfo request;
8558 request.method = "GET";
8559 // Note: the URL has a username:password in it. The password "baz" is
8560 // wrong (should be "bar").
bncce36dca22015-04-21 22:11:238561 request.url = GURL("http://foo:[email protected]/");
[email protected]2262e3a2012-05-22 16:08:168562
8563 request.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:108564 request.traffic_annotation =
8565 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2262e3a2012-05-22 16:08:168566
danakj1fd259a02016-04-16 03:17:098567 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168568 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2262e3a2012-05-22 16:08:168569
8570 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238571 MockWrite(
8572 "GET / HTTP/1.1\r\n"
8573 "Host: www.example.org\r\n"
8574 "Connection: keep-alive\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:168575 };
8576
8577 MockRead data_reads1[] = {
8578 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8579 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8580 MockRead("Content-Length: 10\r\n\r\n"),
8581 MockRead(SYNCHRONOUS, ERR_FAILED),
8582 };
8583
8584 // After the challenge above, the transaction will be restarted using the
8585 // identity from the url (foo, baz) to answer the challenge.
8586 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238587 MockWrite(
8588 "GET / HTTP/1.1\r\n"
8589 "Host: www.example.org\r\n"
8590 "Connection: keep-alive\r\n"
8591 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:168592 };
8593
8594 MockRead data_reads2[] = {
8595 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8596 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8597 MockRead("Content-Length: 10\r\n\r\n"),
8598 MockRead(SYNCHRONOUS, ERR_FAILED),
8599 };
8600
8601 // After the challenge above, the transaction will be restarted using the
8602 // identity supplied by the user (foo, bar) to answer the challenge.
8603 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:238604 MockWrite(
8605 "GET / HTTP/1.1\r\n"
8606 "Host: www.example.org\r\n"
8607 "Connection: keep-alive\r\n"
8608 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:168609 };
8610
8611 MockRead data_reads3[] = {
8612 MockRead("HTTP/1.0 200 OK\r\n"),
8613 MockRead("Content-Length: 100\r\n\r\n"),
8614 MockRead(SYNCHRONOUS, OK),
8615 };
8616
Ryan Sleevib8d7ea02018-05-07 20:01:018617 StaticSocketDataProvider data1(data_reads1, data_writes1);
8618 StaticSocketDataProvider data2(data_reads2, data_writes2);
8619 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]bb88e1d32013-05-03 23:11:078620 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8621 session_deps_.socket_factory->AddSocketDataProvider(&data2);
8622 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:168623
8624 TestCompletionCallback callback1;
8625
tfarina42834112016-09-22 13:38:208626 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018627 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:168628
8629 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018630 EXPECT_THAT(rv, IsOk());
[email protected]2262e3a2012-05-22 16:08:168631
bnc691fda62016-08-12 00:43:168632 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:168633 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:168634 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:018635 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:168636 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018637 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168638 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:168639
bnc691fda62016-08-12 00:43:168640 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528641 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:168642 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
8643
8644 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:168645 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:018646 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:168647 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:018648 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168649 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:168650
bnc691fda62016-08-12 00:43:168651 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528652 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:168653
8654 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:528655 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:168656
8657 EXPECT_EQ(100, response->headers->GetContentLength());
8658
[email protected]ea9dc9a2009-09-05 00:43:328659 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:558660 base::RunLoop().RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:328661}
8662
[email protected]2217aa22013-10-11 03:03:548663
8664// Test the request-challenge-retry sequence for basic auth when there is a
8665// correct identity in the URL, but its use is being suppressed. The identity
8666// from the URL should never be used.
bncd16676a2016-07-20 16:23:018667TEST_F(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
[email protected]2217aa22013-10-11 03:03:548668 HttpRequestInfo request;
8669 request.method = "GET";
bncce36dca22015-04-21 22:11:238670 request.url = GURL("http://foo:[email protected]/");
[email protected]2217aa22013-10-11 03:03:548671 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
Ramin Halavatib5e433e2018-02-07 07:41:108672 request.traffic_annotation =
8673 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2217aa22013-10-11 03:03:548674
danakj1fd259a02016-04-16 03:17:098675 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168676 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2217aa22013-10-11 03:03:548677
8678 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238679 MockWrite(
8680 "GET / HTTP/1.1\r\n"
8681 "Host: www.example.org\r\n"
8682 "Connection: keep-alive\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:548683 };
8684
8685 MockRead data_reads1[] = {
8686 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8687 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8688 MockRead("Content-Length: 10\r\n\r\n"),
8689 MockRead(SYNCHRONOUS, ERR_FAILED),
8690 };
8691
8692 // After the challenge above, the transaction will be restarted using the
8693 // identity supplied by the user, not the one in the URL, to answer the
8694 // challenge.
8695 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:238696 MockWrite(
8697 "GET / HTTP/1.1\r\n"
8698 "Host: www.example.org\r\n"
8699 "Connection: keep-alive\r\n"
8700 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:548701 };
8702
8703 MockRead data_reads3[] = {
8704 MockRead("HTTP/1.0 200 OK\r\n"),
8705 MockRead("Content-Length: 100\r\n\r\n"),
8706 MockRead(SYNCHRONOUS, OK),
8707 };
8708
Ryan Sleevib8d7ea02018-05-07 20:01:018709 StaticSocketDataProvider data1(data_reads1, data_writes1);
8710 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]2217aa22013-10-11 03:03:548711 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8712 session_deps_.socket_factory->AddSocketDataProvider(&data3);
8713
8714 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:208715 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018716 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:548717 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018718 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168719 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:548720
bnc691fda62016-08-12 00:43:168721 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528722 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:548723 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
8724
8725 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:168726 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:018727 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:548728 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:018729 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168730 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:548731
bnc691fda62016-08-12 00:43:168732 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528733 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:548734
8735 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:528736 EXPECT_FALSE(response->auth_challenge);
[email protected]2217aa22013-10-11 03:03:548737 EXPECT_EQ(100, response->headers->GetContentLength());
8738
8739 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:558740 base::RunLoop().RunUntilIdle();
[email protected]2217aa22013-10-11 03:03:548741}
8742
[email protected]f9ee6b52008-11-08 06:46:238743// Test that previously tried username/passwords for a realm get re-used.
bncd16676a2016-07-20 16:23:018744TEST_F(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
danakj1fd259a02016-04-16 03:17:098745 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:238746
8747 // Transaction 1: authenticate (foo, bar) on MyRealm1
8748 {
[email protected]1c773ea12009-04-28 19:58:428749 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238750 request.method = "GET";
bncce36dca22015-04-21 22:11:238751 request.url = GURL("http://www.example.org/x/y/z");
Ramin Halavatib5e433e2018-02-07 07:41:108752 request.traffic_annotation =
8753 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238754
bnc691fda62016-08-12 00:43:168755 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278756
[email protected]f9ee6b52008-11-08 06:46:238757 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238758 MockWrite(
8759 "GET /x/y/z HTTP/1.1\r\n"
8760 "Host: www.example.org\r\n"
8761 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238762 };
8763
8764 MockRead data_reads1[] = {
8765 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8766 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8767 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068768 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238769 };
8770
8771 // Resend with authorization (username=foo, password=bar)
8772 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238773 MockWrite(
8774 "GET /x/y/z HTTP/1.1\r\n"
8775 "Host: www.example.org\r\n"
8776 "Connection: keep-alive\r\n"
8777 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238778 };
8779
8780 // Sever accepts the authorization.
8781 MockRead data_reads2[] = {
8782 MockRead("HTTP/1.0 200 OK\r\n"),
8783 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068784 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238785 };
8786
Ryan Sleevib8d7ea02018-05-07 20:01:018787 StaticSocketDataProvider data1(data_reads1, data_writes1);
8788 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:078789 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8790 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:238791
[email protected]49639fa2011-12-20 23:22:418792 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238793
tfarina42834112016-09-22 13:38:208794 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018795 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238796
8797 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018798 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238799
bnc691fda62016-08-12 00:43:168800 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528801 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:048802 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:238803
[email protected]49639fa2011-12-20 23:22:418804 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:238805
bnc691fda62016-08-12 00:43:168806 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
8807 callback2.callback());
robpercival214763f2016-07-01 23:27:018808 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238809
8810 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018811 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238812
bnc691fda62016-08-12 00:43:168813 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528814 ASSERT_TRUE(response);
8815 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238816 EXPECT_EQ(100, response->headers->GetContentLength());
8817 }
8818
8819 // ------------------------------------------------------------------------
8820
8821 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
8822 {
[email protected]1c773ea12009-04-28 19:58:428823 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238824 request.method = "GET";
8825 // Note that Transaction 1 was at /x/y/z, so this is in the same
8826 // protection space as MyRealm1.
bncce36dca22015-04-21 22:11:238827 request.url = GURL("http://www.example.org/x/y/a/b");
Ramin Halavatib5e433e2018-02-07 07:41:108828 request.traffic_annotation =
8829 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238830
bnc691fda62016-08-12 00:43:168831 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278832
[email protected]f9ee6b52008-11-08 06:46:238833 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238834 MockWrite(
8835 "GET /x/y/a/b HTTP/1.1\r\n"
8836 "Host: www.example.org\r\n"
8837 "Connection: keep-alive\r\n"
8838 // Send preemptive authorization for MyRealm1
8839 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238840 };
8841
8842 // The server didn't like the preemptive authorization, and
8843 // challenges us for a different realm (MyRealm2).
8844 MockRead data_reads1[] = {
8845 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8846 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
8847 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068848 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238849 };
8850
8851 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
8852 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238853 MockWrite(
8854 "GET /x/y/a/b HTTP/1.1\r\n"
8855 "Host: www.example.org\r\n"
8856 "Connection: keep-alive\r\n"
8857 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238858 };
8859
8860 // Sever accepts the authorization.
8861 MockRead data_reads2[] = {
8862 MockRead("HTTP/1.0 200 OK\r\n"),
8863 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068864 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238865 };
8866
Ryan Sleevib8d7ea02018-05-07 20:01:018867 StaticSocketDataProvider data1(data_reads1, data_writes1);
8868 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:078869 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8870 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:238871
[email protected]49639fa2011-12-20 23:22:418872 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238873
tfarina42834112016-09-22 13:38:208874 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018875 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238876
8877 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018878 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238879
bnc691fda62016-08-12 00:43:168880 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528881 ASSERT_TRUE(response);
8882 ASSERT_TRUE(response->auth_challenge);
[email protected]79cb5c12011-09-12 13:12:048883 EXPECT_FALSE(response->auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:438884 EXPECT_EQ("http://www.example.org",
8885 response->auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:048886 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
aberentbba302d2015-12-03 10:20:198887 EXPECT_EQ(kBasicAuthScheme, response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:238888
[email protected]49639fa2011-12-20 23:22:418889 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:238890
bnc691fda62016-08-12 00:43:168891 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
8892 callback2.callback());
robpercival214763f2016-07-01 23:27:018893 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238894
8895 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018896 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238897
bnc691fda62016-08-12 00:43:168898 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528899 ASSERT_TRUE(response);
8900 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238901 EXPECT_EQ(100, response->headers->GetContentLength());
8902 }
8903
8904 // ------------------------------------------------------------------------
8905
8906 // Transaction 3: Resend a request in MyRealm's protection space --
8907 // succeed with preemptive authorization.
8908 {
[email protected]1c773ea12009-04-28 19:58:428909 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238910 request.method = "GET";
bncce36dca22015-04-21 22:11:238911 request.url = GURL("http://www.example.org/x/y/z2");
Ramin Halavatib5e433e2018-02-07 07:41:108912 request.traffic_annotation =
8913 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238914
bnc691fda62016-08-12 00:43:168915 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278916
[email protected]f9ee6b52008-11-08 06:46:238917 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238918 MockWrite(
8919 "GET /x/y/z2 HTTP/1.1\r\n"
8920 "Host: www.example.org\r\n"
8921 "Connection: keep-alive\r\n"
8922 // The authorization for MyRealm1 gets sent preemptively
8923 // (since the url is in the same protection space)
8924 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238925 };
8926
8927 // Sever accepts the preemptive authorization
8928 MockRead data_reads1[] = {
8929 MockRead("HTTP/1.0 200 OK\r\n"),
8930 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068931 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238932 };
8933
Ryan Sleevib8d7ea02018-05-07 20:01:018934 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:078935 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:238936
[email protected]49639fa2011-12-20 23:22:418937 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238938
tfarina42834112016-09-22 13:38:208939 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018940 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238941
8942 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018943 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238944
bnc691fda62016-08-12 00:43:168945 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528946 ASSERT_TRUE(response);
[email protected]f9ee6b52008-11-08 06:46:238947
wezca1070932016-05-26 20:30:528948 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238949 EXPECT_EQ(100, response->headers->GetContentLength());
8950 }
8951
8952 // ------------------------------------------------------------------------
8953
8954 // Transaction 4: request another URL in MyRealm (however the
8955 // url is not known to belong to the protection space, so no pre-auth).
8956 {
[email protected]1c773ea12009-04-28 19:58:428957 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238958 request.method = "GET";
bncce36dca22015-04-21 22:11:238959 request.url = GURL("http://www.example.org/x/1");
Ramin Halavatib5e433e2018-02-07 07:41:108960 request.traffic_annotation =
8961 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238962
bnc691fda62016-08-12 00:43:168963 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278964
[email protected]f9ee6b52008-11-08 06:46:238965 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238966 MockWrite(
8967 "GET /x/1 HTTP/1.1\r\n"
8968 "Host: www.example.org\r\n"
8969 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238970 };
8971
8972 MockRead data_reads1[] = {
8973 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8974 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8975 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068976 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238977 };
8978
8979 // Resend with authorization from MyRealm's cache.
8980 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238981 MockWrite(
8982 "GET /x/1 HTTP/1.1\r\n"
8983 "Host: www.example.org\r\n"
8984 "Connection: keep-alive\r\n"
8985 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238986 };
8987
8988 // Sever accepts the authorization.
8989 MockRead data_reads2[] = {
8990 MockRead("HTTP/1.0 200 OK\r\n"),
8991 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068992 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238993 };
8994
Ryan Sleevib8d7ea02018-05-07 20:01:018995 StaticSocketDataProvider data1(data_reads1, data_writes1);
8996 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:078997 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8998 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:238999
[email protected]49639fa2011-12-20 23:22:419000 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:239001
tfarina42834112016-09-22 13:38:209002 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019003 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:239004
9005 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019006 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:239007
bnc691fda62016-08-12 00:43:169008 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:419009 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:169010 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:019011 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:229012 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:019013 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:169014 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:229015
bnc691fda62016-08-12 00:43:169016 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529017 ASSERT_TRUE(response);
9018 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:239019 EXPECT_EQ(100, response->headers->GetContentLength());
9020 }
9021
9022 // ------------------------------------------------------------------------
9023
9024 // Transaction 5: request a URL in MyRealm, but the server rejects the
9025 // cached identity. Should invalidate and re-prompt.
9026 {
[email protected]1c773ea12009-04-28 19:58:429027 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:239028 request.method = "GET";
bncce36dca22015-04-21 22:11:239029 request.url = GURL("http://www.example.org/p/q/t");
Ramin Halavatib5e433e2018-02-07 07:41:109030 request.traffic_annotation =
9031 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:239032
bnc691fda62016-08-12 00:43:169033 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279034
[email protected]f9ee6b52008-11-08 06:46:239035 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239036 MockWrite(
9037 "GET /p/q/t HTTP/1.1\r\n"
9038 "Host: www.example.org\r\n"
9039 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:239040 };
9041
9042 MockRead data_reads1[] = {
9043 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
9044 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9045 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069046 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:239047 };
9048
9049 // Resend with authorization from cache for MyRealm.
9050 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:239051 MockWrite(
9052 "GET /p/q/t HTTP/1.1\r\n"
9053 "Host: www.example.org\r\n"
9054 "Connection: keep-alive\r\n"
9055 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:239056 };
9057
9058 // Sever rejects the authorization.
9059 MockRead data_reads2[] = {
9060 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
9061 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9062 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069063 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:239064 };
9065
9066 // At this point we should prompt for new credentials for MyRealm.
9067 // Restart with username=foo3, password=foo4.
9068 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:239069 MockWrite(
9070 "GET /p/q/t HTTP/1.1\r\n"
9071 "Host: www.example.org\r\n"
9072 "Connection: keep-alive\r\n"
9073 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:239074 };
9075
9076 // Sever accepts the authorization.
9077 MockRead data_reads3[] = {
9078 MockRead("HTTP/1.0 200 OK\r\n"),
9079 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069080 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:239081 };
9082
Ryan Sleevib8d7ea02018-05-07 20:01:019083 StaticSocketDataProvider data1(data_reads1, data_writes1);
9084 StaticSocketDataProvider data2(data_reads2, data_writes2);
9085 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]bb88e1d32013-05-03 23:11:079086 session_deps_.socket_factory->AddSocketDataProvider(&data1);
9087 session_deps_.socket_factory->AddSocketDataProvider(&data2);
9088 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:239089
[email protected]49639fa2011-12-20 23:22:419090 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:239091
tfarina42834112016-09-22 13:38:209092 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019093 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:239094
9095 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019096 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:239097
bnc691fda62016-08-12 00:43:169098 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:419099 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:169100 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:019101 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:229102 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:019103 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:169104 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:229105
bnc691fda62016-08-12 00:43:169106 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529107 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:049108 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:239109
[email protected]49639fa2011-12-20 23:22:419110 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:239111
bnc691fda62016-08-12 00:43:169112 rv = trans.RestartWithAuth(AuthCredentials(kFoo3, kBar3),
9113 callback3.callback());
robpercival214763f2016-07-01 23:27:019114 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:239115
[email protected]0757e7702009-03-27 04:00:229116 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:019117 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:239118
bnc691fda62016-08-12 00:43:169119 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529120 ASSERT_TRUE(response);
9121 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:239122 EXPECT_EQ(100, response->headers->GetContentLength());
9123 }
9124}
[email protected]89ceba9a2009-03-21 03:46:069125
[email protected]3c32c5f2010-05-18 15:18:129126// Tests that nonce count increments when multiple auth attempts
9127// are started with the same nonce.
bncd16676a2016-07-20 16:23:019128TEST_F(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:449129 HttpAuthHandlerDigest::Factory* digest_factory =
9130 new HttpAuthHandlerDigest::Factory();
9131 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
9132 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
9133 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:079134 session_deps_.http_auth_handler_factory.reset(digest_factory);
danakj1fd259a02016-04-16 03:17:099135 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:129136
9137 // Transaction 1: authenticate (foo, bar) on MyRealm1
9138 {
[email protected]3c32c5f2010-05-18 15:18:129139 HttpRequestInfo request;
9140 request.method = "GET";
bncce36dca22015-04-21 22:11:239141 request.url = GURL("http://www.example.org/x/y/z");
Ramin Halavatib5e433e2018-02-07 07:41:109142 request.traffic_annotation =
9143 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3c32c5f2010-05-18 15:18:129144
bnc691fda62016-08-12 00:43:169145 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279146
[email protected]3c32c5f2010-05-18 15:18:129147 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239148 MockWrite(
9149 "GET /x/y/z HTTP/1.1\r\n"
9150 "Host: www.example.org\r\n"
9151 "Connection: keep-alive\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:129152 };
9153
9154 MockRead data_reads1[] = {
9155 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
9156 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
9157 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069158 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:129159 };
9160
9161 // Resend with authorization (username=foo, password=bar)
9162 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:239163 MockWrite(
9164 "GET /x/y/z HTTP/1.1\r\n"
9165 "Host: www.example.org\r\n"
9166 "Connection: keep-alive\r\n"
9167 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
9168 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
9169 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
9170 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:129171 };
9172
9173 // Sever accepts the authorization.
9174 MockRead data_reads2[] = {
zmo9528c9f42015-08-04 22:12:089175 MockRead("HTTP/1.0 200 OK\r\n"),
9176 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:129177 };
9178
Ryan Sleevib8d7ea02018-05-07 20:01:019179 StaticSocketDataProvider data1(data_reads1, data_writes1);
9180 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:079181 session_deps_.socket_factory->AddSocketDataProvider(&data1);
9182 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:129183
[email protected]49639fa2011-12-20 23:22:419184 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:129185
tfarina42834112016-09-22 13:38:209186 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019187 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:129188
9189 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019190 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:129191
bnc691fda62016-08-12 00:43:169192 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529193 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:049194 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:129195
[email protected]49639fa2011-12-20 23:22:419196 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:129197
bnc691fda62016-08-12 00:43:169198 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
9199 callback2.callback());
robpercival214763f2016-07-01 23:27:019200 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:129201
9202 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:019203 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:129204
bnc691fda62016-08-12 00:43:169205 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529206 ASSERT_TRUE(response);
9207 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:129208 }
9209
9210 // ------------------------------------------------------------------------
9211
9212 // Transaction 2: Request another resource in digestive's protection space.
9213 // This will preemptively add an Authorization header which should have an
9214 // "nc" value of 2 (as compared to 1 in the first use.
9215 {
[email protected]3c32c5f2010-05-18 15:18:129216 HttpRequestInfo request;
9217 request.method = "GET";
9218 // Note that Transaction 1 was at /x/y/z, so this is in the same
9219 // protection space as digest.
bncce36dca22015-04-21 22:11:239220 request.url = GURL("http://www.example.org/x/y/a/b");
Ramin Halavatib5e433e2018-02-07 07:41:109221 request.traffic_annotation =
9222 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3c32c5f2010-05-18 15:18:129223
bnc691fda62016-08-12 00:43:169224 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279225
[email protected]3c32c5f2010-05-18 15:18:129226 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239227 MockWrite(
9228 "GET /x/y/a/b HTTP/1.1\r\n"
9229 "Host: www.example.org\r\n"
9230 "Connection: keep-alive\r\n"
9231 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
9232 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
9233 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
9234 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:129235 };
9236
9237 // Sever accepts the authorization.
9238 MockRead data_reads1[] = {
9239 MockRead("HTTP/1.0 200 OK\r\n"),
9240 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069241 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:129242 };
9243
Ryan Sleevib8d7ea02018-05-07 20:01:019244 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:079245 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:129246
[email protected]49639fa2011-12-20 23:22:419247 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:129248
tfarina42834112016-09-22 13:38:209249 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019250 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:129251
9252 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019253 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:129254
bnc691fda62016-08-12 00:43:169255 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529256 ASSERT_TRUE(response);
9257 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:129258 }
9259}
9260
[email protected]89ceba9a2009-03-21 03:46:069261// Test the ResetStateForRestart() private method.
bncd16676a2016-07-20 16:23:019262TEST_F(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:069263 // Create a transaction (the dependencies aren't important).
danakj1fd259a02016-04-16 03:17:099264 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169265 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]89ceba9a2009-03-21 03:46:069266
9267 // Setup some state (which we expect ResetStateForRestart() will clear).
Victor Costan9c7302b2018-08-27 16:39:449268 trans.read_buf_ = base::MakeRefCounted<IOBuffer>(15);
bnc691fda62016-08-12 00:43:169269 trans.read_buf_len_ = 15;
9270 trans.request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:069271
9272 // Setup state in response_
bnc691fda62016-08-12 00:43:169273 HttpResponseInfo* response = &trans.response_;
[email protected]0877e3d2009-10-17 22:29:579274 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:089275 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:579276 response->response_time = base::Time::Now();
9277 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:069278
9279 { // Setup state for response_.vary_data
9280 HttpRequestInfo request;
9281 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
9282 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:279283 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:439284 request.extra_headers.SetHeader("Foo", "1");
9285 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:509286 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:069287 }
9288
9289 // Cause the above state to be reset.
bnc691fda62016-08-12 00:43:169290 trans.ResetStateForRestart();
[email protected]89ceba9a2009-03-21 03:46:069291
9292 // Verify that the state that needed to be reset, has been reset.
bnc691fda62016-08-12 00:43:169293 EXPECT_FALSE(trans.read_buf_);
9294 EXPECT_EQ(0, trans.read_buf_len_);
9295 EXPECT_TRUE(trans.request_headers_.IsEmpty());
wezca1070932016-05-26 20:30:529296 EXPECT_FALSE(response->auth_challenge);
9297 EXPECT_FALSE(response->headers);
[email protected]34f40942010-10-04 00:34:049298 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:089299 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:579300 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:069301}
9302
[email protected]bacff652009-03-31 17:50:339303// Test HTTPS connections to a site with a bad certificate
bncd16676a2016-07-20 16:23:019304TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:339305 HttpRequestInfo request;
9306 request.method = "GET";
bncce36dca22015-04-21 22:11:239307 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109308 request.traffic_annotation =
9309 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]bacff652009-03-31 17:50:339310
danakj1fd259a02016-04-16 03:17:099311 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169312 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279313
[email protected]bacff652009-03-31 17:50:339314 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239315 MockWrite(
9316 "GET / HTTP/1.1\r\n"
9317 "Host: www.example.org\r\n"
9318 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:339319 };
9320
9321 MockRead data_reads[] = {
9322 MockRead("HTTP/1.0 200 OK\r\n"),
9323 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9324 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069325 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:339326 };
9327
[email protected]5ecc992a42009-11-11 01:41:599328 StaticSocketDataProvider ssl_bad_certificate;
Ryan Sleevib8d7ea02018-05-07 20:01:019329 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069330 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
9331 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:339332
[email protected]bb88e1d32013-05-03 23:11:079333 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
9334 session_deps_.socket_factory->AddSocketDataProvider(&data);
9335 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
9336 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:339337
[email protected]49639fa2011-12-20 23:22:419338 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:339339
tfarina42834112016-09-22 13:38:209340 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019341 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:339342
9343 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019344 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:339345
bnc691fda62016-08-12 00:43:169346 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:019347 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:339348
9349 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019350 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:339351
bnc691fda62016-08-12 00:43:169352 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:339353
wezca1070932016-05-26 20:30:529354 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:339355 EXPECT_EQ(100, response->headers->GetContentLength());
9356}
9357
9358// Test HTTPS connections to a site with a bad certificate, going through a
9359// proxy
bncd16676a2016-07-20 16:23:019360TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
Ramin Halavatica8d5252018-03-12 05:33:499361 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9362 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]bacff652009-03-31 17:50:339363
9364 HttpRequestInfo request;
9365 request.method = "GET";
bncce36dca22015-04-21 22:11:239366 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109367 request.traffic_annotation =
9368 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]bacff652009-03-31 17:50:339369
9370 MockWrite proxy_writes[] = {
rsleevidb16bb02015-11-12 23:47:179371 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9372 "Host: www.example.org:443\r\n"
9373 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:339374 };
9375
9376 MockRead proxy_reads[] = {
9377 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069378 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:339379 };
9380
9381 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179382 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9383 "Host: www.example.org:443\r\n"
9384 "Proxy-Connection: keep-alive\r\n\r\n"),
9385 MockWrite("GET / HTTP/1.1\r\n"
9386 "Host: www.example.org\r\n"
9387 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:339388 };
9389
9390 MockRead data_reads[] = {
9391 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
9392 MockRead("HTTP/1.0 200 OK\r\n"),
9393 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9394 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069395 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:339396 };
9397
Ryan Sleevib8d7ea02018-05-07 20:01:019398 StaticSocketDataProvider ssl_bad_certificate(proxy_reads, proxy_writes);
9399 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069400 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
9401 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:339402
[email protected]bb88e1d32013-05-03 23:11:079403 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
9404 session_deps_.socket_factory->AddSocketDataProvider(&data);
9405 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
9406 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:339407
[email protected]49639fa2011-12-20 23:22:419408 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:339409
9410 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:079411 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:339412
danakj1fd259a02016-04-16 03:17:099413 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169414 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bacff652009-03-31 17:50:339415
tfarina42834112016-09-22 13:38:209416 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019417 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:339418
9419 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019420 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:339421
bnc691fda62016-08-12 00:43:169422 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:019423 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:339424
9425 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019426 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:339427
bnc691fda62016-08-12 00:43:169428 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:339429
wezca1070932016-05-26 20:30:529430 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:339431 EXPECT_EQ(100, response->headers->GetContentLength());
9432 }
9433}
9434
[email protected]2df19bb2010-08-25 20:13:469435
9436// Test HTTPS connections to a site, going through an HTTPS proxy
bncd16676a2016-07-20 16:23:019437TEST_F(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:599438 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499439 ProxyResolutionService::CreateFixedFromPacResult(
9440 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519441 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079442 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:469443
9444 HttpRequestInfo request;
9445 request.method = "GET";
bncce36dca22015-04-21 22:11:239446 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109447 request.traffic_annotation =
9448 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:469449
9450 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179451 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9452 "Host: www.example.org:443\r\n"
9453 "Proxy-Connection: keep-alive\r\n\r\n"),
9454 MockWrite("GET / HTTP/1.1\r\n"
9455 "Host: www.example.org\r\n"
9456 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:469457 };
9458
9459 MockRead data_reads[] = {
9460 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
9461 MockRead("HTTP/1.1 200 OK\r\n"),
9462 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9463 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069464 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:469465 };
9466
Ryan Sleevib8d7ea02018-05-07 20:01:019467 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069468 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
9469 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:469470
[email protected]bb88e1d32013-05-03 23:11:079471 session_deps_.socket_factory->AddSocketDataProvider(&data);
9472 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
9473 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:469474
[email protected]49639fa2011-12-20 23:22:419475 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:469476
danakj1fd259a02016-04-16 03:17:099477 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169478 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:469479
tfarina42834112016-09-22 13:38:209480 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019481 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:469482
9483 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019484 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:169485 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:469486
wezca1070932016-05-26 20:30:529487 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:469488
tbansal2ecbbc72016-10-06 17:15:479489 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:469490 EXPECT_TRUE(response->headers->IsKeepAlive());
9491 EXPECT_EQ(200, response->headers->response_code());
9492 EXPECT_EQ(100, response->headers->GetContentLength());
9493 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:209494
9495 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169496 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209497 TestLoadTimingNotReusedWithPac(load_timing_info,
9498 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:469499}
9500
[email protected]511f6f52010-12-17 03:58:299501// Test an HTTPS Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:019502TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:599503 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499504 ProxyResolutionService::CreateFixedFromPacResult(
9505 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519506 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079507 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:299508
Matt Menkeecfecfc72019-02-05 19:15:289509 base::TimeTicks start_time = base::TimeTicks::Now();
9510 const base::TimeDelta kTimeIncrement = base::TimeDelta::FromSeconds(4);
9511 session_deps_.host_resolver->set_ondemand_mode(true);
9512
[email protected]511f6f52010-12-17 03:58:299513 HttpRequestInfo request;
9514 request.method = "GET";
bncce36dca22015-04-21 22:11:239515 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109516 request.traffic_annotation =
9517 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299518
9519 MockWrite data_writes[] = {
Matt Menkeecfecfc72019-02-05 19:15:289520 MockWrite(ASYNC, 0,
9521 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:179522 "Host: www.example.org:443\r\n"
9523 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:299524 };
9525
9526 MockRead data_reads[] = {
Matt Menkeecfecfc72019-02-05 19:15:289527 // Pause on first read.
9528 MockRead(ASYNC, ERR_IO_PENDING, 1),
9529 MockRead(ASYNC, 2, "HTTP/1.1 302 Redirect\r\n"),
9530 MockRead(ASYNC, 3, "Location: http://login.example.com/\r\n"),
9531 MockRead(ASYNC, 4, "Content-Length: 0\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:299532 };
9533
Matt Menkeecfecfc72019-02-05 19:15:289534 SequencedSocketData data(MockConnect(ASYNC, OK), data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069535 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:299536
[email protected]bb88e1d32013-05-03 23:11:079537 session_deps_.socket_factory->AddSocketDataProvider(&data);
9538 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:299539
[email protected]49639fa2011-12-20 23:22:419540 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:299541
danakj1fd259a02016-04-16 03:17:099542 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169543 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:299544
tfarina42834112016-09-22 13:38:209545 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019546 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Matt Menkeecfecfc72019-02-05 19:15:289547 EXPECT_TRUE(session_deps_.host_resolver->has_pending_requests());
9548
9549 // Host resolution takes |kTimeIncrement|.
9550 FastForwardBy(kTimeIncrement);
9551 // Resolving the current request with |ResolveNow| will cause the pending
9552 // request to instantly complete, and the async connect will start as well.
9553 session_deps_.host_resolver->ResolveOnlyRequestNow();
9554
9555 // Connecting takes |kTimeIncrement|.
9556 FastForwardBy(kTimeIncrement);
9557 data.RunUntilPaused();
9558
9559 // The server takes |kTimeIncrement| to respond.
9560 FastForwardBy(kTimeIncrement);
9561 data.Resume();
[email protected]511f6f52010-12-17 03:58:299562
9563 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019564 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:169565 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:299566
wezca1070932016-05-26 20:30:529567 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:299568
9569 EXPECT_EQ(302, response->headers->response_code());
9570 std::string url;
9571 EXPECT_TRUE(response->headers->IsRedirect(&url));
9572 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:209573
[email protected]029c83b62013-01-24 05:28:209574 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169575 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209576
9577 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:199578 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:209579
Matt Menkeecfecfc72019-02-05 19:15:289580 // In the case of redirects from proxies, just as with all responses from
9581 // proxies, DNS and SSL times reflect timing to look up the destination's
9582 // name, and negotiate an SSL connection to it (Neither of which are done in
9583 // this case), which the DNS and SSL times for the proxy are all included in
9584 // connect_start / connect_end. See
9585 // HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
9586
9587 EXPECT_TRUE(load_timing_info.connect_timing.dns_start.is_null());
9588 EXPECT_TRUE(load_timing_info.connect_timing.dns_end.is_null());
9589 EXPECT_TRUE(load_timing_info.connect_timing.ssl_start.is_null());
9590 EXPECT_TRUE(load_timing_info.connect_timing.ssl_end.is_null());
9591
9592 EXPECT_EQ(start_time, load_timing_info.proxy_resolve_start);
9593 EXPECT_EQ(start_time, load_timing_info.proxy_resolve_end);
9594 EXPECT_EQ(start_time, load_timing_info.connect_timing.connect_start);
9595 EXPECT_EQ(start_time + 3 * kTimeIncrement,
9596 load_timing_info.connect_timing.connect_end);
[email protected]029c83b62013-01-24 05:28:209597
9598 EXPECT_TRUE(load_timing_info.send_start.is_null());
9599 EXPECT_TRUE(load_timing_info.send_end.is_null());
9600 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:299601}
9602
9603// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:019604TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
Ramin Halavatica8d5252018-03-12 05:33:499605 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9606 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Matt Menkeecfecfc72019-02-05 19:15:289607 TestNetLog net_log;
9608 session_deps_.net_log = &net_log;
9609
9610 base::TimeTicks start_time = base::TimeTicks::Now();
9611 const base::TimeDelta kTimeIncrement = base::TimeDelta::FromSeconds(4);
9612 session_deps_.host_resolver->set_ondemand_mode(true);
[email protected]511f6f52010-12-17 03:58:299613
9614 HttpRequestInfo request;
9615 request.method = "GET";
bncce36dca22015-04-21 22:11:239616 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109617 request.traffic_annotation =
9618 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299619
Ryan Hamilton0239aac2018-05-19 00:03:139620 spdy::SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:239621 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:139622 spdy::SpdySerializedFrame goaway(
9623 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:299624 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:419625 CreateMockWrite(conn, 0, SYNCHRONOUS),
Matt Menkeecfecfc72019-02-05 19:15:289626 CreateMockWrite(goaway, 3, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:299627 };
9628
9629 static const char* const kExtraHeaders[] = {
9630 "location",
9631 "http://login.example.com/",
9632 };
Ryan Hamilton0239aac2018-05-19 00:03:139633 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
Avi Drissman4365a4782018-12-28 19:26:249634 "302", kExtraHeaders, base::size(kExtraHeaders) / 2, 1));
[email protected]511f6f52010-12-17 03:58:299635 MockRead data_reads[] = {
Matt Menkeecfecfc72019-02-05 19:15:289636 // Pause on first read.
9637 MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(resp, 2),
9638 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:299639 };
9640
Matt Menkeecfecfc72019-02-05 19:15:289641 SequencedSocketData data(MockConnect(ASYNC, OK), data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069642 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:369643 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:299644
[email protected]bb88e1d32013-05-03 23:11:079645 session_deps_.socket_factory->AddSocketDataProvider(&data);
9646 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:299647
[email protected]49639fa2011-12-20 23:22:419648 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:299649
danakj1fd259a02016-04-16 03:17:099650 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169651 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:299652
tfarina42834112016-09-22 13:38:209653 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019654 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Matt Menkeecfecfc72019-02-05 19:15:289655 EXPECT_TRUE(session_deps_.host_resolver->has_pending_requests());
[email protected]511f6f52010-12-17 03:58:299656
Matt Menkeecfecfc72019-02-05 19:15:289657 // Host resolution takes |kTimeIncrement|.
9658 FastForwardBy(kTimeIncrement);
9659 // Resolving the current request with |ResolveNow| will cause the pending
9660 // request to instantly complete, and the async connect will start as well.
9661 session_deps_.host_resolver->ResolveOnlyRequestNow();
9662
9663 // Connecting takes |kTimeIncrement|.
9664 FastForwardBy(kTimeIncrement);
9665 data.RunUntilPaused();
9666
9667 FastForwardBy(kTimeIncrement);
9668 data.Resume();
[email protected]511f6f52010-12-17 03:58:299669 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019670 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:169671 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:299672
wezca1070932016-05-26 20:30:529673 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:299674
9675 EXPECT_EQ(302, response->headers->response_code());
9676 std::string url;
9677 EXPECT_TRUE(response->headers->IsRedirect(&url));
9678 EXPECT_EQ("http://login.example.com/", url);
Matt Menkeecfecfc72019-02-05 19:15:289679
9680 LoadTimingInfo load_timing_info;
9681 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
9682
9683 EXPECT_FALSE(load_timing_info.socket_reused);
9684 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
9685
9686 // No proxy resolution times, since there's no PAC script.
9687 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
9688 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
9689
9690 // In the case of redirects from proxies, just as with all responses from
9691 // proxies, DNS and SSL times reflect timing to look up the destination's
9692 // name, and negotiate an SSL connection to it (Neither of which are done in
9693 // this case), which the DNS and SSL times for the proxy are all included in
9694 // connect_start / connect_end. See
9695 // HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
9696
9697 EXPECT_TRUE(load_timing_info.connect_timing.dns_start.is_null());
9698 EXPECT_TRUE(load_timing_info.connect_timing.dns_end.is_null());
9699 EXPECT_TRUE(load_timing_info.connect_timing.ssl_start.is_null());
9700 EXPECT_TRUE(load_timing_info.connect_timing.ssl_end.is_null());
9701
9702 EXPECT_EQ(start_time, load_timing_info.connect_timing.connect_start);
9703 EXPECT_EQ(start_time + 3 * kTimeIncrement,
9704 load_timing_info.connect_timing.connect_end);
9705
9706 EXPECT_TRUE(load_timing_info.send_start.is_null());
9707 EXPECT_TRUE(load_timing_info.send_end.is_null());
9708 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:299709}
9710
[email protected]4eddbc732012-08-09 05:40:179711// Test that an HTTPS proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:019712TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaHttpsProxy) {
Ramin Halavatica8d5252018-03-12 05:33:499713 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9714 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299715
9716 HttpRequestInfo request;
9717 request.method = "GET";
bncce36dca22015-04-21 22:11:239718 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109719 request.traffic_annotation =
9720 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299721
9722 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179723 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9724 "Host: www.example.org:443\r\n"
9725 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:299726 };
9727
9728 MockRead data_reads[] = {
9729 MockRead("HTTP/1.1 404 Not Found\r\n"),
9730 MockRead("Content-Length: 23\r\n\r\n"),
9731 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:069732 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:299733 };
9734
Ryan Sleevib8d7ea02018-05-07 20:01:019735 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069736 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:299737
[email protected]bb88e1d32013-05-03 23:11:079738 session_deps_.socket_factory->AddSocketDataProvider(&data);
9739 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:299740
[email protected]49639fa2011-12-20 23:22:419741 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:299742
danakj1fd259a02016-04-16 03:17:099743 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169744 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:299745
tfarina42834112016-09-22 13:38:209746 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019747 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:299748
9749 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019750 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:299751
ttuttle960fcbf2016-04-19 13:26:329752 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:299753}
9754
[email protected]4eddbc732012-08-09 05:40:179755// Test that a SPDY proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:019756TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaSpdyProxy) {
Ramin Halavatica8d5252018-03-12 05:33:499757 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9758 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299759
9760 HttpRequestInfo request;
9761 request.method = "GET";
bncce36dca22015-04-21 22:11:239762 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109763 request.traffic_annotation =
9764 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299765
Ryan Hamilton0239aac2018-05-19 00:03:139766 spdy::SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:239767 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:139768 spdy::SpdySerializedFrame rst(
9769 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:299770 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:419771 CreateMockWrite(conn, 0), CreateMockWrite(rst, 3),
[email protected]511f6f52010-12-17 03:58:299772 };
9773
9774 static const char* const kExtraHeaders[] = {
9775 "location",
9776 "http://login.example.com/",
9777 };
Ryan Hamilton0239aac2018-05-19 00:03:139778 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
Avi Drissman4365a4782018-12-28 19:26:249779 "404", kExtraHeaders, base::size(kExtraHeaders) / 2, 1));
Ryan Hamilton0239aac2018-05-19 00:03:139780 spdy::SpdySerializedFrame body(
Bence Békyd74f4382018-02-20 18:26:199781 spdy_util_.ConstructSpdyDataFrame(1, "The host does not exist", true));
[email protected]511f6f52010-12-17 03:58:299782 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:419783 CreateMockRead(resp, 1), CreateMockRead(body, 2),
rch8e6c6c42015-05-01 14:05:139784 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:299785 };
9786
Ryan Sleevib8d7ea02018-05-07 20:01:019787 SequencedSocketData data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069788 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:369789 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:299790
[email protected]bb88e1d32013-05-03 23:11:079791 session_deps_.socket_factory->AddSocketDataProvider(&data);
9792 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:299793
[email protected]49639fa2011-12-20 23:22:419794 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:299795
danakj1fd259a02016-04-16 03:17:099796 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169797 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:299798
tfarina42834112016-09-22 13:38:209799 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019800 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:299801
9802 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019803 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:299804
ttuttle960fcbf2016-04-19 13:26:329805 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:299806}
9807
[email protected]0c5fb722012-02-28 11:50:359808// Test the request-challenge-retry sequence for basic auth, through
9809// a SPDY proxy over a single SPDY session.
bncd16676a2016-07-20 16:23:019810TEST_F(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:359811 HttpRequestInfo request;
9812 request.method = "GET";
bncce36dca22015-04-21 22:11:239813 request.url = GURL("https://www.example.org/");
[email protected]0c5fb722012-02-28 11:50:359814 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:299815 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:109816 request.traffic_annotation =
9817 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0c5fb722012-02-28 11:50:359818
9819 // Configure against https proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:599820 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499821 ProxyResolutionService::CreateFixedFromPacResult(
9822 "HTTPS myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519823 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:079824 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:099825 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:359826
9827 // Since we have proxy, should try to establish tunnel.
Ryan Hamilton0239aac2018-05-19 00:03:139828 spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:239829 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:139830 spdy::SpdySerializedFrame rst(
9831 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
rdsmithebb50aa2015-11-12 03:44:389832 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]0c5fb722012-02-28 11:50:359833
bnc691fda62016-08-12 00:43:169834 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0c5fb722012-02-28 11:50:359835 // be issuing -- the final header line contains the credentials.
9836 const char* const kAuthCredentials[] = {
9837 "proxy-authorization", "Basic Zm9vOmJhcg==",
9838 };
Ryan Hamilton0239aac2018-05-19 00:03:139839 spdy::SpdySerializedFrame connect2(spdy_util_.ConstructSpdyConnect(
Avi Drissman4365a4782018-12-28 19:26:249840 kAuthCredentials, base::size(kAuthCredentials) / 2, 3, LOWEST,
bncce36dca22015-04-21 22:11:239841 HostPortPair("www.example.org", 443)));
9842 // fetch https://www.example.org/ via HTTP
9843 const char get[] =
9844 "GET / HTTP/1.1\r\n"
9845 "Host: www.example.org\r\n"
9846 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:139847 spdy::SpdySerializedFrame wrapped_get(
Bence Békyd74f4382018-02-20 18:26:199848 spdy_util_.ConstructSpdyDataFrame(3, get, false));
[email protected]0c5fb722012-02-28 11:50:359849
9850 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:419851 CreateMockWrite(req, 0, ASYNC), CreateMockWrite(rst, 2, ASYNC),
9852 CreateMockWrite(connect2, 3), CreateMockWrite(wrapped_get, 5),
[email protected]0c5fb722012-02-28 11:50:359853 };
9854
9855 // The proxy responds to the connect with a 407, using a persistent
9856 // connection.
thestig9d3bb0c2015-01-24 00:49:519857 const char kAuthStatus[] = "407";
[email protected]0c5fb722012-02-28 11:50:359858 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:359859 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
9860 };
Ryan Hamilton0239aac2018-05-19 00:03:139861 spdy::SpdySerializedFrame conn_auth_resp(spdy_util_.ConstructSpdyReplyError(
Avi Drissman4365a4782018-12-28 19:26:249862 kAuthStatus, kAuthChallenge, base::size(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:359863
Ryan Hamilton0239aac2018-05-19 00:03:139864 spdy::SpdySerializedFrame conn_resp(
9865 spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:359866 const char resp[] = "HTTP/1.1 200 OK\r\n"
9867 "Content-Length: 5\r\n\r\n";
9868
Ryan Hamilton0239aac2018-05-19 00:03:139869 spdy::SpdySerializedFrame wrapped_get_resp(
Bence Békyd74f4382018-02-20 18:26:199870 spdy_util_.ConstructSpdyDataFrame(3, resp, false));
Ryan Hamilton0239aac2018-05-19 00:03:139871 spdy::SpdySerializedFrame wrapped_body(
Bence Békyd74f4382018-02-20 18:26:199872 spdy_util_.ConstructSpdyDataFrame(3, "hello", false));
[email protected]0c5fb722012-02-28 11:50:359873 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:419874 CreateMockRead(conn_auth_resp, 1, ASYNC),
9875 CreateMockRead(conn_resp, 4, ASYNC),
9876 CreateMockRead(wrapped_get_resp, 6, ASYNC),
9877 CreateMockRead(wrapped_body, 7, ASYNC),
rch8e6c6c42015-05-01 14:05:139878 MockRead(ASYNC, OK, 8), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:359879 };
9880
Ryan Sleevib8d7ea02018-05-07 20:01:019881 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:079882 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:359883 // Negotiate SPDY to the proxy
9884 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:369885 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:079886 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:359887 // Vanilla SSL to the server
9888 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:079889 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:359890
9891 TestCompletionCallback callback1;
9892
bnc87dcefc2017-05-25 12:47:589893 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:199894 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0c5fb722012-02-28 11:50:359895
9896 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:019897 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:359898
9899 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019900 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:469901 TestNetLogEntry::List entries;
[email protected]0c5fb722012-02-28 11:50:359902 log.GetEntries(&entries);
9903 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:009904 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
9905 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:359906 ExpectLogContainsSomewhere(
9907 entries, pos,
mikecirone8b85c432016-09-08 19:11:009908 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
9909 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:359910
9911 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529912 ASSERT_TRUE(response);
9913 ASSERT_TRUE(response->headers);
[email protected]0c5fb722012-02-28 11:50:359914 EXPECT_EQ(407, response->headers->response_code());
9915 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
wezca1070932016-05-26 20:30:529916 EXPECT_TRUE(response->auth_challenge);
asanka098c0092016-06-16 20:18:439917 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]0c5fb722012-02-28 11:50:359918
9919 TestCompletionCallback callback2;
9920
9921 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
9922 callback2.callback());
robpercival214763f2016-07-01 23:27:019923 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:359924
9925 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:019926 EXPECT_THAT(rv, IsOk());
[email protected]0c5fb722012-02-28 11:50:359927
9928 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529929 ASSERT_TRUE(response);
[email protected]0c5fb722012-02-28 11:50:359930
9931 EXPECT_TRUE(response->headers->IsKeepAlive());
9932 EXPECT_EQ(200, response->headers->response_code());
9933 EXPECT_EQ(5, response->headers->GetContentLength());
9934 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
9935
9936 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:529937 EXPECT_FALSE(response->auth_challenge);
[email protected]0c5fb722012-02-28 11:50:359938
[email protected]029c83b62013-01-24 05:28:209939 LoadTimingInfo load_timing_info;
9940 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
9941 TestLoadTimingNotReusedWithPac(load_timing_info,
9942 CONNECT_TIMING_HAS_SSL_TIMES);
9943
[email protected]0c5fb722012-02-28 11:50:359944 trans.reset();
9945 session->CloseAllConnections();
9946}
9947
[email protected]7c6f7ba2012-04-03 04:09:299948// Test that an explicitly trusted SPDY proxy can push a resource from an
9949// origin that is different from that of its associated resource.
bncd16676a2016-07-20 16:23:019950TEST_F(HttpNetworkTransactionTest, CrossOriginSPDYProxyPush) {
tbansal28e68f82016-02-04 02:56:159951 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:199952 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:159953 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
9954 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]7c6f7ba2012-04-03 04:09:299955 HttpRequestInfo request;
9956 HttpRequestInfo push_request;
Ramin Halavatib5e433e2018-02-07 07:41:109957 request.traffic_annotation =
9958 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7c6f7ba2012-04-03 04:09:299959
[email protected]7c6f7ba2012-04-03 04:09:299960 request.method = "GET";
bncce36dca22015-04-21 22:11:239961 request.url = GURL("http://www.example.org/");
[email protected]7c6f7ba2012-04-03 04:09:299962 push_request.method = "GET";
9963 push_request.url = GURL("http://www.another-origin.com/foo.dat");
Ramin Halavatib5e433e2018-02-07 07:41:109964 push_request.traffic_annotation =
9965 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7c6f7ba2012-04-03 04:09:299966
tbansal28e68f82016-02-04 02:56:159967 // Configure against https proxy server "myproxy:443".
Lily Houghton8c2f97d2018-01-22 05:06:599968 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499969 ProxyResolutionService::CreateFixedFromPacResult(
9970 "HTTPS myproxy:443", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519971 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:079972 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:509973
Eric Roman3d8546a2018-09-10 17:00:529974 session_deps_.proxy_resolution_service->SetProxyDelegate(
9975 proxy_delegate.get());
[email protected]61b4efc2012-04-27 18:12:509976
danakj1fd259a02016-04-16 03:17:099977 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:299978
Ryan Hamilton0239aac2018-05-19 00:03:139979 spdy::SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:459980 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:139981 spdy::SpdySerializedFrame stream2_priority(
tombergan5d22c182017-01-11 02:05:359982 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
[email protected]7c6f7ba2012-04-03 04:09:299983
9984 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:419985 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:359986 CreateMockWrite(stream2_priority, 3, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:299987 };
9988
Ryan Hamilton0239aac2018-05-19 00:03:139989 spdy::SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
Bence Béky7bf94362018-01-10 13:19:369990 NULL, 0, 2, 1, "http://www.another-origin.com/foo.dat"));
9991
Ryan Hamilton0239aac2018-05-19 00:03:139992 spdy::SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:159993 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:299994
Ryan Hamilton0239aac2018-05-19 00:03:139995 spdy::SpdySerializedFrame stream1_body(
9996 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:299997
Ryan Hamilton0239aac2018-05-19 00:03:139998 spdy::SpdySerializedFrame stream2_body(
Bence Békyd74f4382018-02-20 18:26:199999 spdy_util_.ConstructSpdyDataFrame(2, "pushed", true));
[email protected]7c6f7ba2012-04-03 04:09:2910000
10001 MockRead spdy_reads[] = {
Bence Béky7bf94362018-01-10 13:19:3610002 CreateMockRead(stream2_syn, 1, ASYNC),
10003 CreateMockRead(stream1_reply, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:3510004 CreateMockRead(stream1_body, 4, ASYNC),
10005 CreateMockRead(stream2_body, 5, ASYNC),
10006 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
[email protected]7c6f7ba2012-04-03 04:09:2910007 };
10008
Ryan Sleevib8d7ea02018-05-07 20:01:0110009 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0710010 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:2910011 // Negotiate SPDY to the proxy
10012 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610013 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0710014 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:2910015
bnc87dcefc2017-05-25 12:47:5810016 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1910017 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7c6f7ba2012-04-03 04:09:2910018 TestCompletionCallback callback;
10019 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0110020 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:2910021
10022 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110023 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:2910024 const HttpResponseInfo* response = trans->GetResponseInfo();
10025
bnc87dcefc2017-05-25 12:47:5810026 auto push_trans =
Jeremy Roman0579ed62017-08-29 15:56:1910027 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]90499482013-06-01 00:39:5010028 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0110029 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:2910030
10031 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110032 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:2910033 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
10034
wezca1070932016-05-26 20:30:5210035 ASSERT_TRUE(response);
[email protected]7c6f7ba2012-04-03 04:09:2910036 EXPECT_TRUE(response->headers->IsKeepAlive());
10037
10038 EXPECT_EQ(200, response->headers->response_code());
10039 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10040
10041 std::string response_data;
10042 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:0110043 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:2910044 EXPECT_EQ("hello!", response_data);
10045
[email protected]029c83b62013-01-24 05:28:2010046 LoadTimingInfo load_timing_info;
10047 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10048 TestLoadTimingNotReusedWithPac(load_timing_info,
10049 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
10050
[email protected]7c6f7ba2012-04-03 04:09:2910051 // Verify the pushed stream.
wezca1070932016-05-26 20:30:5210052 EXPECT_TRUE(push_response->headers);
[email protected]7c6f7ba2012-04-03 04:09:2910053 EXPECT_EQ(200, push_response->headers->response_code());
10054
10055 rv = ReadTransaction(push_trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:0110056 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:2910057 EXPECT_EQ("pushed", response_data);
10058
[email protected]029c83b62013-01-24 05:28:2010059 LoadTimingInfo push_load_timing_info;
10060 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
10061 TestLoadTimingReusedWithPac(push_load_timing_info);
10062 // The transactions should share a socket ID, despite being for different
10063 // origins.
10064 EXPECT_EQ(load_timing_info.socket_log_id,
10065 push_load_timing_info.socket_log_id);
10066
[email protected]7c6f7ba2012-04-03 04:09:2910067 trans.reset();
10068 push_trans.reset();
10069 session->CloseAllConnections();
10070}
10071
[email protected]8c843192012-04-05 07:15:0010072// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
bncd16676a2016-07-20 16:23:0110073TEST_F(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:1510074 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:1910075 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:1510076 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
10077 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]8c843192012-04-05 07:15:0010078 HttpRequestInfo request;
10079
10080 request.method = "GET";
bncce36dca22015-04-21 22:11:2310081 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010082 request.traffic_annotation =
10083 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c843192012-04-05 07:15:0010084
Ramin Halavatica8d5252018-03-12 05:33:4910085 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
10086 "https://myproxy:443", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110087 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710088 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:5010089
10090 // Enable cross-origin push.
Eric Roman3d8546a2018-09-10 17:00:5210091 session_deps_.proxy_resolution_service->SetProxyDelegate(
10092 proxy_delegate.get());
[email protected]61b4efc2012-04-27 18:12:5010093
danakj1fd259a02016-04-16 03:17:0910094 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:0010095
Ryan Hamilton0239aac2018-05-19 00:03:1310096 spdy::SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:4510097 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
[email protected]8c843192012-04-05 07:15:0010098
Ryan Hamilton0239aac2018-05-19 00:03:1310099 spdy::SpdySerializedFrame push_rst(
10100 spdy_util_.ConstructSpdyRstStream(2, spdy::ERROR_CODE_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:0010101
10102 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4110103 CreateMockWrite(stream1_syn, 0, ASYNC), CreateMockWrite(push_rst, 3),
[email protected]8c843192012-04-05 07:15:0010104 };
10105
Ryan Hamilton0239aac2018-05-19 00:03:1310106 spdy::SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:1510107 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:0010108
Ryan Hamilton0239aac2018-05-19 00:03:1310109 spdy::SpdySerializedFrame stream1_body(
10110 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]8c843192012-04-05 07:15:0010111
Ryan Hamilton0239aac2018-05-19 00:03:1310112 spdy::SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
bncb03b1092016-04-06 11:19:5510113 NULL, 0, 2, 1, "https://www.another-origin.com/foo.dat"));
[email protected]8c843192012-04-05 07:15:0010114
10115 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4110116 CreateMockRead(stream1_reply, 1, ASYNC),
10117 CreateMockRead(stream2_syn, 2, ASYNC),
10118 CreateMockRead(stream1_body, 4, ASYNC),
mmenkee24011922015-12-17 22:12:5910119 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
[email protected]8c843192012-04-05 07:15:0010120 };
10121
Ryan Sleevib8d7ea02018-05-07 20:01:0110122 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0710123 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:0010124 // Negotiate SPDY to the proxy
10125 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610126 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0710127 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:0010128
bnc87dcefc2017-05-25 12:47:5810129 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1910130 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]8c843192012-04-05 07:15:0010131 TestCompletionCallback callback;
10132 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0110133 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c843192012-04-05 07:15:0010134
10135 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110136 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:0010137 const HttpResponseInfo* response = trans->GetResponseInfo();
10138
wezca1070932016-05-26 20:30:5210139 ASSERT_TRUE(response);
[email protected]8c843192012-04-05 07:15:0010140 EXPECT_TRUE(response->headers->IsKeepAlive());
10141
10142 EXPECT_EQ(200, response->headers->response_code());
10143 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10144
10145 std::string response_data;
10146 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:0110147 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:0010148 EXPECT_EQ("hello!", response_data);
10149
10150 trans.reset();
10151 session->CloseAllConnections();
10152}
10153
tbansal8ef1d3e2016-02-03 04:05:4210154// Test that an explicitly trusted SPDY proxy can push same-origin HTTPS
10155// resources.
bncd16676a2016-07-20 16:23:0110156TEST_F(HttpNetworkTransactionTest, SameOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:1510157 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:1910158 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:1510159 proxy_delegate->set_trusted_spdy_proxy(
10160 net::ProxyServer::FromURI("myproxy:70", net::ProxyServer::SCHEME_HTTP));
10161
tbansal8ef1d3e2016-02-03 04:05:4210162 HttpRequestInfo request;
10163
10164 request.method = "GET";
10165 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010166 request.traffic_annotation =
10167 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal8ef1d3e2016-02-03 04:05:4210168
10169 // Configure against https proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:4910170 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
10171 "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal8ef1d3e2016-02-03 04:05:4210172 BoundTestNetLog log;
10173 session_deps_.net_log = log.bound().net_log();
10174
10175 // Enable cross-origin push.
Eric Roman3d8546a2018-09-10 17:00:5210176 session_deps_.proxy_resolution_service->SetProxyDelegate(
10177 proxy_delegate.get());
tbansal8ef1d3e2016-02-03 04:05:4210178
danakj1fd259a02016-04-16 03:17:0910179 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
tbansal8ef1d3e2016-02-03 04:05:4210180
Ryan Hamilton0239aac2018-05-19 00:03:1310181 spdy::SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:4510182 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1310183 spdy::SpdySerializedFrame stream2_priority(
tombergan5d22c182017-01-11 02:05:3510184 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
tbansal8ef1d3e2016-02-03 04:05:4210185
10186 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4110187 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:3510188 CreateMockWrite(stream2_priority, 3, ASYNC),
tbansal8ef1d3e2016-02-03 04:05:4210189 };
10190
Ryan Hamilton0239aac2018-05-19 00:03:1310191 spdy::SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:1510192 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:4210193
Ryan Hamilton0239aac2018-05-19 00:03:1310194 spdy::SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
Bence Béky096cf052017-08-08 23:55:3310195 nullptr, 0, 2, 1, "http://www.example.org/foo.dat"));
bnc38dcd392016-02-09 23:19:4910196
Ryan Hamilton0239aac2018-05-19 00:03:1310197 spdy::SpdySerializedFrame stream1_body(
10198 spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:4210199
Ryan Hamilton0239aac2018-05-19 00:03:1310200 spdy::SpdySerializedFrame stream2_reply(
bnc42331402016-07-25 13:36:1510201 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:4210202
Ryan Hamilton0239aac2018-05-19 00:03:1310203 spdy::SpdySerializedFrame stream2_body(
10204 spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:4210205
10206 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4110207 CreateMockRead(stream1_reply, 1, ASYNC),
10208 CreateMockRead(stream2_syn, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:3510209 CreateMockRead(stream1_body, 4, ASYNC),
10210 CreateMockRead(stream2_body, 5, ASYNC),
10211 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
tbansal8ef1d3e2016-02-03 04:05:4210212 };
10213
Ryan Sleevib8d7ea02018-05-07 20:01:0110214 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
tbansal8ef1d3e2016-02-03 04:05:4210215 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
10216 // Negotiate SPDY to the proxy
10217 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610218 proxy.next_proto = kProtoHTTP2;
tbansal8ef1d3e2016-02-03 04:05:4210219 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
10220
bnc87dcefc2017-05-25 12:47:5810221 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1910222 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tbansal8ef1d3e2016-02-03 04:05:4210223 TestCompletionCallback callback;
10224 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0110225 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
tbansal8ef1d3e2016-02-03 04:05:4210226
10227 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110228 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:4210229 const HttpResponseInfo* response = trans->GetResponseInfo();
10230
wezca1070932016-05-26 20:30:5210231 ASSERT_TRUE(response);
tbansal8ef1d3e2016-02-03 04:05:4210232 EXPECT_TRUE(response->headers->IsKeepAlive());
10233
10234 EXPECT_EQ(200, response->headers->response_code());
10235 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10236
10237 std::string response_data;
10238 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:0110239 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:4210240 EXPECT_EQ("hello!", response_data);
10241
10242 trans.reset();
10243 session->CloseAllConnections();
10244}
10245
[email protected]2df19bb2010-08-25 20:13:4610246// Test HTTPS connections to a site with a bad certificate, going through an
10247// HTTPS proxy
bncd16676a2016-07-20 16:23:0110248TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
Ramin Halavatica8d5252018-03-12 05:33:4910249 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
10250 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:4610251
10252 HttpRequestInfo request;
10253 request.method = "GET";
bncce36dca22015-04-21 22:11:2310254 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010255 request.traffic_annotation =
10256 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:4610257
10258 // Attempt to fetch the URL from a server with a bad cert
10259 MockWrite bad_cert_writes[] = {
rsleevidb16bb02015-11-12 23:47:1710260 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
10261 "Host: www.example.org:443\r\n"
10262 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:4610263 };
10264
10265 MockRead bad_cert_reads[] = {
10266 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610267 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:4610268 };
10269
10270 // Attempt to fetch the URL with a good cert
10271 MockWrite good_data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1710272 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
10273 "Host: www.example.org:443\r\n"
10274 "Proxy-Connection: keep-alive\r\n\r\n"),
10275 MockWrite("GET / HTTP/1.1\r\n"
10276 "Host: www.example.org\r\n"
10277 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:4610278 };
10279
10280 MockRead good_cert_reads[] = {
10281 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
10282 MockRead("HTTP/1.0 200 OK\r\n"),
10283 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10284 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610285 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:4610286 };
10287
Ryan Sleevib8d7ea02018-05-07 20:01:0110288 StaticSocketDataProvider ssl_bad_certificate(bad_cert_reads, bad_cert_writes);
10289 StaticSocketDataProvider data(good_cert_reads, good_data_writes);
[email protected]8ddf8322012-02-23 18:08:0610290 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
10291 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:4610292
10293 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:0710294 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10295 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
10296 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:4610297
10298 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:0710299 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10300 session_deps_.socket_factory->AddSocketDataProvider(&data);
10301 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:4610302
[email protected]49639fa2011-12-20 23:22:4110303 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:4610304
danakj1fd259a02016-04-16 03:17:0910305 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610306 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:4610307
tfarina42834112016-09-22 13:38:2010308 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110309 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:4610310
10311 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110312 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]2df19bb2010-08-25 20:13:4610313
bnc691fda62016-08-12 00:43:1610314 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:0110315 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:4610316
10317 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110318 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:4610319
bnc691fda62016-08-12 00:43:1610320 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:4610321
wezca1070932016-05-26 20:30:5210322 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:4610323 EXPECT_EQ(100, response->headers->GetContentLength());
10324}
10325
bncd16676a2016-07-20 16:23:0110326TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:4210327 HttpRequestInfo request;
10328 request.method = "GET";
bncce36dca22015-04-21 22:11:2310329 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:4310330 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
10331 "Chromium Ultra Awesome X Edition");
Ramin Halavatib5e433e2018-02-07 07:41:1010332 request.traffic_annotation =
10333 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210334
danakj1fd259a02016-04-16 03:17:0910335 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610336 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710337
[email protected]1c773ea12009-04-28 19:58:4210338 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310339 MockWrite(
10340 "GET / HTTP/1.1\r\n"
10341 "Host: www.example.org\r\n"
10342 "Connection: keep-alive\r\n"
10343 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210344 };
10345
10346 // Lastly, the server responds with the actual content.
10347 MockRead data_reads[] = {
10348 MockRead("HTTP/1.0 200 OK\r\n"),
10349 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10350 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610351 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210352 };
10353
Ryan Sleevib8d7ea02018-05-07 20:01:0110354 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710355 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210356
[email protected]49639fa2011-12-20 23:22:4110357 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210358
tfarina42834112016-09-22 13:38:2010359 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110360 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210361
10362 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110363 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210364}
10365
bncd16676a2016-07-20 16:23:0110366TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:2910367 HttpRequestInfo request;
10368 request.method = "GET";
bncce36dca22015-04-21 22:11:2310369 request.url = GURL("https://www.example.org/");
[email protected]da81f132010-08-18 23:39:2910370 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
10371 "Chromium Ultra Awesome X Edition");
Ramin Halavatib5e433e2018-02-07 07:41:1010372 request.traffic_annotation =
10373 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]da81f132010-08-18 23:39:2910374
Ramin Halavatica8d5252018-03-12 05:33:4910375 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
10376 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:0910377 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610378 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710379
[email protected]da81f132010-08-18 23:39:2910380 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1710381 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
10382 "Host: www.example.org:443\r\n"
10383 "Proxy-Connection: keep-alive\r\n"
10384 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]da81f132010-08-18 23:39:2910385 };
10386 MockRead data_reads[] = {
10387 // Return an error, so the transaction stops here (this test isn't
10388 // interested in the rest).
10389 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
10390 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
10391 MockRead("Proxy-Connection: close\r\n\r\n"),
10392 };
10393
Ryan Sleevib8d7ea02018-05-07 20:01:0110394 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710395 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:2910396
[email protected]49639fa2011-12-20 23:22:4110397 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:2910398
tfarina42834112016-09-22 13:38:2010399 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110400 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]da81f132010-08-18 23:39:2910401
10402 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110403 EXPECT_THAT(rv, IsOk());
[email protected]da81f132010-08-18 23:39:2910404}
10405
bncd16676a2016-07-20 16:23:0110406TEST_F(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:4210407 HttpRequestInfo request;
10408 request.method = "GET";
bncce36dca22015-04-21 22:11:2310409 request.url = GURL("http://www.example.org/");
[email protected]c10450102011-06-27 09:06:1610410 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
10411 "http://the.previous.site.com/");
Ramin Halavatib5e433e2018-02-07 07:41:1010412 request.traffic_annotation =
10413 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210414
danakj1fd259a02016-04-16 03:17:0910415 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610416 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710417
[email protected]1c773ea12009-04-28 19:58:4210418 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310419 MockWrite(
10420 "GET / HTTP/1.1\r\n"
10421 "Host: www.example.org\r\n"
10422 "Connection: keep-alive\r\n"
10423 "Referer: http://the.previous.site.com/\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210424 };
10425
10426 // Lastly, the server responds with the actual content.
10427 MockRead data_reads[] = {
10428 MockRead("HTTP/1.0 200 OK\r\n"),
10429 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10430 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610431 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210432 };
10433
Ryan Sleevib8d7ea02018-05-07 20:01:0110434 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710435 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210436
[email protected]49639fa2011-12-20 23:22:4110437 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210438
tfarina42834112016-09-22 13:38:2010439 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110440 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210441
10442 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110443 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210444}
10445
bncd16676a2016-07-20 16:23:0110446TEST_F(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:4210447 HttpRequestInfo request;
10448 request.method = "POST";
bncce36dca22015-04-21 22:11:2310449 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010450 request.traffic_annotation =
10451 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210452
danakj1fd259a02016-04-16 03:17:0910453 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610454 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710455
[email protected]1c773ea12009-04-28 19:58:4210456 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310457 MockWrite(
10458 "POST / HTTP/1.1\r\n"
10459 "Host: www.example.org\r\n"
10460 "Connection: keep-alive\r\n"
10461 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210462 };
10463
10464 // Lastly, the server responds with the actual content.
10465 MockRead data_reads[] = {
10466 MockRead("HTTP/1.0 200 OK\r\n"),
10467 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10468 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610469 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210470 };
10471
Ryan Sleevib8d7ea02018-05-07 20:01:0110472 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710473 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210474
[email protected]49639fa2011-12-20 23:22:4110475 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210476
tfarina42834112016-09-22 13:38:2010477 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110478 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210479
10480 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110481 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210482}
10483
bncd16676a2016-07-20 16:23:0110484TEST_F(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:4210485 HttpRequestInfo request;
10486 request.method = "PUT";
bncce36dca22015-04-21 22:11:2310487 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010488 request.traffic_annotation =
10489 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210490
danakj1fd259a02016-04-16 03:17:0910491 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610492 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710493
[email protected]1c773ea12009-04-28 19:58:4210494 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310495 MockWrite(
10496 "PUT / HTTP/1.1\r\n"
10497 "Host: www.example.org\r\n"
10498 "Connection: keep-alive\r\n"
10499 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210500 };
10501
10502 // Lastly, the server responds with the actual content.
10503 MockRead data_reads[] = {
10504 MockRead("HTTP/1.0 200 OK\r\n"),
10505 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10506 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610507 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210508 };
10509
Ryan Sleevib8d7ea02018-05-07 20:01:0110510 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710511 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210512
[email protected]49639fa2011-12-20 23:22:4110513 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210514
tfarina42834112016-09-22 13:38:2010515 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110516 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210517
10518 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110519 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210520}
10521
bncd16676a2016-07-20 16:23:0110522TEST_F(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:4210523 HttpRequestInfo request;
10524 request.method = "HEAD";
bncce36dca22015-04-21 22:11:2310525 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010526 request.traffic_annotation =
10527 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210528
danakj1fd259a02016-04-16 03:17:0910529 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610530 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710531
[email protected]1c773ea12009-04-28 19:58:4210532 MockWrite data_writes[] = {
csharrisonf473dd192015-08-18 13:54:1310533 MockWrite("HEAD / HTTP/1.1\r\n"
10534 "Host: www.example.org\r\n"
10535 "Connection: keep-alive\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210536 };
10537
10538 // Lastly, the server responds with the actual content.
10539 MockRead data_reads[] = {
10540 MockRead("HTTP/1.0 200 OK\r\n"),
10541 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10542 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610543 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210544 };
10545
Ryan Sleevib8d7ea02018-05-07 20:01:0110546 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710547 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210548
[email protected]49639fa2011-12-20 23:22:4110549 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210550
tfarina42834112016-09-22 13:38:2010551 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110552 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210553
10554 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110555 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210556}
10557
bncd16676a2016-07-20 16:23:0110558TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:4210559 HttpRequestInfo request;
10560 request.method = "GET";
bncce36dca22015-04-21 22:11:2310561 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:4210562 request.load_flags = LOAD_BYPASS_CACHE;
Ramin Halavatib5e433e2018-02-07 07:41:1010563 request.traffic_annotation =
10564 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210565
danakj1fd259a02016-04-16 03:17:0910566 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610567 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710568
[email protected]1c773ea12009-04-28 19:58:4210569 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310570 MockWrite(
10571 "GET / HTTP/1.1\r\n"
10572 "Host: www.example.org\r\n"
10573 "Connection: keep-alive\r\n"
10574 "Pragma: no-cache\r\n"
10575 "Cache-Control: no-cache\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210576 };
10577
10578 // Lastly, the server responds with the actual content.
10579 MockRead data_reads[] = {
10580 MockRead("HTTP/1.0 200 OK\r\n"),
10581 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10582 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610583 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210584 };
10585
Ryan Sleevib8d7ea02018-05-07 20:01:0110586 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710587 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210588
[email protected]49639fa2011-12-20 23:22:4110589 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210590
tfarina42834112016-09-22 13:38:2010591 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110592 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210593
10594 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110595 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210596}
10597
bncd16676a2016-07-20 16:23:0110598TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:4210599 HttpRequestInfo request;
10600 request.method = "GET";
bncce36dca22015-04-21 22:11:2310601 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:4210602 request.load_flags = LOAD_VALIDATE_CACHE;
Ramin Halavatib5e433e2018-02-07 07:41:1010603 request.traffic_annotation =
10604 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210605
danakj1fd259a02016-04-16 03:17:0910606 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610607 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710608
[email protected]1c773ea12009-04-28 19:58:4210609 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310610 MockWrite(
10611 "GET / HTTP/1.1\r\n"
10612 "Host: www.example.org\r\n"
10613 "Connection: keep-alive\r\n"
10614 "Cache-Control: max-age=0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210615 };
10616
10617 // Lastly, the server responds with the actual content.
10618 MockRead data_reads[] = {
10619 MockRead("HTTP/1.0 200 OK\r\n"),
10620 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10621 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610622 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210623 };
10624
Ryan Sleevib8d7ea02018-05-07 20:01:0110625 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710626 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210627
[email protected]49639fa2011-12-20 23:22:4110628 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210629
tfarina42834112016-09-22 13:38:2010630 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110631 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210632
10633 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110634 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210635}
10636
bncd16676a2016-07-20 16:23:0110637TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:4210638 HttpRequestInfo request;
10639 request.method = "GET";
bncce36dca22015-04-21 22:11:2310640 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:4310641 request.extra_headers.SetHeader("FooHeader", "Bar");
Ramin Halavatib5e433e2018-02-07 07:41:1010642 request.traffic_annotation =
10643 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210644
danakj1fd259a02016-04-16 03:17:0910645 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610646 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710647
[email protected]1c773ea12009-04-28 19:58:4210648 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310649 MockWrite(
10650 "GET / HTTP/1.1\r\n"
10651 "Host: www.example.org\r\n"
10652 "Connection: keep-alive\r\n"
10653 "FooHeader: Bar\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210654 };
10655
10656 // Lastly, the server responds with the actual content.
10657 MockRead data_reads[] = {
10658 MockRead("HTTP/1.0 200 OK\r\n"),
10659 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10660 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610661 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210662 };
10663
Ryan Sleevib8d7ea02018-05-07 20:01:0110664 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710665 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210666
[email protected]49639fa2011-12-20 23:22:4110667 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210668
tfarina42834112016-09-22 13:38:2010669 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110670 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210671
10672 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110673 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210674}
10675
bncd16676a2016-07-20 16:23:0110676TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:4710677 HttpRequestInfo request;
10678 request.method = "GET";
bncce36dca22015-04-21 22:11:2310679 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:4310680 request.extra_headers.SetHeader("referer", "www.foo.com");
10681 request.extra_headers.SetHeader("hEllo", "Kitty");
10682 request.extra_headers.SetHeader("FoO", "bar");
Ramin Halavatib5e433e2018-02-07 07:41:1010683 request.traffic_annotation =
10684 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]270c6412010-03-29 22:02:4710685
danakj1fd259a02016-04-16 03:17:0910686 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610687 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710688
[email protected]270c6412010-03-29 22:02:4710689 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310690 MockWrite(
10691 "GET / HTTP/1.1\r\n"
10692 "Host: www.example.org\r\n"
10693 "Connection: keep-alive\r\n"
10694 "referer: www.foo.com\r\n"
10695 "hEllo: Kitty\r\n"
10696 "FoO: bar\r\n\r\n"),
[email protected]270c6412010-03-29 22:02:4710697 };
10698
10699 // Lastly, the server responds with the actual content.
10700 MockRead data_reads[] = {
10701 MockRead("HTTP/1.0 200 OK\r\n"),
10702 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10703 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610704 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:4710705 };
10706
Ryan Sleevib8d7ea02018-05-07 20:01:0110707 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710708 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:4710709
[email protected]49639fa2011-12-20 23:22:4110710 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:4710711
tfarina42834112016-09-22 13:38:2010712 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110713 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]270c6412010-03-29 22:02:4710714
10715 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110716 EXPECT_THAT(rv, IsOk());
[email protected]270c6412010-03-29 22:02:4710717}
10718
bncd16676a2016-07-20 16:23:0110719TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:2710720 HttpRequestInfo request;
10721 request.method = "GET";
bncce36dca22015-04-21 22:11:2310722 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010723 request.traffic_annotation =
10724 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710725
Lily Houghton8c2f97d2018-01-22 05:06:5910726 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910727 ProxyResolutionService::CreateFixedFromPacResult(
10728 "SOCKS myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110729 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710730 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:0210731
danakj1fd259a02016-04-16 03:17:0910732 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610733 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:0210734
[email protected]3cd17242009-06-23 02:59:0210735 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
10736 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
10737
10738 MockWrite data_writes[] = {
Avi Drissman4365a4782018-12-28 19:26:2410739 MockWrite(ASYNC, write_buffer, base::size(write_buffer)),
10740 MockWrite("GET / HTTP/1.1\r\n"
10741 "Host: www.example.org\r\n"
10742 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:0210743
10744 MockRead data_reads[] = {
Avi Drissman4365a4782018-12-28 19:26:2410745 MockRead(ASYNC, read_buffer, base::size(read_buffer)),
10746 MockRead("HTTP/1.0 200 OK\r\n"),
10747 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
10748 MockRead("Payload"), MockRead(SYNCHRONOUS, OK)};
[email protected]3cd17242009-06-23 02:59:0210749
Ryan Sleevib8d7ea02018-05-07 20:01:0110750 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710751 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:0210752
[email protected]49639fa2011-12-20 23:22:4110753 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:0210754
tfarina42834112016-09-22 13:38:2010755 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110756 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:0210757
10758 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110759 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0210760
bnc691fda62016-08-12 00:43:1610761 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210762 ASSERT_TRUE(response);
[email protected]3cd17242009-06-23 02:59:0210763
tbansal2ecbbc72016-10-06 17:15:4710764 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]029c83b62013-01-24 05:28:2010765 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1610766 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2010767 TestLoadTimingNotReusedWithPac(load_timing_info,
10768 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
10769
[email protected]3cd17242009-06-23 02:59:0210770 std::string response_text;
bnc691fda62016-08-12 00:43:1610771 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0110772 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0210773 EXPECT_EQ("Payload", response_text);
10774}
10775
bncd16676a2016-07-20 16:23:0110776TEST_F(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:2710777 HttpRequestInfo request;
10778 request.method = "GET";
bncce36dca22015-04-21 22:11:2310779 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010780 request.traffic_annotation =
10781 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710782
Lily Houghton8c2f97d2018-01-22 05:06:5910783 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910784 ProxyResolutionService::CreateFixedFromPacResult(
10785 "SOCKS myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110786 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710787 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:0210788
danakj1fd259a02016-04-16 03:17:0910789 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610790 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:0210791
[email protected]3cd17242009-06-23 02:59:0210792 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
10793 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
10794
10795 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310796 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
Avi Drissman4365a4782018-12-28 19:26:2410797 base::size(write_buffer)),
10798 MockWrite("GET / HTTP/1.1\r\n"
10799 "Host: www.example.org\r\n"
10800 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:0210801
10802 MockRead data_reads[] = {
Avi Drissman4365a4782018-12-28 19:26:2410803 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
10804 base::size(read_buffer)),
10805 MockRead("HTTP/1.0 200 OK\r\n"),
10806 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
10807 MockRead("Payload"), MockRead(SYNCHRONOUS, OK)};
[email protected]e0c27be2009-07-15 13:09:3510808
Ryan Sleevib8d7ea02018-05-07 20:01:0110809 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710810 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:3510811
[email protected]8ddf8322012-02-23 18:08:0610812 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710813 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:3510814
[email protected]49639fa2011-12-20 23:22:4110815 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:3510816
tfarina42834112016-09-22 13:38:2010817 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110818 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:3510819
10820 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110821 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3510822
[email protected]029c83b62013-01-24 05:28:2010823 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1610824 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2010825 TestLoadTimingNotReusedWithPac(load_timing_info,
10826 CONNECT_TIMING_HAS_SSL_TIMES);
10827
bnc691fda62016-08-12 00:43:1610828 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210829 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:4710830 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:3510831
10832 std::string response_text;
bnc691fda62016-08-12 00:43:1610833 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0110834 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3510835 EXPECT_EQ("Payload", response_text);
10836}
10837
bncd16676a2016-07-20 16:23:0110838TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:2010839 HttpRequestInfo request;
10840 request.method = "GET";
bncce36dca22015-04-21 22:11:2310841 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010842 request.traffic_annotation =
10843 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:2010844
Ramin Halavatica8d5252018-03-12 05:33:4910845 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
10846 "socks4://myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110847 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710848 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:2010849
danakj1fd259a02016-04-16 03:17:0910850 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610851 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:2010852
10853 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
10854 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
10855
10856 MockWrite data_writes[] = {
Avi Drissman4365a4782018-12-28 19:26:2410857 MockWrite(ASYNC, write_buffer, base::size(write_buffer)),
10858 MockWrite("GET / HTTP/1.1\r\n"
10859 "Host: www.example.org\r\n"
10860 "Connection: keep-alive\r\n\r\n")};
[email protected]029c83b62013-01-24 05:28:2010861
10862 MockRead data_reads[] = {
Avi Drissman4365a4782018-12-28 19:26:2410863 MockRead(ASYNC, read_buffer, base::size(read_buffer)),
10864 MockRead("HTTP/1.0 200 OK\r\n"),
10865 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
10866 MockRead("Payload"), MockRead(SYNCHRONOUS, OK)};
[email protected]029c83b62013-01-24 05:28:2010867
Ryan Sleevib8d7ea02018-05-07 20:01:0110868 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710869 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:2010870
10871 TestCompletionCallback callback;
10872
tfarina42834112016-09-22 13:38:2010873 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110874 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:2010875
10876 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110877 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:2010878
bnc691fda62016-08-12 00:43:1610879 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210880 ASSERT_TRUE(response);
[email protected]029c83b62013-01-24 05:28:2010881
10882 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1610883 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2010884 TestLoadTimingNotReused(load_timing_info,
10885 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
10886
10887 std::string response_text;
bnc691fda62016-08-12 00:43:1610888 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0110889 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:2010890 EXPECT_EQ("Payload", response_text);
10891}
10892
bncd16676a2016-07-20 16:23:0110893TEST_F(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:2710894 HttpRequestInfo request;
10895 request.method = "GET";
bncce36dca22015-04-21 22:11:2310896 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010897 request.traffic_annotation =
10898 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710899
Lily Houghton8c2f97d2018-01-22 05:06:5910900 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910901 ProxyResolutionService::CreateFixedFromPacResult(
10902 "SOCKS5 myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110903 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710904 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:3510905
danakj1fd259a02016-04-16 03:17:0910906 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610907 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:3510908
[email protected]e0c27be2009-07-15 13:09:3510909 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
10910 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:3710911 const char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:2310912 0x05, // Version
10913 0x01, // Command (CONNECT)
10914 0x00, // Reserved.
10915 0x03, // Address type (DOMAINNAME).
10916 0x0F, // Length of domain (15)
10917 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
10918 '.', 'o', 'r', 'g', 0x00, 0x50, // 16-bit port (80)
[email protected]f209dba2009-12-18 00:24:3710919 };
[email protected]e0c27be2009-07-15 13:09:3510920 const char kSOCKS5OkResponse[] =
10921 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
10922
10923 MockWrite data_writes[] = {
Avi Drissman4365a4782018-12-28 19:26:2410924 MockWrite(ASYNC, kSOCKS5GreetRequest, base::size(kSOCKS5GreetRequest)),
10925 MockWrite(ASYNC, kSOCKS5OkRequest, base::size(kSOCKS5OkRequest)),
10926 MockWrite("GET / HTTP/1.1\r\n"
10927 "Host: www.example.org\r\n"
10928 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:3510929
10930 MockRead data_reads[] = {
Avi Drissman4365a4782018-12-28 19:26:2410931 MockRead(ASYNC, kSOCKS5GreetResponse, base::size(kSOCKS5GreetResponse)),
10932 MockRead(ASYNC, kSOCKS5OkResponse, base::size(kSOCKS5OkResponse)),
10933 MockRead("HTTP/1.0 200 OK\r\n"),
10934 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
10935 MockRead("Payload"),
10936 MockRead(SYNCHRONOUS, OK)};
[email protected]e0c27be2009-07-15 13:09:3510937
Ryan Sleevib8d7ea02018-05-07 20:01:0110938 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710939 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:3510940
[email protected]49639fa2011-12-20 23:22:4110941 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:3510942
tfarina42834112016-09-22 13:38:2010943 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110944 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:3510945
10946 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110947 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3510948
bnc691fda62016-08-12 00:43:1610949 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210950 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:4710951 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:3510952
[email protected]029c83b62013-01-24 05:28:2010953 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1610954 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2010955 TestLoadTimingNotReusedWithPac(load_timing_info,
10956 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
10957
[email protected]e0c27be2009-07-15 13:09:3510958 std::string response_text;
bnc691fda62016-08-12 00:43:1610959 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0110960 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3510961 EXPECT_EQ("Payload", response_text);
10962}
10963
bncd16676a2016-07-20 16:23:0110964TEST_F(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:2710965 HttpRequestInfo request;
10966 request.method = "GET";
bncce36dca22015-04-21 22:11:2310967 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010968 request.traffic_annotation =
10969 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710970
Lily Houghton8c2f97d2018-01-22 05:06:5910971 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910972 ProxyResolutionService::CreateFixedFromPacResult(
10973 "SOCKS5 myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110974 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710975 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:3510976
danakj1fd259a02016-04-16 03:17:0910977 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610978 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:3510979
[email protected]e0c27be2009-07-15 13:09:3510980 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
10981 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:3710982 const unsigned char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:2310983 0x05, // Version
10984 0x01, // Command (CONNECT)
10985 0x00, // Reserved.
10986 0x03, // Address type (DOMAINNAME).
10987 0x0F, // Length of domain (15)
10988 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
10989 '.', 'o', 'r', 'g', 0x01, 0xBB, // 16-bit port (443)
[email protected]f209dba2009-12-18 00:24:3710990 };
10991
[email protected]e0c27be2009-07-15 13:09:3510992 const char kSOCKS5OkResponse[] =
10993 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
10994
10995 MockWrite data_writes[] = {
Avi Drissman4365a4782018-12-28 19:26:2410996 MockWrite(ASYNC, kSOCKS5GreetRequest, base::size(kSOCKS5GreetRequest)),
bncce36dca22015-04-21 22:11:2310997 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
Avi Drissman4365a4782018-12-28 19:26:2410998 base::size(kSOCKS5OkRequest)),
10999 MockWrite("GET / HTTP/1.1\r\n"
11000 "Host: www.example.org\r\n"
11001 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:3511002
11003 MockRead data_reads[] = {
Avi Drissman4365a4782018-12-28 19:26:2411004 MockRead(ASYNC, kSOCKS5GreetResponse, base::size(kSOCKS5GreetResponse)),
11005 MockRead(ASYNC, kSOCKS5OkResponse, base::size(kSOCKS5OkResponse)),
11006 MockRead("HTTP/1.0 200 OK\r\n"),
11007 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
11008 MockRead("Payload"),
11009 MockRead(SYNCHRONOUS, OK)};
[email protected]3cd17242009-06-23 02:59:0211010
Ryan Sleevib8d7ea02018-05-07 20:01:0111011 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0711012 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:0211013
[email protected]8ddf8322012-02-23 18:08:0611014 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0711015 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:0211016
[email protected]49639fa2011-12-20 23:22:4111017 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:0211018
tfarina42834112016-09-22 13:38:2011019 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111020 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:0211021
11022 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111023 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0211024
bnc691fda62016-08-12 00:43:1611025 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211026 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:4711027 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]3cd17242009-06-23 02:59:0211028
[email protected]029c83b62013-01-24 05:28:2011029 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1611030 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2011031 TestLoadTimingNotReusedWithPac(load_timing_info,
11032 CONNECT_TIMING_HAS_SSL_TIMES);
11033
[email protected]3cd17242009-06-23 02:59:0211034 std::string response_text;
bnc691fda62016-08-12 00:43:1611035 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0111036 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0211037 EXPECT_EQ("Payload", response_text);
11038}
11039
[email protected]448d4ca52012-03-04 04:12:2311040namespace {
11041
[email protected]04e5be32009-06-26 20:00:3111042// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:0611043
11044struct GroupNameTest {
11045 std::string proxy_server;
11046 std::string url;
11047 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:1811048 bool ssl;
[email protected]2d731a32010-04-29 01:04:0611049};
11050
danakj1fd259a02016-04-16 03:17:0911051std::unique_ptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]bb88e1d32013-05-03 23:11:0711052 SpdySessionDependencies* session_deps_) {
danakj1fd259a02016-04-16 03:17:0911053 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:0611054
bnc525e175a2016-06-20 12:36:4011055 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311056 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2111057 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnc7dc7e1b42015-07-28 14:43:1211058 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111059 http_server_properties->SetHttp2AlternativeService(
bncaa60ff402016-06-22 19:12:4211060 url::SchemeHostPort("https", "host.with.alternate", 443),
zhongyi3d4a55e72016-04-22 20:36:4611061 alternative_service, expiration);
[email protected]2d731a32010-04-29 01:04:0611062
11063 return session;
11064}
11065
mmenkee65e7af2015-10-13 17:16:4211066int GroupNameTransactionHelper(const std::string& url,
11067 HttpNetworkSession* session) {
[email protected]2d731a32010-04-29 01:04:0611068 HttpRequestInfo request;
11069 request.method = "GET";
11070 request.url = GURL(url);
Ramin Halavatib5e433e2018-02-07 07:41:1011071 request.traffic_annotation =
11072 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d731a32010-04-29 01:04:0611073
bnc691fda62016-08-12 00:43:1611074 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
[email protected]cb9bf6ca2011-01-28 13:15:2711075
[email protected]49639fa2011-12-20 23:22:4111076 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:0611077
11078 // We do not complete this request, the dtor will clean the transaction up.
tfarina42834112016-09-22 13:38:2011079 return trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]2d731a32010-04-29 01:04:0611080}
11081
[email protected]448d4ca52012-03-04 04:12:2311082} // namespace
11083
bncd16676a2016-07-20 16:23:0111084TEST_F(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:0611085 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:2311086 {
11087 "", // unused
11088 "http://www.example.org/direct",
11089 "www.example.org:80",
11090 false,
11091 },
11092 {
11093 "", // unused
11094 "http://[2001:1418:13:1::25]/direct",
11095 "[2001:1418:13:1::25]:80",
11096 false,
11097 },
[email protected]04e5be32009-06-26 20:00:3111098
bncce36dca22015-04-21 22:11:2311099 // SSL Tests
11100 {
11101 "", // unused
11102 "https://www.example.org/direct_ssl",
11103 "ssl/www.example.org:443",
11104 true,
11105 },
11106 {
11107 "", // unused
11108 "https://[2001:1418:13:1::25]/direct",
11109 "ssl/[2001:1418:13:1::25]:443",
11110 true,
11111 },
11112 {
11113 "", // unused
bncaa60ff402016-06-22 19:12:4211114 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:2311115 "ssl/host.with.alternate:443",
11116 true,
11117 },
[email protected]2d731a32010-04-29 01:04:0611118 };
[email protected]2ff8b312010-04-26 22:20:5411119
Avi Drissman4365a4782018-12-28 19:26:2411120 for (size_t i = 0; i < base::size(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5911121 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4911122 ProxyResolutionService::CreateFixed(tests[i].proxy_server,
11123 TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:0911124 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:4011125 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:0611126
mmenkee65e7af2015-10-13 17:16:4211127 HttpNetworkSessionPeer peer(session.get());
[email protected]ab739042011-04-07 15:22:2811128 CaptureGroupNameTransportSocketPool* transport_conn_pool =
bnc87dcefc2017-05-25 12:47:5811129 new CaptureGroupNameTransportSocketPool(nullptr, nullptr);
Jeremy Roman0579ed62017-08-29 15:56:1911130 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
[email protected]a42dbd142011-11-17 16:42:0211131 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
dchengc7eeda422015-12-26 03:56:4811132 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:0611133
11134 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:4211135 GroupNameTransactionHelper(tests[i].url, session.get()));
Matt Menke9d5e2c92019-02-05 01:42:2311136 EXPECT_EQ(tests[i].expected_group_name,
11137 transport_conn_pool->last_group_name_received());
11138 EXPECT_TRUE(transport_conn_pool->socket_requested());
[email protected]2d731a32010-04-29 01:04:0611139 }
[email protected]2d731a32010-04-29 01:04:0611140}
11141
bncd16676a2016-07-20 16:23:0111142TEST_F(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:0611143 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:2311144 {
Matt Menked1eb6d42018-01-17 04:54:0611145 "http_proxy", "http://www.example.org/http_proxy_normal",
11146 "http_proxy/www.example.org:80", false,
bncce36dca22015-04-21 22:11:2311147 },
[email protected]2d731a32010-04-29 01:04:0611148
bncce36dca22015-04-21 22:11:2311149 // SSL Tests
11150 {
Matt Menked1eb6d42018-01-17 04:54:0611151 "http_proxy", "https://www.example.org/http_connect_ssl",
11152 "http_proxy/ssl/www.example.org:443", true,
bncce36dca22015-04-21 22:11:2311153 },
[email protected]af3490e2010-10-16 21:02:2911154
bncce36dca22015-04-21 22:11:2311155 {
Matt Menked1eb6d42018-01-17 04:54:0611156 "http_proxy", "https://host.with.alternate/direct",
11157 "http_proxy/ssl/host.with.alternate:443", true,
bncce36dca22015-04-21 22:11:2311158 },
[email protected]45499252013-01-23 17:12:5611159
bncce36dca22015-04-21 22:11:2311160 {
Matt Menked1eb6d42018-01-17 04:54:0611161 "http_proxy", "ftp://ftp.google.com/http_proxy_normal",
11162 "http_proxy/ftp/ftp.google.com:21", false,
bncce36dca22015-04-21 22:11:2311163 },
[email protected]2d731a32010-04-29 01:04:0611164 };
11165
Avi Drissman4365a4782018-12-28 19:26:2411166 for (size_t i = 0; i < base::size(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5911167 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4911168 ProxyResolutionService::CreateFixed(tests[i].proxy_server,
11169 TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:0911170 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:4011171 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:0611172
mmenkee65e7af2015-10-13 17:16:4211173 HttpNetworkSessionPeer peer(session.get());
[email protected]2d731a32010-04-29 01:04:0611174
Matt Menkee8648fa2019-01-17 16:47:0711175 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
11176 HostPortPair("http_proxy", 80));
Matt Menke0754b5d02019-02-10 21:46:4311177 CaptureGroupNameTransportSocketPool* http_proxy_pool =
11178 new CaptureGroupNameTransportSocketPool(NULL, NULL);
Matt Menkedf126e0e2019-02-01 22:23:4711179 CaptureGroupNameTransportSocketPool* ssl_conn_pool =
11180 new CaptureGroupNameTransportSocketPool(NULL, NULL);
Jeremy Roman0579ed62017-08-29 15:56:1911181 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
aviadef3442016-10-03 18:50:3911182 mock_pool_manager->SetSocketPoolForHTTPProxy(
Matt Menkee8648fa2019-01-17 16:47:0711183 proxy_server, base::WrapUnique(http_proxy_pool));
aviadef3442016-10-03 18:50:3911184 mock_pool_manager->SetSocketPoolForSSLWithProxy(
Matt Menkee8648fa2019-01-17 16:47:0711185 proxy_server, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:4811186 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:0611187
11188 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:4211189 GroupNameTransactionHelper(tests[i].url, session.get()));
Matt Menkee8648fa2019-01-17 16:47:0711190 if (tests[i].ssl) {
[email protected]e60e47a2010-07-14 03:37:1811191 EXPECT_EQ(tests[i].expected_group_name,
11192 ssl_conn_pool->last_group_name_received());
Matt Menkee8648fa2019-01-17 16:47:0711193 } else {
[email protected]e60e47a2010-07-14 03:37:1811194 EXPECT_EQ(tests[i].expected_group_name,
11195 http_proxy_pool->last_group_name_received());
Matt Menkee8648fa2019-01-17 16:47:0711196 }
[email protected]2d731a32010-04-29 01:04:0611197 }
[email protected]2d731a32010-04-29 01:04:0611198}
11199
bncd16676a2016-07-20 16:23:0111200TEST_F(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:0611201 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:2311202 {
11203 "socks4://socks_proxy:1080",
11204 "http://www.example.org/socks4_direct",
11205 "socks4/www.example.org:80",
11206 false,
11207 },
11208 {
11209 "socks5://socks_proxy:1080",
11210 "http://www.example.org/socks5_direct",
11211 "socks5/www.example.org:80",
11212 false,
11213 },
[email protected]2d731a32010-04-29 01:04:0611214
bncce36dca22015-04-21 22:11:2311215 // SSL Tests
11216 {
11217 "socks4://socks_proxy:1080",
11218 "https://www.example.org/socks4_ssl",
11219 "socks4/ssl/www.example.org:443",
11220 true,
11221 },
11222 {
11223 "socks5://socks_proxy:1080",
11224 "https://www.example.org/socks5_ssl",
11225 "socks5/ssl/www.example.org:443",
11226 true,
11227 },
[email protected]af3490e2010-10-16 21:02:2911228
bncce36dca22015-04-21 22:11:2311229 {
11230 "socks4://socks_proxy:1080",
bncaa60ff402016-06-22 19:12:4211231 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:2311232 "socks4/ssl/host.with.alternate:443",
11233 true,
11234 },
[email protected]04e5be32009-06-26 20:00:3111235 };
11236
Avi Drissman4365a4782018-12-28 19:26:2411237 for (size_t i = 0; i < base::size(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5911238 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4911239 ProxyResolutionService::CreateFixed(tests[i].proxy_server,
11240 TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:0911241 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:4011242 SetupSessionForGroupNameTests(&session_deps_));
[email protected]8b114dd72011-03-25 05:33:0211243
mmenkee65e7af2015-10-13 17:16:4211244 HttpNetworkSessionPeer peer(session.get());
[email protected]04e5be32009-06-26 20:00:3111245
Matt Menkee8648fa2019-01-17 16:47:0711246 ProxyServer proxy_server(
11247 ProxyServer::FromURI(tests[i].proxy_server, ProxyServer::SCHEME_HTTP));
11248 ASSERT_TRUE(proxy_server.is_valid());
Matt Menke4b412da2019-01-25 19:31:1211249 CaptureGroupNameTransportSocketPool* socks_conn_pool =
11250 new CaptureGroupNameTransportSocketPool(NULL, NULL);
Jeremy Roman0579ed62017-08-29 15:56:1911251 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
Matt Menke4b412da2019-01-25 19:31:1211252 mock_pool_manager->SetSocketPoolForProxy(proxy_server,
11253 base::WrapUnique(socks_conn_pool));
dchengc7eeda422015-12-26 03:56:4811254 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]04e5be32009-06-26 20:00:3111255
bnc691fda62016-08-12 00:43:1611256 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]04e5be32009-06-26 20:00:3111257
[email protected]2d731a32010-04-29 01:04:0611258 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:4211259 GroupNameTransactionHelper(tests[i].url, session.get()));
Matt Menke628d624f2019-02-09 00:40:2411260 EXPECT_EQ(tests[i].expected_group_name,
11261 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:3111262 }
11263}
11264
bncd16676a2016-07-20 16:23:0111265TEST_F(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:2711266 HttpRequestInfo request;
11267 request.method = "GET";
bncce36dca22015-04-21 22:11:2311268 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011269 request.traffic_annotation =
11270 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2711271
Ramin Halavatica8d5252018-03-12 05:33:4911272 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
11273 "myproxy:70;foobar:80", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]b59ff372009-07-15 22:04:3211274
[email protected]69719062010-01-05 20:09:2111275 // This simulates failure resolving all hostnames; that means we will fail
11276 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:0711277 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:3211278
danakj1fd259a02016-04-16 03:17:0911279 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611280 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]9172a982009-06-06 00:30:2511281
[email protected]49639fa2011-12-20 23:22:4111282 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:2511283
tfarina42834112016-09-22 13:38:2011284 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111285 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9172a982009-06-06 00:30:2511286
[email protected]9172a982009-06-06 00:30:2511287 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111288 EXPECT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]9172a982009-06-06 00:30:2511289}
11290
Miriam Gershenson2a01b162018-03-22 22:54:4711291// LOAD_BYPASS_CACHE should trigger the host cache bypass.
11292TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh) {
[email protected]cb9bf6ca2011-01-28 13:15:2711293 // Issue a request, asking to bypass the cache(s).
maksim.sisov31452af2016-07-27 06:38:1011294 HttpRequestInfo request_info;
11295 request_info.method = "GET";
Miriam Gershenson2a01b162018-03-22 22:54:4711296 request_info.load_flags = LOAD_BYPASS_CACHE;
maksim.sisov31452af2016-07-27 06:38:1011297 request_info.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011298 request_info.traffic_annotation =
11299 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2711300
[email protected]a2c2fb92009-07-18 07:31:0411301 // Select a host resolver that does caching.
Jeremy Roman0579ed62017-08-29 15:56:1911302 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
[email protected]b59ff372009-07-15 22:04:3211303
danakj1fd259a02016-04-16 03:17:0911304 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611305 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3b9cca42009-06-16 01:08:2811306
bncce36dca22015-04-21 22:11:2311307 // Warm up the host cache so it has an entry for "www.example.org".
Eric Orthf4db66a2019-02-19 21:35:3311308 int rv = session_deps_.host_resolver->LoadIntoCache(
11309 HostPortPair("www.example.org", 80), base::nullopt);
robpercival214763f2016-07-01 23:27:0111310 EXPECT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:2811311
bncce36dca22015-04-21 22:11:2311312 // Inject a failure the next time that "www.example.org" is resolved. This way
[email protected]3b9cca42009-06-16 01:08:2811313 // we can tell if the next lookup hit the cache, or the "network".
11314 // (cache --> success, "network" --> failure).
bncce36dca22015-04-21 22:11:2311315 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.example.org");
[email protected]3b9cca42009-06-16 01:08:2811316
11317 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
11318 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:0611319 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
Ryan Sleevib8d7ea02018-05-07 20:01:0111320 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711321 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:2811322
[email protected]3b9cca42009-06-16 01:08:2811323 // Run the request.
Eric Orthf4db66a2019-02-19 21:35:3311324 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2011325 rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111326 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]49639fa2011-12-20 23:22:4111327 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:2811328
11329 // If we bypassed the cache, we would have gotten a failure while resolving
bncce36dca22015-04-21 22:11:2311330 // "www.example.org".
robpercival214763f2016-07-01 23:27:0111331 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]3b9cca42009-06-16 01:08:2811332}
11333
[email protected]0877e3d2009-10-17 22:29:5711334// Make sure we can handle an error when writing the request.
bncd16676a2016-07-20 16:23:0111335TEST_F(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:5711336 HttpRequestInfo request;
11337 request.method = "GET";
11338 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:1011339 request.traffic_annotation =
11340 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5711341
11342 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:0611343 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:5711344 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111345 StaticSocketDataProvider data(base::span<MockRead>(), write_failure);
[email protected]bb88e1d32013-05-03 23:11:0711346 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:0911347 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5711348
[email protected]49639fa2011-12-20 23:22:4111349 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5711350
bnc691fda62016-08-12 00:43:1611351 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5711352
tfarina42834112016-09-22 13:38:2011353 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111354 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5711355
11356 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111357 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:5911358
11359 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1611360 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5911361 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:5711362}
11363
zmo9528c9f42015-08-04 22:12:0811364// Check that a connection closed after the start of the headers finishes ok.
bncd16676a2016-07-20 16:23:0111365TEST_F(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:5711366 HttpRequestInfo request;
11367 request.method = "GET";
11368 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:1011369 request.traffic_annotation =
11370 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5711371
11372 MockRead data_reads[] = {
11373 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:0611374 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:5711375 };
11376
Ryan Sleevib8d7ea02018-05-07 20:01:0111377 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711378 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:0911379 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5711380
[email protected]49639fa2011-12-20 23:22:4111381 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5711382
bnc691fda62016-08-12 00:43:1611383 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5711384
tfarina42834112016-09-22 13:38:2011385 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111386 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5711387
11388 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111389 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:0811390
bnc691fda62016-08-12 00:43:1611391 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211392 ASSERT_TRUE(response);
zmo9528c9f42015-08-04 22:12:0811393
wezca1070932016-05-26 20:30:5211394 EXPECT_TRUE(response->headers);
zmo9528c9f42015-08-04 22:12:0811395 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
11396
11397 std::string response_data;
bnc691fda62016-08-12 00:43:1611398 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0111399 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:0811400 EXPECT_EQ("", response_data);
ttuttled9dbc652015-09-29 20:00:5911401
11402 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1611403 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5911404 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:5711405}
11406
11407// Make sure that a dropped connection while draining the body for auth
11408// restart does the right thing.
bncd16676a2016-07-20 16:23:0111409TEST_F(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:5711410 HttpRequestInfo request;
11411 request.method = "GET";
bncce36dca22015-04-21 22:11:2311412 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011413 request.traffic_annotation =
11414 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5711415
11416 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2311417 MockWrite(
11418 "GET / HTTP/1.1\r\n"
11419 "Host: www.example.org\r\n"
11420 "Connection: keep-alive\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:5711421 };
11422
11423 MockRead data_reads1[] = {
11424 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
11425 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
11426 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11427 MockRead("Content-Length: 14\r\n\r\n"),
11428 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:0611429 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:5711430 };
11431
Ryan Sleevib8d7ea02018-05-07 20:01:0111432 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:0711433 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:5711434
bnc691fda62016-08-12 00:43:1611435 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0877e3d2009-10-17 22:29:5711436 // be issuing -- the final header line contains the credentials.
11437 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:2311438 MockWrite(
11439 "GET / HTTP/1.1\r\n"
11440 "Host: www.example.org\r\n"
11441 "Connection: keep-alive\r\n"
11442 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:5711443 };
11444
11445 // Lastly, the server responds with the actual content.
11446 MockRead data_reads2[] = {
11447 MockRead("HTTP/1.1 200 OK\r\n"),
11448 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11449 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0611450 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:5711451 };
11452
Ryan Sleevib8d7ea02018-05-07 20:01:0111453 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:0711454 session_deps_.socket_factory->AddSocketDataProvider(&data2);
danakj1fd259a02016-04-16 03:17:0911455 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5711456
[email protected]49639fa2011-12-20 23:22:4111457 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:5711458
bnc691fda62016-08-12 00:43:1611459 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5011460
tfarina42834112016-09-22 13:38:2011461 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111462 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5711463
11464 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0111465 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:5711466
bnc691fda62016-08-12 00:43:1611467 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211468 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0411469 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:5711470
[email protected]49639fa2011-12-20 23:22:4111471 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:5711472
bnc691fda62016-08-12 00:43:1611473 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:0111474 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5711475
11476 rv = callback2.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 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211480 ASSERT_TRUE(response);
11481 EXPECT_FALSE(response->auth_challenge);
[email protected]0877e3d2009-10-17 22:29:5711482 EXPECT_EQ(100, response->headers->GetContentLength());
11483}
11484
11485// Test HTTPS connections going through a proxy that sends extra data.
bncd16676a2016-07-20 16:23:0111486TEST_F(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
Ramin Halavatica8d5252018-03-12 05:33:4911487 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
11488 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5711489
11490 HttpRequestInfo request;
11491 request.method = "GET";
bncce36dca22015-04-21 22:11:2311492 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011493 request.traffic_annotation =
11494 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5711495
11496 MockRead proxy_reads[] = {
11497 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:0611498 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:5711499 };
11500
Ryan Sleevib8d7ea02018-05-07 20:01:0111501 StaticSocketDataProvider data(proxy_reads, base::span<MockWrite>());
[email protected]8ddf8322012-02-23 18:08:0611502 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:5711503
[email protected]bb88e1d32013-05-03 23:11:0711504 session_deps_.socket_factory->AddSocketDataProvider(&data);
11505 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:5711506
[email protected]49639fa2011-12-20 23:22:4111507 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5711508
[email protected]bb88e1d32013-05-03 23:11:0711509 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:5711510
danakj1fd259a02016-04-16 03:17:0911511 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611512 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5711513
tfarina42834112016-09-22 13:38:2011514 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111515 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5711516
11517 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111518 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]0877e3d2009-10-17 22:29:5711519}
11520
bncd16676a2016-07-20 16:23:0111521TEST_F(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:4611522 HttpRequestInfo request;
11523 request.method = "GET";
bncce36dca22015-04-21 22:11:2311524 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011525 request.traffic_annotation =
11526 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]9492e4a2010-02-24 00:58:4611527
danakj1fd259a02016-04-16 03:17:0911528 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611529 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2711530
[email protected]e22e1362009-11-23 21:31:1211531 MockRead data_reads[] = {
11532 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0611533 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:1211534 };
[email protected]9492e4a2010-02-24 00:58:4611535
Ryan Sleevib8d7ea02018-05-07 20:01:0111536 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711537 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:4611538
[email protected]49639fa2011-12-20 23:22:4111539 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:4611540
tfarina42834112016-09-22 13:38:2011541 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111542 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9492e4a2010-02-24 00:58:4611543
robpercival214763f2016-07-01 23:27:0111544 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]9492e4a2010-02-24 00:58:4611545
bnc691fda62016-08-12 00:43:1611546 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211547 ASSERT_TRUE(response);
[email protected]9492e4a2010-02-24 00:58:4611548
wezca1070932016-05-26 20:30:5211549 EXPECT_TRUE(response->headers);
[email protected]9492e4a2010-02-24 00:58:4611550 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
11551
11552 std::string response_data;
bnc691fda62016-08-12 00:43:1611553 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0111554 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]e22e1362009-11-23 21:31:1211555}
11556
bncd16676a2016-07-20 16:23:0111557TEST_F(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:1511558 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:5211559 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
avibf0746c2015-12-09 19:53:1411560 const uint64_t kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:2111561 UploadFileElementReader::ScopedOverridingContentLengthForTests
11562 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:3311563
danakj1fd259a02016-04-16 03:17:0911564 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:1911565 element_readers.push_back(std::make_unique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:1411566 base::ThreadTaskRunnerHandle::Get().get(), temp_file_path, 0,
ricea2deef682016-09-09 08:04:0711567 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:2211568 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:2711569
11570 HttpRequestInfo request;
11571 request.method = "POST";
bncce36dca22015-04-21 22:11:2311572 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:2711573 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1011574 request.traffic_annotation =
11575 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]329b68b2012-11-14 17:54:2711576
danakj1fd259a02016-04-16 03:17:0911577 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611578 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]95d88ffe2010-02-04 21:25:3311579
11580 MockRead data_reads[] = {
11581 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
11582 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611583 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:3311584 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111585 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711586 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:3311587
[email protected]49639fa2011-12-20 23:22:4111588 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:3311589
tfarina42834112016-09-22 13:38:2011590 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111591 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]95d88ffe2010-02-04 21:25:3311592
11593 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111594 EXPECT_THAT(rv, IsError(ERR_UPLOAD_FILE_CHANGED));
[email protected]95d88ffe2010-02-04 21:25:3311595
bnc691fda62016-08-12 00:43:1611596 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211597 ASSERT_TRUE(response);
[email protected]95d88ffe2010-02-04 21:25:3311598
maksim.sisove869bf52016-06-23 17:11:5211599 EXPECT_FALSE(response->headers);
[email protected]95d88ffe2010-02-04 21:25:3311600
[email protected]dd3aa792013-07-16 19:10:2311601 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:3311602}
11603
bncd16676a2016-07-20 16:23:0111604TEST_F(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:1511605 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:5211606 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:3611607 std::string temp_file_content("Unreadable file.");
lazyboy8df84fc2017-04-12 02:12:4811608 ASSERT_EQ(static_cast<int>(temp_file_content.length()),
11609 base::WriteFile(temp_file, temp_file_content.c_str(),
11610 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:1111611 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:3611612
danakj1fd259a02016-04-16 03:17:0911613 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:1911614 element_readers.push_back(std::make_unique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:1411615 base::ThreadTaskRunnerHandle::Get().get(), temp_file, 0,
ricea2deef682016-09-09 08:04:0711616 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:2211617 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:2711618
11619 HttpRequestInfo request;
11620 request.method = "POST";
bncce36dca22015-04-21 22:11:2311621 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:2711622 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1011623 request.traffic_annotation =
11624 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]329b68b2012-11-14 17:54:2711625
[email protected]999dd8c2013-11-12 06:45:5411626 // If we try to upload an unreadable file, the transaction should fail.
danakj1fd259a02016-04-16 03:17:0911627 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611628 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]6624b4622010-03-29 19:58:3611629
Ryan Sleevib8d7ea02018-05-07 20:01:0111630 StaticSocketDataProvider data;
[email protected]bb88e1d32013-05-03 23:11:0711631 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:3611632
[email protected]49639fa2011-12-20 23:22:4111633 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:3611634
tfarina42834112016-09-22 13:38:2011635 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111636 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6624b4622010-03-29 19:58:3611637
11638 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111639 EXPECT_THAT(rv, IsError(ERR_ACCESS_DENIED));
[email protected]6624b4622010-03-29 19:58:3611640
[email protected]dd3aa792013-07-16 19:10:2311641 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:3611642}
11643
bncd16676a2016-07-20 16:23:0111644TEST_F(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
[email protected]02cad5d2013-10-02 08:14:0311645 class FakeUploadElementReader : public UploadElementReader {
11646 public:
Chris Watkins7a41d3552017-12-01 02:13:2711647 FakeUploadElementReader() = default;
11648 ~FakeUploadElementReader() override = default;
[email protected]02cad5d2013-10-02 08:14:0311649
Matt Menkecc1d3a902018-02-05 18:27:3311650 CompletionOnceCallback TakeCallback() { return std::move(callback_); }
[email protected]02cad5d2013-10-02 08:14:0311651
11652 // UploadElementReader overrides:
Matt Menkecc1d3a902018-02-05 18:27:3311653 int Init(CompletionOnceCallback callback) override {
11654 callback_ = std::move(callback);
[email protected]02cad5d2013-10-02 08:14:0311655 return ERR_IO_PENDING;
11656 }
avibf0746c2015-12-09 19:53:1411657 uint64_t GetContentLength() const override { return 0; }
11658 uint64_t BytesRemaining() const override { return 0; }
dchengb03027d2014-10-21 12:00:2011659 int Read(IOBuffer* buf,
11660 int buf_length,
Matt Menkecc1d3a902018-02-05 18:27:3311661 CompletionOnceCallback callback) override {
[email protected]02cad5d2013-10-02 08:14:0311662 return ERR_FAILED;
11663 }
11664
11665 private:
Matt Menkecc1d3a902018-02-05 18:27:3311666 CompletionOnceCallback callback_;
[email protected]02cad5d2013-10-02 08:14:0311667 };
11668
11669 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
danakj1fd259a02016-04-16 03:17:0911670 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
11671 element_readers.push_back(base::WrapUnique(fake_reader));
olli.raula6df48b2a2015-11-26 07:40:2211672 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02cad5d2013-10-02 08:14:0311673
11674 HttpRequestInfo request;
11675 request.method = "POST";
bncce36dca22015-04-21 22:11:2311676 request.url = GURL("http://www.example.org/upload");
[email protected]02cad5d2013-10-02 08:14:0311677 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1011678 request.traffic_annotation =
11679 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02cad5d2013-10-02 08:14:0311680
danakj1fd259a02016-04-16 03:17:0911681 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5811682 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1911683 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]02cad5d2013-10-02 08:14:0311684
11685 StaticSocketDataProvider data;
11686 session_deps_.socket_factory->AddSocketDataProvider(&data);
11687
11688 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2011689 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111690 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
fdoray92e35a72016-06-10 15:54:5511691 base::RunLoop().RunUntilIdle();
[email protected]02cad5d2013-10-02 08:14:0311692
11693 // Transaction is pending on request body initialization.
Matt Menkecc1d3a902018-02-05 18:27:3311694 CompletionOnceCallback init_callback = fake_reader->TakeCallback();
11695 ASSERT_FALSE(init_callback.is_null());
[email protected]02cad5d2013-10-02 08:14:0311696
11697 // Return Init()'s result after the transaction gets destroyed.
11698 trans.reset();
Matt Menkecc1d3a902018-02-05 18:27:3311699 std::move(init_callback).Run(OK); // Should not crash.
[email protected]02cad5d2013-10-02 08:14:0311700}
11701
[email protected]aeefc9e82010-02-19 16:18:2711702// Tests that changes to Auth realms are treated like auth rejections.
bncd16676a2016-07-20 16:23:0111703TEST_F(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:2711704 HttpRequestInfo request;
11705 request.method = "GET";
bncce36dca22015-04-21 22:11:2311706 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011707 request.traffic_annotation =
11708 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]aeefc9e82010-02-19 16:18:2711709
11710 // First transaction will request a resource and receive a Basic challenge
11711 // with realm="first_realm".
11712 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2311713 MockWrite(
11714 "GET / HTTP/1.1\r\n"
11715 "Host: www.example.org\r\n"
11716 "Connection: keep-alive\r\n"
11717 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2711718 };
11719 MockRead data_reads1[] = {
11720 MockRead("HTTP/1.1 401 Unauthorized\r\n"
11721 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
11722 "\r\n"),
11723 };
11724
bnc691fda62016-08-12 00:43:1611725 // After calling trans.RestartWithAuth(), provide an Authentication header
[email protected]aeefc9e82010-02-19 16:18:2711726 // for first_realm. The server will reject and provide a challenge with
11727 // second_realm.
11728 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:2311729 MockWrite(
11730 "GET / HTTP/1.1\r\n"
11731 "Host: www.example.org\r\n"
11732 "Connection: keep-alive\r\n"
11733 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
11734 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2711735 };
11736 MockRead data_reads2[] = {
11737 MockRead("HTTP/1.1 401 Unauthorized\r\n"
11738 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
11739 "\r\n"),
11740 };
11741
11742 // This again fails, and goes back to first_realm. Make sure that the
11743 // entry is removed from cache.
11744 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:2311745 MockWrite(
11746 "GET / HTTP/1.1\r\n"
11747 "Host: www.example.org\r\n"
11748 "Connection: keep-alive\r\n"
11749 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
11750 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2711751 };
11752 MockRead data_reads3[] = {
11753 MockRead("HTTP/1.1 401 Unauthorized\r\n"
11754 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
11755 "\r\n"),
11756 };
11757
11758 // Try one last time (with the correct password) and get the resource.
11759 MockWrite data_writes4[] = {
bncce36dca22015-04-21 22:11:2311760 MockWrite(
11761 "GET / HTTP/1.1\r\n"
11762 "Host: www.example.org\r\n"
11763 "Connection: keep-alive\r\n"
11764 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
11765 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2711766 };
11767 MockRead data_reads4[] = {
11768 MockRead("HTTP/1.1 200 OK\r\n"
11769 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:5011770 "Content-Length: 5\r\n"
11771 "\r\n"
11772 "hello"),
[email protected]aeefc9e82010-02-19 16:18:2711773 };
11774
Ryan Sleevib8d7ea02018-05-07 20:01:0111775 StaticSocketDataProvider data1(data_reads1, data_writes1);
11776 StaticSocketDataProvider data2(data_reads2, data_writes2);
11777 StaticSocketDataProvider data3(data_reads3, data_writes3);
11778 StaticSocketDataProvider data4(data_reads4, data_writes4);
[email protected]bb88e1d32013-05-03 23:11:0711779 session_deps_.socket_factory->AddSocketDataProvider(&data1);
11780 session_deps_.socket_factory->AddSocketDataProvider(&data2);
11781 session_deps_.socket_factory->AddSocketDataProvider(&data3);
11782 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:2711783
[email protected]49639fa2011-12-20 23:22:4111784 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:2711785
danakj1fd259a02016-04-16 03:17:0911786 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611787 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5011788
[email protected]aeefc9e82010-02-19 16:18:2711789 // Issue the first request with Authorize headers. There should be a
11790 // password prompt for first_realm waiting to be filled in after the
11791 // transaction completes.
tfarina42834112016-09-22 13:38:2011792 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111793 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2711794 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0111795 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1611796 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211797 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0411798 const AuthChallengeInfo* challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5211799 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0411800 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4311801 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0411802 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1911803 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2711804
11805 // Issue the second request with an incorrect password. There should be a
11806 // password prompt for second_realm waiting to be filled in after the
11807 // transaction completes.
[email protected]49639fa2011-12-20 23:22:4111808 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:1611809 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBaz),
11810 callback2.callback());
robpercival214763f2016-07-01 23:27:0111811 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2711812 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0111813 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1611814 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211815 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0411816 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5211817 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0411818 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4311819 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0411820 EXPECT_EQ("second_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1911821 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2711822
11823 // Issue the third request with another incorrect password. There should be
11824 // a password prompt for first_realm waiting to be filled in. If the password
11825 // prompt is not present, it indicates that the HttpAuthCacheEntry for
11826 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:4111827 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:1611828 rv = trans.RestartWithAuth(AuthCredentials(kSecond, kFou),
11829 callback3.callback());
robpercival214763f2016-07-01 23:27:0111830 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2711831 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:0111832 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1611833 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211834 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0411835 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5211836 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0411837 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4311838 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0411839 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1911840 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2711841
11842 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:4111843 TestCompletionCallback callback4;
bnc691fda62016-08-12 00:43:1611844 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBar),
11845 callback4.callback());
robpercival214763f2016-07-01 23:27:0111846 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2711847 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:0111848 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1611849 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211850 ASSERT_TRUE(response);
11851 EXPECT_FALSE(response->auth_challenge);
[email protected]aeefc9e82010-02-19 16:18:2711852}
11853
Bence Béky230ac612017-08-30 19:17:0811854// Regression test for https://crbug.com/754395.
11855TEST_F(HttpNetworkTransactionTest, IgnoreAltSvcWithInvalidCert) {
11856 MockRead data_reads[] = {
11857 MockRead("HTTP/1.1 200 OK\r\n"),
11858 MockRead(kAlternativeServiceHttpHeader),
11859 MockRead("\r\n"),
11860 MockRead("hello world"),
11861 MockRead(SYNCHRONOUS, OK),
11862 };
11863
11864 HttpRequestInfo request;
11865 request.method = "GET";
11866 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011867 request.traffic_annotation =
11868 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Béky230ac612017-08-30 19:17:0811869
Ryan Sleevib8d7ea02018-05-07 20:01:0111870 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
Bence Béky230ac612017-08-30 19:17:0811871 session_deps_.socket_factory->AddSocketDataProvider(&data);
11872
11873 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911874 ssl.ssl_info.cert =
11875 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11876 ASSERT_TRUE(ssl.ssl_info.cert);
11877 ssl.ssl_info.cert_status = CERT_STATUS_COMMON_NAME_INVALID;
Bence Béky230ac612017-08-30 19:17:0811878 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11879
11880 TestCompletionCallback callback;
11881
11882 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11883 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11884
11885 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
11886 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11887
11888 url::SchemeHostPort test_server(request.url);
11889 HttpServerProperties* http_server_properties =
11890 session->http_server_properties();
11891 EXPECT_TRUE(
11892 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
11893
11894 EXPECT_THAT(callback.WaitForResult(), IsOk());
11895
11896 const HttpResponseInfo* response = trans.GetResponseInfo();
11897 ASSERT_TRUE(response);
11898 ASSERT_TRUE(response->headers);
11899 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11900 EXPECT_FALSE(response->was_fetched_via_spdy);
11901 EXPECT_FALSE(response->was_alpn_negotiated);
11902
11903 std::string response_data;
11904 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
11905 EXPECT_EQ("hello world", response_data);
11906
11907 EXPECT_TRUE(
11908 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
11909}
11910
bncd16676a2016-07-20 16:23:0111911TEST_F(HttpNetworkTransactionTest, HonorAlternativeServiceHeader) {
bncc958faa2015-07-31 18:14:5211912 MockRead data_reads[] = {
11913 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311914 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211915 MockRead("\r\n"),
11916 MockRead("hello world"),
11917 MockRead(SYNCHRONOUS, OK),
11918 };
11919
11920 HttpRequestInfo request;
11921 request.method = "GET";
bncb26024382016-06-29 02:39:4511922 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011923 request.traffic_annotation =
11924 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bncc958faa2015-07-31 18:14:5211925
Ryan Sleevib8d7ea02018-05-07 20:01:0111926 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:5211927 session_deps_.socket_factory->AddSocketDataProvider(&data);
11928
bncb26024382016-06-29 02:39:4511929 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911930 ssl.ssl_info.cert =
11931 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11932 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4511933 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11934
bncc958faa2015-07-31 18:14:5211935 TestCompletionCallback callback;
11936
danakj1fd259a02016-04-16 03:17:0911937 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611938 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5211939
tfarina42834112016-09-22 13:38:2011940 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111941 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5211942
bncb26024382016-06-29 02:39:4511943 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4011944 HttpServerProperties* http_server_properties =
11945 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3411946 EXPECT_TRUE(
11947 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5211948
robpercival214763f2016-07-01 23:27:0111949 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5211950
bnc691fda62016-08-12 00:43:1611951 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211952 ASSERT_TRUE(response);
11953 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5211954 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11955 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211956 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5211957
11958 std::string response_data;
bnc691fda62016-08-12 00:43:1611959 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5211960 EXPECT_EQ("hello world", response_data);
11961
zhongyic4de03032017-05-19 04:07:3411962 AlternativeServiceInfoVector alternative_service_info_vector =
11963 http_server_properties->GetAlternativeServiceInfos(test_server);
11964 ASSERT_EQ(1u, alternative_service_info_vector.size());
11965 AlternativeService alternative_service(kProtoHTTP2, "mail.example.org", 443);
11966 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5411967 alternative_service_info_vector[0].alternative_service());
bncc958faa2015-07-31 18:14:5211968}
11969
bnce3dd56f2016-06-01 10:37:1111970// Regression test for https://crbug.com/615497.
bncd16676a2016-07-20 16:23:0111971TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1111972 DoNotParseAlternativeServiceHeaderOnInsecureRequest) {
bnce3dd56f2016-06-01 10:37:1111973 MockRead data_reads[] = {
11974 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311975 MockRead(kAlternativeServiceHttpHeader),
bnce3dd56f2016-06-01 10:37:1111976 MockRead("\r\n"),
11977 MockRead("hello world"),
11978 MockRead(SYNCHRONOUS, OK),
11979 };
11980
11981 HttpRequestInfo request;
11982 request.method = "GET";
11983 request.url = GURL("http://www.example.org/");
11984 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1011985 request.traffic_annotation =
11986 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnce3dd56f2016-06-01 10:37:1111987
Ryan Sleevib8d7ea02018-05-07 20:01:0111988 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
bnce3dd56f2016-06-01 10:37:1111989 session_deps_.socket_factory->AddSocketDataProvider(&data);
11990
11991 TestCompletionCallback callback;
11992
11993 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611994 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1111995
11996 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4011997 HttpServerProperties* http_server_properties =
11998 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3411999 EXPECT_TRUE(
12000 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1112001
tfarina42834112016-09-22 13:38:2012002 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112003 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12004 EXPECT_THAT(callback.WaitForResult(), IsOk());
bnce3dd56f2016-06-01 10:37:1112005
bnc691fda62016-08-12 00:43:1612006 const HttpResponseInfo* response = trans.GetResponseInfo();
bnce3dd56f2016-06-01 10:37:1112007 ASSERT_TRUE(response);
12008 ASSERT_TRUE(response->headers);
12009 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12010 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212011 EXPECT_FALSE(response->was_alpn_negotiated);
bnce3dd56f2016-06-01 10:37:1112012
12013 std::string response_data;
bnc691fda62016-08-12 00:43:1612014 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnce3dd56f2016-06-01 10:37:1112015 EXPECT_EQ("hello world", response_data);
12016
zhongyic4de03032017-05-19 04:07:3412017 EXPECT_TRUE(
12018 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1112019}
12020
bnca86731e2017-04-17 12:31:2812021// HTTP/2 Alternative Services should be disabled by default.
bnc8bef8da22016-05-30 01:28:2512022// TODO(bnc): Remove when https://crbug.com/615413 is fixed.
bncd16676a2016-07-20 16:23:0112023TEST_F(HttpNetworkTransactionTest,
bnc8bef8da22016-05-30 01:28:2512024 DisableHTTP2AlternativeServicesWithDifferentHost) {
bnca86731e2017-04-17 12:31:2812025 session_deps_.enable_http2_alternative_service = false;
bncb26024382016-06-29 02:39:4512026
bnc8bef8da22016-05-30 01:28:2512027 HttpRequestInfo request;
12028 request.method = "GET";
bncb26024382016-06-29 02:39:4512029 request.url = GURL("https://www.example.org/");
bnc8bef8da22016-05-30 01:28:2512030 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1012031 request.traffic_annotation =
12032 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8bef8da22016-05-30 01:28:2512033
12034 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
12035 StaticSocketDataProvider first_data;
12036 first_data.set_connect_data(mock_connect);
12037 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4512038 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612039 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512040 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
bnc8bef8da22016-05-30 01:28:2512041
12042 MockRead data_reads[] = {
12043 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
12044 MockRead(ASYNC, OK),
12045 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112046 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
bnc8bef8da22016-05-30 01:28:2512047 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
12048
12049 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12050
bnc525e175a2016-06-20 12:36:4012051 HttpServerProperties* http_server_properties =
bnc8bef8da22016-05-30 01:28:2512052 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2112053 AlternativeService alternative_service(kProtoHTTP2, "different.example.org",
12054 444);
bnc8bef8da22016-05-30 01:28:2512055 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112056 http_server_properties->SetHttp2AlternativeService(
bnc8bef8da22016-05-30 01:28:2512057 url::SchemeHostPort(request.url), alternative_service, expiration);
12058
bnc691fda62016-08-12 00:43:1612059 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc8bef8da22016-05-30 01:28:2512060 TestCompletionCallback callback;
12061
tfarina42834112016-09-22 13:38:2012062 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc8bef8da22016-05-30 01:28:2512063 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0112064 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc8bef8da22016-05-30 01:28:2512065}
12066
bnce3dd56f2016-06-01 10:37:1112067// Regression test for https://crbug.com/615497:
12068// Alternative Services should be disabled for http origin.
bncd16676a2016-07-20 16:23:0112069TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1112070 DisableAlternativeServicesForInsecureOrigin) {
bnce3dd56f2016-06-01 10:37:1112071 HttpRequestInfo request;
12072 request.method = "GET";
12073 request.url = GURL("http://www.example.org/");
12074 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1012075 request.traffic_annotation =
12076 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnce3dd56f2016-06-01 10:37:1112077
12078 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
12079 StaticSocketDataProvider first_data;
12080 first_data.set_connect_data(mock_connect);
12081 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
12082
12083 MockRead data_reads[] = {
12084 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
12085 MockRead(ASYNC, OK),
12086 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112087 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
bnce3dd56f2016-06-01 10:37:1112088 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
12089
12090 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12091
bnc525e175a2016-06-20 12:36:4012092 HttpServerProperties* http_server_properties =
bnce3dd56f2016-06-01 10:37:1112093 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2112094 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnce3dd56f2016-06-01 10:37:1112095 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112096 http_server_properties->SetHttp2AlternativeService(
bnce3dd56f2016-06-01 10:37:1112097 url::SchemeHostPort(request.url), alternative_service, expiration);
12098
bnc691fda62016-08-12 00:43:1612099 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1112100 TestCompletionCallback callback;
12101
tfarina42834112016-09-22 13:38:2012102 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnce3dd56f2016-06-01 10:37:1112103 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0112104 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnce3dd56f2016-06-01 10:37:1112105}
12106
bncd16676a2016-07-20 16:23:0112107TEST_F(HttpNetworkTransactionTest, ClearAlternativeServices) {
bnc4f575852015-10-14 18:35:0812108 // Set an alternative service for origin.
danakj1fd259a02016-04-16 03:17:0912109 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4012110 HttpServerProperties* http_server_properties =
12111 session->http_server_properties();
bncb26024382016-06-29 02:39:4512112 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc3472afd2016-11-17 15:27:2112113 AlternativeService alternative_service(kProtoQUIC, "", 80);
bnc4f575852015-10-14 18:35:0812114 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112115 http_server_properties->SetQuicAlternativeService(
12116 test_server, alternative_service, expiration,
12117 session->params().quic_supported_versions);
zhongyic4de03032017-05-19 04:07:3412118 EXPECT_EQ(
12119 1u,
12120 http_server_properties->GetAlternativeServiceInfos(test_server).size());
bnc4f575852015-10-14 18:35:0812121
12122 // Send a clear header.
12123 MockRead data_reads[] = {
12124 MockRead("HTTP/1.1 200 OK\r\n"),
12125 MockRead("Alt-Svc: clear\r\n"),
12126 MockRead("\r\n"),
12127 MockRead("hello world"),
12128 MockRead(SYNCHRONOUS, OK),
12129 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112130 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
bnc4f575852015-10-14 18:35:0812131 session_deps_.socket_factory->AddSocketDataProvider(&data);
12132
bncb26024382016-06-29 02:39:4512133 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4912134 ssl.ssl_info.cert =
12135 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
12136 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4512137 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12138
bnc4f575852015-10-14 18:35:0812139 HttpRequestInfo request;
12140 request.method = "GET";
bncb26024382016-06-29 02:39:4512141 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1012142 request.traffic_annotation =
12143 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc4f575852015-10-14 18:35:0812144
12145 TestCompletionCallback callback;
12146
bnc691fda62016-08-12 00:43:1612147 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc4f575852015-10-14 18:35:0812148
tfarina42834112016-09-22 13:38:2012149 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112150 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc4f575852015-10-14 18:35:0812151
bnc691fda62016-08-12 00:43:1612152 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212153 ASSERT_TRUE(response);
12154 ASSERT_TRUE(response->headers);
bnc4f575852015-10-14 18:35:0812155 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12156 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212157 EXPECT_FALSE(response->was_alpn_negotiated);
bnc4f575852015-10-14 18:35:0812158
12159 std::string response_data;
bnc691fda62016-08-12 00:43:1612160 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc4f575852015-10-14 18:35:0812161 EXPECT_EQ("hello world", response_data);
12162
zhongyic4de03032017-05-19 04:07:3412163 EXPECT_TRUE(
12164 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnc4f575852015-10-14 18:35:0812165}
12166
bncd16676a2016-07-20 16:23:0112167TEST_F(HttpNetworkTransactionTest, HonorMultipleAlternativeServiceHeaders) {
bncc958faa2015-07-31 18:14:5212168 MockRead data_reads[] = {
12169 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312170 MockRead("Alt-Svc: h2=\"www.example.com:443\","),
12171 MockRead("h2=\":1234\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:5212172 MockRead("hello world"),
12173 MockRead(SYNCHRONOUS, OK),
12174 };
12175
12176 HttpRequestInfo request;
12177 request.method = "GET";
bncb26024382016-06-29 02:39:4512178 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1012179 request.traffic_annotation =
12180 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bncc958faa2015-07-31 18:14:5212181
Ryan Sleevib8d7ea02018-05-07 20:01:0112182 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:5212183 session_deps_.socket_factory->AddSocketDataProvider(&data);
12184
bncb26024382016-06-29 02:39:4512185 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4912186 ssl.ssl_info.cert =
12187 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
12188 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4512189 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12190
bncc958faa2015-07-31 18:14:5212191 TestCompletionCallback callback;
12192
danakj1fd259a02016-04-16 03:17:0912193 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1612194 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5212195
tfarina42834112016-09-22 13:38:2012196 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112197 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5212198
bncb26024382016-06-29 02:39:4512199 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc525e175a2016-06-20 12:36:4012200 HttpServerProperties* http_server_properties =
12201 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3412202 EXPECT_TRUE(
12203 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5212204
robpercival214763f2016-07-01 23:27:0112205 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5212206
bnc691fda62016-08-12 00:43:1612207 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212208 ASSERT_TRUE(response);
12209 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5212210 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12211 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212212 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5212213
12214 std::string response_data;
bnc691fda62016-08-12 00:43:1612215 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5212216 EXPECT_EQ("hello world", response_data);
12217
zhongyic4de03032017-05-19 04:07:3412218 AlternativeServiceInfoVector alternative_service_info_vector =
12219 http_server_properties->GetAlternativeServiceInfos(test_server);
12220 ASSERT_EQ(2u, alternative_service_info_vector.size());
12221
12222 AlternativeService alternative_service(kProtoHTTP2, "www.example.com", 443);
12223 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5412224 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3412225 AlternativeService alternative_service_2(kProtoHTTP2, "www.example.org",
12226 1234);
12227 EXPECT_EQ(alternative_service_2,
zhongyi422ce352017-06-09 23:28:5412228 alternative_service_info_vector[1].alternative_service());
bncc958faa2015-07-31 18:14:5212229}
12230
bncd16676a2016-07-20 16:23:0112231TEST_F(HttpNetworkTransactionTest, IdentifyQuicBroken) {
zhongyi3d4a55e72016-04-22 20:36:4612232 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0212233 HostPortPair alternative("alternative.example.org", 443);
12234 std::string origin_url = "https://origin.example.org:443";
12235 std::string alternative_url = "https://alternative.example.org:443";
12236
12237 // Negotiate HTTP/1.1 with alternative.example.org.
12238 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612239 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0212240 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12241
12242 // HTTP/1.1 data for request.
12243 MockWrite http_writes[] = {
12244 MockWrite("GET / HTTP/1.1\r\n"
12245 "Host: alternative.example.org\r\n"
12246 "Connection: keep-alive\r\n\r\n"),
12247 };
12248
12249 MockRead http_reads[] = {
12250 MockRead("HTTP/1.1 200 OK\r\n"
12251 "Content-Type: text/html; charset=iso-8859-1\r\n"
12252 "Content-Length: 40\r\n\r\n"
12253 "first HTTP/1.1 response from alternative"),
12254 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112255 StaticSocketDataProvider http_data(http_reads, http_writes);
zhongyi48704c182015-12-07 07:52:0212256 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12257
12258 StaticSocketDataProvider data_refused;
12259 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
12260 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
12261
zhongyi3d4a55e72016-04-22 20:36:4612262 // Set up a QUIC alternative service for server.
danakj1fd259a02016-04-16 03:17:0912263 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4012264 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0212265 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2112266 AlternativeService alternative_service(kProtoQUIC, alternative);
zhongyi48704c182015-12-07 07:52:0212267 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112268 http_server_properties->SetQuicAlternativeService(
12269 server, alternative_service, expiration,
12270 HttpNetworkSession::Params().quic_supported_versions);
zhongyi48704c182015-12-07 07:52:0212271 // Mark the QUIC alternative service as broken.
12272 http_server_properties->MarkAlternativeServiceBroken(alternative_service);
12273
zhongyi48704c182015-12-07 07:52:0212274 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4612275 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0212276 request.method = "GET";
12277 request.url = GURL(origin_url);
Ramin Halavatib5e433e2018-02-07 07:41:1012278 request.traffic_annotation =
12279 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
12280
zhongyi48704c182015-12-07 07:52:0212281 TestCompletionCallback callback;
12282 NetErrorDetails details;
12283 EXPECT_FALSE(details.quic_broken);
12284
tfarina42834112016-09-22 13:38:2012285 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1612286 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0212287 EXPECT_TRUE(details.quic_broken);
12288}
12289
bncd16676a2016-07-20 16:23:0112290TEST_F(HttpNetworkTransactionTest, IdentifyQuicNotBroken) {
zhongyi3d4a55e72016-04-22 20:36:4612291 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0212292 HostPortPair alternative1("alternative1.example.org", 443);
12293 HostPortPair alternative2("alternative2.example.org", 443);
12294 std::string origin_url = "https://origin.example.org:443";
12295 std::string alternative_url1 = "https://alternative1.example.org:443";
12296 std::string alternative_url2 = "https://alternative2.example.org:443";
12297
12298 // Negotiate HTTP/1.1 with alternative1.example.org.
12299 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612300 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0212301 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12302
12303 // HTTP/1.1 data for request.
12304 MockWrite http_writes[] = {
12305 MockWrite("GET / HTTP/1.1\r\n"
12306 "Host: alternative1.example.org\r\n"
12307 "Connection: keep-alive\r\n\r\n"),
12308 };
12309
12310 MockRead http_reads[] = {
12311 MockRead("HTTP/1.1 200 OK\r\n"
12312 "Content-Type: text/html; charset=iso-8859-1\r\n"
12313 "Content-Length: 40\r\n\r\n"
12314 "first HTTP/1.1 response from alternative1"),
12315 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112316 StaticSocketDataProvider http_data(http_reads, http_writes);
zhongyi48704c182015-12-07 07:52:0212317 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12318
12319 StaticSocketDataProvider data_refused;
12320 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
12321 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
12322
danakj1fd259a02016-04-16 03:17:0912323 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4012324 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0212325 session->http_server_properties();
12326
zhongyi3d4a55e72016-04-22 20:36:4612327 // Set up two QUIC alternative services for server.
zhongyi48704c182015-12-07 07:52:0212328 AlternativeServiceInfoVector alternative_service_info_vector;
12329 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
12330
bnc3472afd2016-11-17 15:27:2112331 AlternativeService alternative_service1(kProtoQUIC, alternative1);
zhongyie537a002017-06-27 16:48:2112332 alternative_service_info_vector.push_back(
12333 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
12334 alternative_service1, expiration,
12335 session->params().quic_supported_versions));
bnc3472afd2016-11-17 15:27:2112336 AlternativeService alternative_service2(kProtoQUIC, alternative2);
zhongyie537a002017-06-27 16:48:2112337 alternative_service_info_vector.push_back(
12338 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
12339 alternative_service2, expiration,
12340 session->params().quic_supported_versions));
zhongyi48704c182015-12-07 07:52:0212341
12342 http_server_properties->SetAlternativeServices(
zhongyi3d4a55e72016-04-22 20:36:4612343 server, alternative_service_info_vector);
zhongyi48704c182015-12-07 07:52:0212344
12345 // Mark one of the QUIC alternative service as broken.
12346 http_server_properties->MarkAlternativeServiceBroken(alternative_service1);
zhongyic4de03032017-05-19 04:07:3412347 EXPECT_EQ(2u,
12348 http_server_properties->GetAlternativeServiceInfos(server).size());
zhongyi48704c182015-12-07 07:52:0212349
zhongyi48704c182015-12-07 07:52:0212350 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4612351 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0212352 request.method = "GET";
12353 request.url = GURL(origin_url);
Ramin Halavatib5e433e2018-02-07 07:41:1012354 request.traffic_annotation =
12355 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
12356
zhongyi48704c182015-12-07 07:52:0212357 TestCompletionCallback callback;
12358 NetErrorDetails details;
12359 EXPECT_FALSE(details.quic_broken);
12360
tfarina42834112016-09-22 13:38:2012361 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1612362 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0212363 EXPECT_FALSE(details.quic_broken);
12364}
12365
bncd16676a2016-07-20 16:23:0112366TEST_F(HttpNetworkTransactionTest, MarkBrokenAlternateProtocolAndFallback) {
[email protected]564b4912010-03-09 16:30:4212367 HttpRequestInfo request;
12368 request.method = "GET";
bncb26024382016-06-29 02:39:4512369 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1012370 request.traffic_annotation =
12371 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]564b4912010-03-09 16:30:4212372
[email protected]d973e99a2012-02-17 21:02:3612373 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:4212374 StaticSocketDataProvider first_data;
12375 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712376 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4512377 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612378 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512379 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]564b4912010-03-09 16:30:4212380
12381 MockRead data_reads[] = {
12382 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12383 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0612384 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:4212385 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112386 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712387 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:4212388
danakj1fd259a02016-04-16 03:17:0912389 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:4212390
bnc525e175a2016-06-20 12:36:4012391 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5312392 session->http_server_properties();
zhongyi3d4a55e72016-04-22 20:36:4612393 const url::SchemeHostPort server(request.url);
[email protected]3912662a32011-10-04 00:51:1112394 // Port must be < 1024, or the header will be ignored (since initial port was
12395 // port 80 (another restricted port).
zhongyie537a002017-06-27 16:48:2112396 // Port is ignored by MockConnect anyway.
12397 const AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12398 666);
bnc7dc7e1b42015-07-28 14:43:1212399 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112400 http_server_properties->SetHttp2AlternativeService(
12401 server, alternative_service, expiration);
[email protected]564b4912010-03-09 16:30:4212402
bnc691fda62016-08-12 00:43:1612403 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112404 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:4212405
tfarina42834112016-09-22 13:38:2012406 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112407 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12408 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]564b4912010-03-09 16:30:4212409
bnc691fda62016-08-12 00:43:1612410 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212411 ASSERT_TRUE(response);
12412 ASSERT_TRUE(response->headers);
[email protected]564b4912010-03-09 16:30:4212413 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12414
12415 std::string response_data;
bnc691fda62016-08-12 00:43:1612416 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]564b4912010-03-09 16:30:4212417 EXPECT_EQ("hello world", response_data);
12418
zhongyic4de03032017-05-19 04:07:3412419 const AlternativeServiceInfoVector alternative_service_info_vector =
12420 http_server_properties->GetAlternativeServiceInfos(server);
12421 ASSERT_EQ(1u, alternative_service_info_vector.size());
12422 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5412423 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3412424 EXPECT_TRUE(
12425 http_server_properties->IsAlternativeServiceBroken(alternative_service));
[email protected]564b4912010-03-09 16:30:4212426}
12427
bnc55ff9da2015-08-19 18:42:3512428// Ensure that we are not allowed to redirect traffic via an alternate protocol
12429// to an unrestricted (port >= 1024) when the original traffic was on a
12430// restricted port (port < 1024). Ensure that we can redirect in all other
12431// cases.
bncd16676a2016-07-20 16:23:0112432TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:1112433 HttpRequestInfo restricted_port_request;
12434 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4512435 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1112436 restricted_port_request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1012437 restricted_port_request.traffic_annotation =
12438 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1112439
[email protected]d973e99a2012-02-17 21:02:3612440 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1112441 StaticSocketDataProvider first_data;
12442 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712443 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1112444
12445 MockRead data_reads[] = {
12446 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12447 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0612448 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1112449 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112450 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712451 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4512452 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612453 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512454 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1112455
danakj1fd259a02016-04-16 03:17:0912456 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1112457
bnc525e175a2016-06-20 12:36:4012458 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5312459 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1112460 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2112461 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12462 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1212463 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112464 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4612465 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5012466 expiration);
[email protected]3912662a32011-10-04 00:51:1112467
bnc691fda62016-08-12 00:43:1612468 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112469 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1112470
tfarina42834112016-09-22 13:38:2012471 int rv = trans.Start(&restricted_port_request, callback.callback(),
12472 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112473 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1112474 // Invalid change to unrestricted port should fail.
robpercival214763f2016-07-01 23:27:0112475 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_REFUSED));
[email protected]c54c6962013-02-01 04:53:1912476}
[email protected]3912662a32011-10-04 00:51:1112477
bnc55ff9da2015-08-19 18:42:3512478// Ensure that we are allowed to redirect traffic via an alternate protocol to
12479// an unrestricted (port >= 1024) when the original traffic was on a restricted
12480// port (port < 1024) if we set |enable_user_alternate_protocol_ports|.
bncd16676a2016-07-20 16:23:0112481TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedPermitted) {
[email protected]bb88e1d32013-05-03 23:11:0712482 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:1912483
12484 HttpRequestInfo restricted_port_request;
12485 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4512486 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]c54c6962013-02-01 04:53:1912487 restricted_port_request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1012488 restricted_port_request.traffic_annotation =
12489 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]c54c6962013-02-01 04:53:1912490
12491 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
12492 StaticSocketDataProvider first_data;
12493 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712494 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:1912495
12496 MockRead data_reads[] = {
12497 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12498 MockRead("hello world"),
12499 MockRead(ASYNC, OK),
12500 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112501 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712502 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4512503 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612504 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512505 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]c54c6962013-02-01 04:53:1912506
danakj1fd259a02016-04-16 03:17:0912507 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:1912508
bnc525e175a2016-06-20 12:36:4012509 HttpServerProperties* http_server_properties =
[email protected]c54c6962013-02-01 04:53:1912510 session->http_server_properties();
12511 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2112512 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12513 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1212514 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112515 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4612516 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5012517 expiration);
[email protected]c54c6962013-02-01 04:53:1912518
bnc691fda62016-08-12 00:43:1612519 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]c54c6962013-02-01 04:53:1912520 TestCompletionCallback callback;
12521
tfarina42834112016-09-22 13:38:2012522 EXPECT_EQ(ERR_IO_PENDING,
12523 trans.Start(&restricted_port_request, callback.callback(),
12524 NetLogWithSource()));
[email protected]c54c6962013-02-01 04:53:1912525 // Change to unrestricted port should succeed.
robpercival214763f2016-07-01 23:27:0112526 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1112527}
12528
bnc55ff9da2015-08-19 18:42:3512529// Ensure that we are not allowed to redirect traffic via an alternate protocol
12530// to an unrestricted (port >= 1024) when the original traffic was on a
12531// restricted port (port < 1024). Ensure that we can redirect in all other
12532// cases.
bncd16676a2016-07-20 16:23:0112533TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:1112534 HttpRequestInfo restricted_port_request;
12535 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4512536 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1112537 restricted_port_request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1012538 restricted_port_request.traffic_annotation =
12539 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1112540
[email protected]d973e99a2012-02-17 21:02:3612541 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1112542 StaticSocketDataProvider first_data;
12543 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712544 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1112545
12546 MockRead data_reads[] = {
12547 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12548 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0612549 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1112550 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112551 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712552 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1112553
bncb26024382016-06-29 02:39:4512554 SSLSocketDataProvider ssl(ASYNC, OK);
12555 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12556
danakj1fd259a02016-04-16 03:17:0912557 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1112558
bnc525e175a2016-06-20 12:36:4012559 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5312560 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1112561 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2112562 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12563 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1212564 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112565 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4612566 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5012567 expiration);
[email protected]3912662a32011-10-04 00:51:1112568
bnc691fda62016-08-12 00:43:1612569 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112570 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1112571
tfarina42834112016-09-22 13:38:2012572 int rv = trans.Start(&restricted_port_request, callback.callback(),
12573 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112574 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1112575 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0112576 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1112577}
12578
bnc55ff9da2015-08-19 18:42:3512579// Ensure that we are not allowed to redirect traffic via an alternate protocol
12580// to an unrestricted (port >= 1024) when the original traffic was on a
12581// restricted port (port < 1024). Ensure that we can redirect in all other
12582// cases.
bncd16676a2016-07-20 16:23:0112583TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:1112584 HttpRequestInfo unrestricted_port_request;
12585 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4512586 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1112587 unrestricted_port_request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1012588 unrestricted_port_request.traffic_annotation =
12589 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1112590
[email protected]d973e99a2012-02-17 21:02:3612591 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1112592 StaticSocketDataProvider first_data;
12593 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712594 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1112595
12596 MockRead data_reads[] = {
12597 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12598 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0612599 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1112600 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112601 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712602 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4512603 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612604 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512605 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1112606
danakj1fd259a02016-04-16 03:17:0912607 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1112608
bnc525e175a2016-06-20 12:36:4012609 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5312610 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1112611 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2112612 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12613 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1212614 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112615 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4612616 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5012617 expiration);
[email protected]3912662a32011-10-04 00:51:1112618
bnc691fda62016-08-12 00:43:1612619 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112620 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1112621
bnc691fda62016-08-12 00:43:1612622 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2012623 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112624 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1112625 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0112626 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1112627}
12628
bnc55ff9da2015-08-19 18:42:3512629// Ensure that we are not allowed to redirect traffic via an alternate protocol
12630// to an unrestricted (port >= 1024) when the original traffic was on a
12631// restricted port (port < 1024). Ensure that we can redirect in all other
12632// cases.
bncd16676a2016-07-20 16:23:0112633TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:1112634 HttpRequestInfo unrestricted_port_request;
12635 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4512636 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1112637 unrestricted_port_request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1012638 unrestricted_port_request.traffic_annotation =
12639 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1112640
[email protected]d973e99a2012-02-17 21:02:3612641 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1112642 StaticSocketDataProvider first_data;
12643 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712644 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1112645
12646 MockRead data_reads[] = {
12647 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12648 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0612649 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1112650 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112651 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712652 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1112653
bncb26024382016-06-29 02:39:4512654 SSLSocketDataProvider ssl(ASYNC, OK);
12655 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12656
danakj1fd259a02016-04-16 03:17:0912657 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1112658
bnc525e175a2016-06-20 12:36:4012659 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5312660 session->http_server_properties();
bnc0bbb02622015-07-23 10:06:2212661 const int kUnrestrictedAlternatePort = 1025;
bnc3472afd2016-11-17 15:27:2112662 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12663 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1212664 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112665 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4612666 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5012667 expiration);
[email protected]3912662a32011-10-04 00:51:1112668
bnc691fda62016-08-12 00:43:1612669 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112670 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1112671
bnc691fda62016-08-12 00:43:1612672 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2012673 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112674 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1112675 // Valid change to an unrestricted port should pass.
robpercival214763f2016-07-01 23:27:0112676 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1112677}
12678
bnc55ff9da2015-08-19 18:42:3512679// Ensure that we are not allowed to redirect traffic via an alternate protocol
Xida Chen9bfe0b62018-04-24 19:52:2112680// to an unsafe port, and that we resume the second HttpStreamFactory::Job once
12681// the alternate protocol request fails.
bncd16676a2016-07-20 16:23:0112682TEST_F(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:0212683 HttpRequestInfo request;
12684 request.method = "GET";
bncce36dca22015-04-21 22:11:2312685 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1012686 request.traffic_annotation =
12687 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]eb6234e2012-01-19 01:50:0212688
12689 // The alternate protocol request will error out before we attempt to connect,
12690 // so only the standard HTTP request will try to connect.
12691 MockRead data_reads[] = {
12692 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12693 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0612694 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:0212695 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112696 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712697 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:0212698
danakj1fd259a02016-04-16 03:17:0912699 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:0212700
bnc525e175a2016-06-20 12:36:4012701 HttpServerProperties* http_server_properties =
[email protected]eb6234e2012-01-19 01:50:0212702 session->http_server_properties();
12703 const int kUnsafePort = 7;
bnc3472afd2016-11-17 15:27:2112704 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12705 kUnsafePort);
bnc7dc7e1b42015-07-28 14:43:1212706 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112707 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4612708 url::SchemeHostPort(request.url), alternative_service, expiration);
[email protected]eb6234e2012-01-19 01:50:0212709
bnc691fda62016-08-12 00:43:1612710 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]eb6234e2012-01-19 01:50:0212711 TestCompletionCallback callback;
12712
tfarina42834112016-09-22 13:38:2012713 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112714 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]eb6234e2012-01-19 01:50:0212715 // The HTTP request should succeed.
robpercival214763f2016-07-01 23:27:0112716 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb6234e2012-01-19 01:50:0212717
bnc691fda62016-08-12 00:43:1612718 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212719 ASSERT_TRUE(response);
12720 ASSERT_TRUE(response->headers);
[email protected]eb6234e2012-01-19 01:50:0212721 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12722
12723 std::string response_data;
bnc691fda62016-08-12 00:43:1612724 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]eb6234e2012-01-19 01:50:0212725 EXPECT_EQ("hello world", response_data);
12726}
12727
bncd16676a2016-07-20 16:23:0112728TEST_F(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]2ff8b312010-04-26 22:20:5412729 HttpRequestInfo request;
12730 request.method = "GET";
bncb26024382016-06-29 02:39:4512731 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1012732 request.traffic_annotation =
12733 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2ff8b312010-04-26 22:20:5412734
12735 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212736 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312737 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212738 MockRead("\r\n"),
12739 MockRead("hello world"),
12740 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
12741 MockRead(ASYNC, OK)};
[email protected]2ff8b312010-04-26 22:20:5412742
Ryan Sleevib8d7ea02018-05-07 20:01:0112743 StaticSocketDataProvider first_transaction(data_reads,
12744 base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712745 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4512746 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612747 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512748 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5412749
bnc032658ba2016-09-26 18:17:1512750 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5412751
Ryan Hamilton0239aac2018-05-19 00:03:1312752 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4512753 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4112754 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5412755
Ryan Hamilton0239aac2018-05-19 00:03:1312756 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
12757 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5412758 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4112759 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5412760 };
12761
Ryan Sleevib8d7ea02018-05-07 20:01:0112762 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0712763 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5412764
[email protected]d973e99a2012-02-17 21:02:3612765 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0112766 StaticSocketDataProvider hanging_non_alternate_protocol_socket;
[email protected]2d6728692011-03-12 01:39:5512767 hanging_non_alternate_protocol_socket.set_connect_data(
12768 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0712769 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5512770 &hanging_non_alternate_protocol_socket);
12771
[email protected]49639fa2011-12-20 23:22:4112772 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5412773
danakj1fd259a02016-04-16 03:17:0912774 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5812775 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1912776 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5412777
tfarina42834112016-09-22 13:38:2012778 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112779 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12780 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412781
12782 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212783 ASSERT_TRUE(response);
12784 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5412785 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12786
12787 std::string response_data;
robpercival214763f2016-07-01 23:27:0112788 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412789 EXPECT_EQ("hello world", response_data);
12790
bnc87dcefc2017-05-25 12:47:5812791 trans =
Jeremy Roman0579ed62017-08-29 15:56:1912792 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5412793
tfarina42834112016-09-22 13:38:2012794 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112795 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12796 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412797
12798 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212799 ASSERT_TRUE(response);
12800 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212801 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5312802 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212803 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5412804
robpercival214763f2016-07-01 23:27:0112805 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412806 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:5412807}
12808
bncd16676a2016-07-20 16:23:0112809TEST_F(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]2d6728692011-03-12 01:39:5512810 HttpRequestInfo request;
12811 request.method = "GET";
bncb26024382016-06-29 02:39:4512812 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1012813 request.traffic_annotation =
12814 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d6728692011-03-12 01:39:5512815
bncb26024382016-06-29 02:39:4512816 // First transaction receives Alt-Svc header over HTTP/1.1.
[email protected]2d6728692011-03-12 01:39:5512817 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212818 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312819 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212820 MockRead("\r\n"),
12821 MockRead("hello world"),
12822 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
12823 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5512824 };
12825
Ryan Sleevib8d7ea02018-05-07 20:01:0112826 StaticSocketDataProvider http11_data(data_reads, base::span<MockWrite>());
bncb26024382016-06-29 02:39:4512827 session_deps_.socket_factory->AddSocketDataProvider(&http11_data);
[email protected]2d6728692011-03-12 01:39:5512828
bncb26024382016-06-29 02:39:4512829 SSLSocketDataProvider ssl_http11(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4912830 ssl_http11.ssl_info.cert =
12831 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
12832 ASSERT_TRUE(ssl_http11.ssl_info.cert);
bncb26024382016-06-29 02:39:4512833 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
12834
12835 // Second transaction starts an alternative and a non-alternative Job.
12836 // Both sockets hang.
[email protected]d973e99a2012-02-17 21:02:3612837 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0112838 StaticSocketDataProvider hanging_socket1;
mmenkecc2298e2015-12-07 18:20:1812839 hanging_socket1.set_connect_data(never_finishing_connect);
mmenkecc2298e2015-12-07 18:20:1812840 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket1);
12841
Ryan Sleevib8d7ea02018-05-07 20:01:0112842 StaticSocketDataProvider hanging_socket2;
mmenkecc2298e2015-12-07 18:20:1812843 hanging_socket2.set_connect_data(never_finishing_connect);
12844 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket2);
[email protected]2d6728692011-03-12 01:39:5512845
bncb26024382016-06-29 02:39:4512846 // Third transaction starts an alternative and a non-alternative job.
12847 // The non-alternative job hangs, but the alternative one succeeds.
12848 // The second transaction, still pending, binds to this socket.
Ryan Hamilton0239aac2018-05-19 00:03:1312849 spdy::SpdySerializedFrame req1(
bncb26024382016-06-29 02:39:4512850 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1312851 spdy::SpdySerializedFrame req2(
bncb26024382016-06-29 02:39:4512852 spdy_util_.ConstructSpdyGet("https://www.example.org/", 3, LOWEST));
[email protected]2d6728692011-03-12 01:39:5512853 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4112854 CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
[email protected]2d6728692011-03-12 01:39:5512855 };
Ryan Hamilton0239aac2018-05-19 00:03:1312856 spdy::SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
12857 spdy::SpdySerializedFrame data1(spdy_util_.ConstructSpdyDataFrame(1, true));
12858 spdy::SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
12859 spdy::SpdySerializedFrame data2(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]2d6728692011-03-12 01:39:5512860 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4112861 CreateMockRead(resp1, 2), CreateMockRead(data1, 3),
12862 CreateMockRead(resp2, 4), CreateMockRead(data2, 5),
rch8e6c6c42015-05-01 14:05:1312863 MockRead(ASYNC, 0, 6),
[email protected]2d6728692011-03-12 01:39:5512864 };
12865
Ryan Sleevib8d7ea02018-05-07 20:01:0112866 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0712867 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:5512868
bnc032658ba2016-09-26 18:17:1512869 AddSSLSocketData();
bncb26024382016-06-29 02:39:4512870
Ryan Sleevib8d7ea02018-05-07 20:01:0112871 StaticSocketDataProvider hanging_socket3;
mmenkecc2298e2015-12-07 18:20:1812872 hanging_socket3.set_connect_data(never_finishing_connect);
12873 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket3);
[email protected]2d6728692011-03-12 01:39:5512874
danakj1fd259a02016-04-16 03:17:0912875 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:4112876 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:5012877 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5512878
tfarina42834112016-09-22 13:38:2012879 int rv = trans1.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112880 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12881 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512882
12883 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5212884 ASSERT_TRUE(response);
12885 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5512886 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12887
12888 std::string response_data;
robpercival214763f2016-07-01 23:27:0112889 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512890 EXPECT_EQ("hello world", response_data);
12891
[email protected]49639fa2011-12-20 23:22:4112892 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:5012893 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2012894 rv = trans2.Start(&request, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112895 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5512896
[email protected]49639fa2011-12-20 23:22:4112897 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:5012898 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2012899 rv = trans3.Start(&request, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112900 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5512901
robpercival214763f2016-07-01 23:27:0112902 EXPECT_THAT(callback2.WaitForResult(), IsOk());
12903 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512904
12905 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5212906 ASSERT_TRUE(response);
12907 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212908 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5512909 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212910 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0112911 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512912 EXPECT_EQ("hello!", response_data);
12913
12914 response = trans3.GetResponseInfo();
wezca1070932016-05-26 20:30:5212915 ASSERT_TRUE(response);
12916 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212917 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5512918 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212919 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0112920 ASSERT_THAT(ReadTransaction(&trans3, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512921 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:5512922}
12923
bncd16676a2016-07-20 16:23:0112924TEST_F(HttpNetworkTransactionTest, StallAlternativeServiceForNpnSpdy) {
Bence Békybcae37092018-06-12 04:18:5312925 session_deps_.host_resolver->set_synchronous_mode(true);
12926
[email protected]2d6728692011-03-12 01:39:5512927 HttpRequestInfo request;
12928 request.method = "GET";
bncb26024382016-06-29 02:39:4512929 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1012930 request.traffic_annotation =
12931 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d6728692011-03-12 01:39:5512932
12933 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212934 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312935 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212936 MockRead("\r\n"),
12937 MockRead("hello world"),
12938 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
12939 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5512940 };
12941
Ryan Sleevib8d7ea02018-05-07 20:01:0112942 StaticSocketDataProvider first_transaction(data_reads,
12943 base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712944 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:5512945
[email protected]8ddf8322012-02-23 18:08:0612946 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4912947 ssl.ssl_info.cert =
12948 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
12949 ASSERT_TRUE(ssl.ssl_info.cert);
[email protected]bb88e1d32013-05-03 23:11:0712950 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5512951
[email protected]d973e99a2012-02-17 21:02:3612952 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0112953 StaticSocketDataProvider hanging_alternate_protocol_socket;
[email protected]2d6728692011-03-12 01:39:5512954 hanging_alternate_protocol_socket.set_connect_data(
12955 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0712956 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5512957 &hanging_alternate_protocol_socket);
12958
bncb26024382016-06-29 02:39:4512959 // 2nd request is just a copy of the first one, over HTTP/1.1 again.
Ryan Sleevib8d7ea02018-05-07 20:01:0112960 StaticSocketDataProvider second_transaction(data_reads,
12961 base::span<MockWrite>());
mmenkecc2298e2015-12-07 18:20:1812962 session_deps_.socket_factory->AddSocketDataProvider(&second_transaction);
bncb26024382016-06-29 02:39:4512963 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5512964
[email protected]49639fa2011-12-20 23:22:4112965 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:5512966
danakj1fd259a02016-04-16 03:17:0912967 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5812968 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1912969 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5512970
tfarina42834112016-09-22 13:38:2012971 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112972 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12973 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512974
12975 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212976 ASSERT_TRUE(response);
12977 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5512978 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12979
12980 std::string response_data;
robpercival214763f2016-07-01 23:27:0112981 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512982 EXPECT_EQ("hello world", response_data);
12983
bnc87dcefc2017-05-25 12:47:5812984 trans =
Jeremy Roman0579ed62017-08-29 15:56:1912985 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5512986
tfarina42834112016-09-22 13:38:2012987 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112988 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12989 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512990
12991 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212992 ASSERT_TRUE(response);
12993 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5512994 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12995 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212996 EXPECT_FALSE(response->was_alpn_negotiated);
[email protected]2d6728692011-03-12 01:39:5512997
robpercival214763f2016-07-01 23:27:0112998 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512999 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:5513000}
13001
bnc2e884782016-08-11 19:45:1913002// Test that proxy is resolved using the origin url,
13003// regardless of the alternative server.
13004TEST_F(HttpNetworkTransactionTest, UseOriginNotAlternativeForProxy) {
13005 // Configure proxy to bypass www.example.org, which is the origin URL.
13006 ProxyConfig proxy_config;
13007 proxy_config.proxy_rules().ParseFromString("myproxy:70");
13008 proxy_config.proxy_rules().bypass_rules.AddRuleFromString("www.example.org");
Ramin Halavatica8d5252018-03-12 05:33:4913009 auto proxy_config_service = std::make_unique<ProxyConfigServiceFixed>(
13010 ProxyConfigWithAnnotation(proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS));
bnc2e884782016-08-11 19:45:1913011
13012 CapturingProxyResolver capturing_proxy_resolver;
Jeremy Roman0579ed62017-08-29 15:56:1913013 auto proxy_resolver_factory = std::make_unique<CapturingProxyResolverFactory>(
bnc2e884782016-08-11 19:45:1913014 &capturing_proxy_resolver);
13015
13016 TestNetLog net_log;
13017
Bence Béky53a5aef2018-03-29 21:54:1213018 session_deps_.proxy_resolution_service =
13019 std::make_unique<ProxyResolutionService>(
13020 std::move(proxy_config_service), std::move(proxy_resolver_factory),
13021 &net_log);
bnc2e884782016-08-11 19:45:1913022
13023 session_deps_.net_log = &net_log;
13024
13025 // Configure alternative service with a hostname that is not bypassed by the
13026 // proxy.
13027 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13028 HttpServerProperties* http_server_properties =
13029 session->http_server_properties();
13030 url::SchemeHostPort server("https", "www.example.org", 443);
13031 HostPortPair alternative("www.example.com", 443);
bnc3472afd2016-11-17 15:27:2113032 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc2e884782016-08-11 19:45:1913033 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2113034 http_server_properties->SetHttp2AlternativeService(
13035 server, alternative_service, expiration);
bnc2e884782016-08-11 19:45:1913036
13037 // Non-alternative job should hang.
13038 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0113039 StaticSocketDataProvider hanging_alternate_protocol_socket;
bnc2e884782016-08-11 19:45:1913040 hanging_alternate_protocol_socket.set_connect_data(never_finishing_connect);
13041 session_deps_.socket_factory->AddSocketDataProvider(
13042 &hanging_alternate_protocol_socket);
13043
bnc032658ba2016-09-26 18:17:1513044 AddSSLSocketData();
bnc2e884782016-08-11 19:45:1913045
13046 HttpRequestInfo request;
13047 request.method = "GET";
13048 request.url = GURL("https://www.example.org/");
13049 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1013050 request.traffic_annotation =
13051 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc2e884782016-08-11 19:45:1913052
Ryan Hamilton0239aac2018-05-19 00:03:1313053 spdy::SpdySerializedFrame req(
bnc2e884782016-08-11 19:45:1913054 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
13055
13056 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
13057
Ryan Hamilton0239aac2018-05-19 00:03:1313058 spdy::SpdySerializedFrame resp(
13059 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
13060 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
bnc2e884782016-08-11 19:45:1913061 MockRead spdy_reads[] = {
13062 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
13063 };
13064
Ryan Sleevib8d7ea02018-05-07 20:01:0113065 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
bnc2e884782016-08-11 19:45:1913066 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
13067
13068 TestCompletionCallback callback;
13069
13070 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
13071
tfarina42834112016-09-22 13:38:2013072 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc2e884782016-08-11 19:45:1913073 EXPECT_THAT(callback.GetResult(rv), IsOk());
13074
13075 const HttpResponseInfo* response = trans.GetResponseInfo();
13076 ASSERT_TRUE(response);
13077 ASSERT_TRUE(response->headers);
13078 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
13079 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213080 EXPECT_TRUE(response->was_alpn_negotiated);
bnc2e884782016-08-11 19:45:1913081
13082 std::string response_data;
13083 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
13084 EXPECT_EQ("hello!", response_data);
13085
13086 // Origin host bypasses proxy, no resolution should have happened.
13087 ASSERT_TRUE(capturing_proxy_resolver.resolved().empty());
13088}
13089
bncd16676a2016-07-20 16:23:0113090TEST_F(HttpNetworkTransactionTest, UseAlternativeServiceForTunneledNpnSpdy) {
[email protected]631f1322010-04-30 17:59:1113091 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:4213092 proxy_config.set_auto_detect(true);
13093 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:1113094
sammc5dd160c2015-04-02 02:43:1313095 CapturingProxyResolver capturing_proxy_resolver;
Ramin Halavatica8d5252018-03-12 05:33:4913096 session_deps_.proxy_resolution_service =
13097 std::make_unique<ProxyResolutionService>(
13098 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
13099 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
13100 std::make_unique<CapturingProxyResolverFactory>(
13101 &capturing_proxy_resolver),
13102 nullptr);
vishal.b62985ca92015-04-17 08:45:5113103 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0713104 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:1113105
13106 HttpRequestInfo request;
13107 request.method = "GET";
bncb26024382016-06-29 02:39:4513108 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1013109 request.traffic_annotation =
13110 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]631f1322010-04-30 17:59:1113111
13112 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5213113 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4313114 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5213115 MockRead("\r\n"),
13116 MockRead("hello world"),
13117 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
13118 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:1113119 };
13120
Ryan Sleevib8d7ea02018-05-07 20:01:0113121 StaticSocketDataProvider first_transaction(data_reads,
13122 base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0713123 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4513124 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613125 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4513126 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]631f1322010-04-30 17:59:1113127
bnc032658ba2016-09-26 18:17:1513128 AddSSLSocketData();
[email protected]631f1322010-04-30 17:59:1113129
Ryan Hamilton0239aac2018-05-19 00:03:1313130 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4513131 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
[email protected]631f1322010-04-30 17:59:1113132 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1313133 MockWrite(ASYNC, 0,
bnc8bef8da22016-05-30 01:28:2513134 "CONNECT www.example.org:443 HTTP/1.1\r\n"
13135 "Host: www.example.org:443\r\n"
rch8e6c6c42015-05-01 14:05:1313136 "Proxy-Connection: keep-alive\r\n\r\n"),
bncdf80d44fd2016-07-15 20:27:4113137 CreateMockWrite(req, 2),
[email protected]631f1322010-04-30 17:59:1113138 };
13139
[email protected]d911f1b2010-05-05 22:39:4213140 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
13141
Ryan Hamilton0239aac2018-05-19 00:03:1313142 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
13143 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]631f1322010-04-30 17:59:1113144 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113145 MockRead(ASYNC, 1, kCONNECTResponse), CreateMockRead(resp, 3),
13146 CreateMockRead(data, 4), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5),
[email protected]631f1322010-04-30 17:59:1113147 };
13148
Ryan Sleevib8d7ea02018-05-07 20:01:0113149 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0713150 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:1113151
[email protected]d973e99a2012-02-17 21:02:3613152 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0113153 StaticSocketDataProvider hanging_non_alternate_protocol_socket;
[email protected]2d6728692011-03-12 01:39:5513154 hanging_non_alternate_protocol_socket.set_connect_data(
13155 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0713156 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5513157 &hanging_non_alternate_protocol_socket);
13158
[email protected]49639fa2011-12-20 23:22:4113159 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:1113160
danakj1fd259a02016-04-16 03:17:0913161 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5813162 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1913163 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1113164
tfarina42834112016-09-22 13:38:2013165 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea2dcd3bf2016-08-16 21:49:4113166 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13167 EXPECT_THAT(callback.WaitForResult(), IsOk());
13168
13169 const HttpResponseInfo* response = trans->GetResponseInfo();
13170 ASSERT_TRUE(response);
13171 ASSERT_TRUE(response->headers);
13172 EXPECT_EQ("HTTP/0.9 200 OK", response->headers->GetStatusLine());
13173 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213174 EXPECT_TRUE(response->was_alpn_negotiated);
mmenkea2dcd3bf2016-08-16 21:49:4113175
13176 std::string response_data;
13177 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
13178 EXPECT_EQ("hello world", response_data);
[email protected]631f1322010-04-30 17:59:1113179
bnc87dcefc2017-05-25 12:47:5813180 trans =
Jeremy Roman0579ed62017-08-29 15:56:1913181 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1113182
tfarina42834112016-09-22 13:38:2013183 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113184 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13185 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]631f1322010-04-30 17:59:1113186
mmenkea2dcd3bf2016-08-16 21:49:4113187 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5213188 ASSERT_TRUE(response);
13189 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213190 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5313191 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213192 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]631f1322010-04-30 17:59:1113193
robpercival214763f2016-07-01 23:27:0113194 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]631f1322010-04-30 17:59:1113195 EXPECT_EQ("hello!", response_data);
bncb26024382016-06-29 02:39:4513196 ASSERT_EQ(2u, capturing_proxy_resolver.resolved().size());
13197 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1313198 capturing_proxy_resolver.resolved()[0].spec());
bncce36dca22015-04-21 22:11:2313199 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1313200 capturing_proxy_resolver.resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:1113201
[email protected]029c83b62013-01-24 05:28:2013202 LoadTimingInfo load_timing_info;
13203 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
13204 TestLoadTimingNotReusedWithPac(load_timing_info,
13205 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:1113206}
[email protected]631f1322010-04-30 17:59:1113207
bncd16676a2016-07-20 16:23:0113208TEST_F(HttpNetworkTransactionTest,
bnc1c196c6e2016-05-28 13:51:4813209 UseAlternativeServiceForNpnSpdyWithExistingSpdySession) {
[email protected]2ff8b312010-04-26 22:20:5413210 HttpRequestInfo request;
13211 request.method = "GET";
bncb26024382016-06-29 02:39:4513212 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1013213 request.traffic_annotation =
13214 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2ff8b312010-04-26 22:20:5413215
13216 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5213217 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4313218 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5213219 MockRead("\r\n"),
13220 MockRead("hello world"),
13221 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:5413222 };
13223
Ryan Sleevib8d7ea02018-05-07 20:01:0113224 StaticSocketDataProvider first_transaction(data_reads,
13225 base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0713226 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4513227 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613228 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4513229 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5413230
bnc032658ba2016-09-26 18:17:1513231 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5413232
Ryan Hamilton0239aac2018-05-19 00:03:1313233 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4513234 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4113235 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5413236
Ryan Hamilton0239aac2018-05-19 00:03:1313237 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
13238 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5413239 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113240 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5413241 };
13242
Ryan Sleevib8d7ea02018-05-07 20:01:0113243 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0713244 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5413245
[email protected]83039bb2011-12-09 18:43:5513246 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5413247
danakj1fd259a02016-04-16 03:17:0913248 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:5413249
bnc87dcefc2017-05-25 12:47:5813250 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1913251 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5413252
tfarina42834112016-09-22 13:38:2013253 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113254 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13255 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5413256
13257 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5213258 ASSERT_TRUE(response);
13259 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5413260 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13261
13262 std::string response_data;
robpercival214763f2016-07-01 23:27:0113263 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5413264 EXPECT_EQ("hello world", response_data);
13265
13266 // Set up an initial SpdySession in the pool to reuse.
bnc8bef8da22016-05-30 01:28:2513267 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4013268 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
Matt Menke2436b2f2018-12-11 18:07:1113269 PRIVACY_MODE_DISABLED,
13270 SpdySessionKey::IsProxySession::kFalse, SocketTag());
[email protected]795cbf82013-07-22 09:37:2713271 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:5213272 CreateSpdySession(session.get(), key, NetLogWithSource());
[email protected]02b0c342010-09-25 21:09:3813273
bnc87dcefc2017-05-25 12:47:5813274 trans =
Jeremy Roman0579ed62017-08-29 15:56:1913275 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5413276
tfarina42834112016-09-22 13:38:2013277 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113278 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13279 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5413280
13281 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5213282 ASSERT_TRUE(response);
13283 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213284 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5313285 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213286 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5413287
robpercival214763f2016-07-01 23:27:0113288 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5413289 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:4213290}
13291
[email protected]044de0642010-06-17 10:42:1513292// GenerateAuthToken is a mighty big test.
13293// It tests all permutation of GenerateAuthToken behavior:
13294// - Synchronous and Asynchronous completion.
13295// - OK or error on completion.
13296// - Direct connection, non-authenticating proxy, and authenticating proxy.
13297// - HTTP or HTTPS backend (to include proxy tunneling).
13298// - Non-authenticating and authenticating backend.
13299//
[email protected]fe3b7dc2012-02-03 19:52:0913300// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:1513301// problems generating an auth token for an authenticating proxy, we don't
13302// need to test all permutations of the backend server).
13303//
13304// The test proceeds by going over each of the configuration cases, and
13305// potentially running up to three rounds in each of the tests. The TestConfig
13306// specifies both the configuration for the test as well as the expectations
13307// for the results.
bncd16676a2016-07-20 16:23:0113308TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:5013309 static const char kServer[] = "http://www.example.com";
13310 static const char kSecureServer[] = "https://www.example.com";
13311 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:1513312
13313 enum AuthTiming {
13314 AUTH_NONE,
13315 AUTH_SYNC,
13316 AUTH_ASYNC,
13317 };
13318
13319 const MockWrite kGet(
13320 "GET / HTTP/1.1\r\n"
13321 "Host: www.example.com\r\n"
13322 "Connection: keep-alive\r\n\r\n");
13323 const MockWrite kGetProxy(
13324 "GET http://www.example.com/ HTTP/1.1\r\n"
13325 "Host: www.example.com\r\n"
13326 "Proxy-Connection: keep-alive\r\n\r\n");
13327 const MockWrite kGetAuth(
13328 "GET / HTTP/1.1\r\n"
13329 "Host: www.example.com\r\n"
13330 "Connection: keep-alive\r\n"
13331 "Authorization: auth_token\r\n\r\n");
13332 const MockWrite kGetProxyAuth(
13333 "GET http://www.example.com/ HTTP/1.1\r\n"
13334 "Host: www.example.com\r\n"
13335 "Proxy-Connection: keep-alive\r\n"
13336 "Proxy-Authorization: auth_token\r\n\r\n");
13337 const MockWrite kGetAuthThroughProxy(
13338 "GET http://www.example.com/ HTTP/1.1\r\n"
13339 "Host: www.example.com\r\n"
13340 "Proxy-Connection: keep-alive\r\n"
13341 "Authorization: auth_token\r\n\r\n");
13342 const MockWrite kGetAuthWithProxyAuth(
13343 "GET http://www.example.com/ HTTP/1.1\r\n"
13344 "Host: www.example.com\r\n"
13345 "Proxy-Connection: keep-alive\r\n"
13346 "Proxy-Authorization: auth_token\r\n"
13347 "Authorization: auth_token\r\n\r\n");
13348 const MockWrite kConnect(
13349 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1713350 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1513351 "Proxy-Connection: keep-alive\r\n\r\n");
13352 const MockWrite kConnectProxyAuth(
13353 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1713354 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1513355 "Proxy-Connection: keep-alive\r\n"
13356 "Proxy-Authorization: auth_token\r\n\r\n");
13357
13358 const MockRead kSuccess(
13359 "HTTP/1.1 200 OK\r\n"
13360 "Content-Type: text/html; charset=iso-8859-1\r\n"
13361 "Content-Length: 3\r\n\r\n"
13362 "Yes");
13363 const MockRead kFailure(
13364 "Should not be called.");
13365 const MockRead kServerChallenge(
13366 "HTTP/1.1 401 Unauthorized\r\n"
13367 "WWW-Authenticate: Mock realm=server\r\n"
13368 "Content-Type: text/html; charset=iso-8859-1\r\n"
13369 "Content-Length: 14\r\n\r\n"
13370 "Unauthorized\r\n");
13371 const MockRead kProxyChallenge(
13372 "HTTP/1.1 407 Unauthorized\r\n"
13373 "Proxy-Authenticate: Mock realm=proxy\r\n"
13374 "Proxy-Connection: close\r\n"
13375 "Content-Type: text/html; charset=iso-8859-1\r\n"
13376 "Content-Length: 14\r\n\r\n"
13377 "Unauthorized\r\n");
13378 const MockRead kProxyConnected(
13379 "HTTP/1.1 200 Connection Established\r\n\r\n");
13380
13381 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
13382 // no constructors, but the C++ compiler on Windows warns about
13383 // unspecified data in compound literals. So, moved to using constructors,
13384 // and TestRound's created with the default constructor should not be used.
13385 struct TestRound {
13386 TestRound()
13387 : expected_rv(ERR_UNEXPECTED),
13388 extra_write(NULL),
13389 extra_read(NULL) {
13390 }
13391 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
13392 int expected_rv_arg)
13393 : write(write_arg),
13394 read(read_arg),
13395 expected_rv(expected_rv_arg),
13396 extra_write(NULL),
13397 extra_read(NULL) {
13398 }
13399 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
13400 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:0113401 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:1513402 : write(write_arg),
13403 read(read_arg),
13404 expected_rv(expected_rv_arg),
13405 extra_write(extra_write_arg),
13406 extra_read(extra_read_arg) {
13407 }
13408 MockWrite write;
13409 MockRead read;
13410 int expected_rv;
13411 const MockWrite* extra_write;
13412 const MockRead* extra_read;
13413 };
13414
13415 static const int kNoSSL = 500;
13416
13417 struct TestConfig {
asanka463ca4262016-11-16 02:34:3113418 int line_number;
thestig9d3bb0c2015-01-24 00:49:5113419 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:1513420 AuthTiming proxy_auth_timing;
asanka463ca4262016-11-16 02:34:3113421 int first_generate_proxy_token_rv;
thestig9d3bb0c2015-01-24 00:49:5113422 const char* const server_url;
[email protected]044de0642010-06-17 10:42:1513423 AuthTiming server_auth_timing;
asanka463ca4262016-11-16 02:34:3113424 int first_generate_server_token_rv;
[email protected]044de0642010-06-17 10:42:1513425 int num_auth_rounds;
13426 int first_ssl_round;
asankae2257db2016-10-11 22:03:1613427 TestRound rounds[4];
[email protected]044de0642010-06-17 10:42:1513428 } test_configs[] = {
asankac93076192016-10-03 15:46:0213429 // Non-authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3113430 {__LINE__,
13431 nullptr,
asankac93076192016-10-03 15:46:0213432 AUTH_NONE,
13433 OK,
13434 kServer,
13435 AUTH_NONE,
13436 OK,
13437 1,
13438 kNoSSL,
13439 {TestRound(kGet, kSuccess, OK)}},
13440 // Authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3113441 {__LINE__,
13442 nullptr,
asankac93076192016-10-03 15:46:0213443 AUTH_NONE,
13444 OK,
13445 kServer,
13446 AUTH_SYNC,
13447 OK,
13448 2,
13449 kNoSSL,
13450 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513451 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113452 {__LINE__,
13453 nullptr,
asankac93076192016-10-03 15:46:0213454 AUTH_NONE,
13455 OK,
13456 kServer,
13457 AUTH_SYNC,
13458 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1613459 3,
13460 kNoSSL,
13461 {TestRound(kGet, kServerChallenge, OK),
13462 TestRound(kGet, kServerChallenge, OK),
13463 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113464 {__LINE__,
13465 nullptr,
asankae2257db2016-10-11 22:03:1613466 AUTH_NONE,
13467 OK,
13468 kServer,
13469 AUTH_SYNC,
13470 ERR_UNSUPPORTED_AUTH_SCHEME,
13471 2,
13472 kNoSSL,
13473 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113474 {__LINE__,
13475 nullptr,
asankae2257db2016-10-11 22:03:1613476 AUTH_NONE,
13477 OK,
13478 kServer,
13479 AUTH_SYNC,
13480 ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS,
13481 2,
13482 kNoSSL,
13483 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113484 {__LINE__,
13485 kProxy,
asankae2257db2016-10-11 22:03:1613486 AUTH_SYNC,
13487 ERR_FAILED,
13488 kServer,
13489 AUTH_NONE,
13490 OK,
13491 2,
13492 kNoSSL,
13493 {TestRound(kGetProxy, kProxyChallenge, OK),
13494 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3113495 {__LINE__,
13496 kProxy,
asankae2257db2016-10-11 22:03:1613497 AUTH_ASYNC,
13498 ERR_FAILED,
13499 kServer,
13500 AUTH_NONE,
13501 OK,
13502 2,
13503 kNoSSL,
13504 {TestRound(kGetProxy, kProxyChallenge, OK),
13505 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3113506 {__LINE__,
13507 nullptr,
asankae2257db2016-10-11 22:03:1613508 AUTH_NONE,
13509 OK,
13510 kServer,
13511 AUTH_SYNC,
13512 ERR_FAILED,
asankac93076192016-10-03 15:46:0213513 2,
13514 kNoSSL,
13515 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613516 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3113517 {__LINE__,
13518 nullptr,
asankae2257db2016-10-11 22:03:1613519 AUTH_NONE,
13520 OK,
13521 kServer,
13522 AUTH_ASYNC,
13523 ERR_FAILED,
13524 2,
13525 kNoSSL,
13526 {TestRound(kGet, kServerChallenge, OK),
13527 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3113528 {__LINE__,
13529 nullptr,
asankac93076192016-10-03 15:46:0213530 AUTH_NONE,
13531 OK,
13532 kServer,
13533 AUTH_ASYNC,
13534 OK,
13535 2,
13536 kNoSSL,
13537 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513538 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113539 {__LINE__,
13540 nullptr,
asankac93076192016-10-03 15:46:0213541 AUTH_NONE,
13542 OK,
13543 kServer,
13544 AUTH_ASYNC,
13545 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1613546 3,
asankac93076192016-10-03 15:46:0213547 kNoSSL,
13548 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613549 // The second round uses a HttpAuthHandlerMock that always succeeds.
13550 TestRound(kGet, kServerChallenge, OK),
13551 TestRound(kGetAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213552 // Non-authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3113553 {__LINE__,
13554 kProxy,
asankac93076192016-10-03 15:46:0213555 AUTH_NONE,
13556 OK,
13557 kServer,
13558 AUTH_NONE,
13559 OK,
13560 1,
13561 kNoSSL,
13562 {TestRound(kGetProxy, kSuccess, OK)}},
13563 // Authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3113564 {__LINE__,
13565 kProxy,
asankac93076192016-10-03 15:46:0213566 AUTH_NONE,
13567 OK,
13568 kServer,
13569 AUTH_SYNC,
13570 OK,
13571 2,
13572 kNoSSL,
13573 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513574 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113575 {__LINE__,
13576 kProxy,
asankac93076192016-10-03 15:46:0213577 AUTH_NONE,
13578 OK,
13579 kServer,
13580 AUTH_SYNC,
13581 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1613582 3,
asankac93076192016-10-03 15:46:0213583 kNoSSL,
13584 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613585 TestRound(kGetProxy, kServerChallenge, OK),
13586 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_ASYNC,
13593 OK,
13594 2,
13595 kNoSSL,
13596 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513597 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113598 {__LINE__,
13599 kProxy,
asankac93076192016-10-03 15:46:0213600 AUTH_NONE,
13601 OK,
13602 kServer,
13603 AUTH_ASYNC,
13604 ERR_INVALID_AUTH_CREDENTIALS,
13605 2,
13606 kNoSSL,
13607 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613608 TestRound(kGetProxy, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213609 // Non-authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3113610 {__LINE__,
13611 kProxy,
asankac93076192016-10-03 15:46:0213612 AUTH_SYNC,
13613 OK,
13614 kServer,
13615 AUTH_NONE,
13616 OK,
13617 2,
13618 kNoSSL,
13619 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513620 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113621 {__LINE__,
13622 kProxy,
asankac93076192016-10-03 15:46:0213623 AUTH_SYNC,
13624 ERR_INVALID_AUTH_CREDENTIALS,
13625 kServer,
13626 AUTH_NONE,
13627 OK,
13628 2,
13629 kNoSSL,
13630 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1613631 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113632 {__LINE__,
13633 kProxy,
asankac93076192016-10-03 15:46:0213634 AUTH_ASYNC,
13635 OK,
13636 kServer,
13637 AUTH_NONE,
13638 OK,
13639 2,
13640 kNoSSL,
13641 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513642 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113643 {__LINE__,
13644 kProxy,
asankac93076192016-10-03 15:46:0213645 AUTH_ASYNC,
13646 ERR_INVALID_AUTH_CREDENTIALS,
13647 kServer,
13648 AUTH_NONE,
13649 OK,
13650 2,
13651 kNoSSL,
13652 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1613653 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113654 {__LINE__,
13655 kProxy,
13656 AUTH_ASYNC,
13657 ERR_INVALID_AUTH_CREDENTIALS,
13658 kServer,
13659 AUTH_NONE,
13660 OK,
13661 3,
13662 kNoSSL,
13663 {TestRound(kGetProxy, kProxyChallenge, OK),
13664 TestRound(kGetProxy, kProxyChallenge, OK),
13665 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213666 // Authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3113667 {__LINE__,
13668 kProxy,
asankac93076192016-10-03 15:46:0213669 AUTH_SYNC,
13670 OK,
13671 kServer,
13672 AUTH_SYNC,
13673 OK,
13674 3,
13675 kNoSSL,
13676 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513677 TestRound(kGetProxyAuth, kServerChallenge, OK),
13678 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
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 ERR_INVALID_AUTH_CREDENTIALS,
13686 3,
13687 kNoSSL,
13688 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513689 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613690 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113691 {__LINE__,
13692 kProxy,
asankac93076192016-10-03 15:46:0213693 AUTH_ASYNC,
13694 OK,
13695 kServer,
13696 AUTH_SYNC,
13697 OK,
13698 3,
13699 kNoSSL,
13700 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513701 TestRound(kGetProxyAuth, kServerChallenge, OK),
13702 TestRound(kGetAuthWithProxyAuth, 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 ERR_INVALID_AUTH_CREDENTIALS,
13710 3,
13711 kNoSSL,
13712 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513713 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613714 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113715 {__LINE__,
13716 kProxy,
asankac93076192016-10-03 15:46:0213717 AUTH_SYNC,
13718 OK,
13719 kServer,
13720 AUTH_ASYNC,
13721 OK,
13722 3,
13723 kNoSSL,
13724 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513725 TestRound(kGetProxyAuth, kServerChallenge, OK),
13726 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113727 {__LINE__,
13728 kProxy,
13729 AUTH_SYNC,
13730 ERR_INVALID_AUTH_CREDENTIALS,
13731 kServer,
13732 AUTH_ASYNC,
13733 OK,
13734 4,
13735 kNoSSL,
13736 {TestRound(kGetProxy, kProxyChallenge, OK),
13737 TestRound(kGetProxy, kProxyChallenge, OK),
13738 TestRound(kGetProxyAuth, kServerChallenge, OK),
13739 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
13740 {__LINE__,
13741 kProxy,
asankac93076192016-10-03 15:46:0213742 AUTH_SYNC,
13743 OK,
13744 kServer,
13745 AUTH_ASYNC,
13746 ERR_INVALID_AUTH_CREDENTIALS,
13747 3,
13748 kNoSSL,
13749 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513750 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613751 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113752 {__LINE__,
13753 kProxy,
asankac93076192016-10-03 15:46:0213754 AUTH_ASYNC,
13755 OK,
13756 kServer,
13757 AUTH_ASYNC,
13758 OK,
13759 3,
13760 kNoSSL,
13761 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513762 TestRound(kGetProxyAuth, kServerChallenge, OK),
13763 TestRound(kGetAuthWithProxyAuth, 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 ERR_INVALID_AUTH_CREDENTIALS,
13771 3,
13772 kNoSSL,
13773 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513774 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613775 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113776 {__LINE__,
13777 kProxy,
13778 AUTH_ASYNC,
13779 ERR_INVALID_AUTH_CREDENTIALS,
13780 kServer,
13781 AUTH_ASYNC,
13782 ERR_INVALID_AUTH_CREDENTIALS,
13783 4,
13784 kNoSSL,
13785 {TestRound(kGetProxy, kProxyChallenge, OK),
13786 TestRound(kGetProxy, kProxyChallenge, OK),
13787 TestRound(kGetProxyAuth, kServerChallenge, OK),
13788 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213789 // Non-authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3113790 {__LINE__,
13791 nullptr,
asankac93076192016-10-03 15:46:0213792 AUTH_NONE,
13793 OK,
13794 kSecureServer,
13795 AUTH_NONE,
13796 OK,
13797 1,
13798 0,
13799 {TestRound(kGet, kSuccess, OK)}},
13800 // Authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3113801 {__LINE__,
13802 nullptr,
asankac93076192016-10-03 15:46:0213803 AUTH_NONE,
13804 OK,
13805 kSecureServer,
13806 AUTH_SYNC,
13807 OK,
13808 2,
13809 0,
13810 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513811 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113812 {__LINE__,
13813 nullptr,
asankac93076192016-10-03 15:46:0213814 AUTH_NONE,
13815 OK,
13816 kSecureServer,
13817 AUTH_SYNC,
13818 ERR_INVALID_AUTH_CREDENTIALS,
13819 2,
13820 0,
asankae2257db2016-10-11 22:03:1613821 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113822 {__LINE__,
13823 nullptr,
asankac93076192016-10-03 15:46:0213824 AUTH_NONE,
13825 OK,
13826 kSecureServer,
13827 AUTH_ASYNC,
13828 OK,
13829 2,
13830 0,
13831 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513832 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113833 {__LINE__,
13834 nullptr,
asankac93076192016-10-03 15:46:0213835 AUTH_NONE,
13836 OK,
13837 kSecureServer,
13838 AUTH_ASYNC,
13839 ERR_INVALID_AUTH_CREDENTIALS,
13840 2,
13841 0,
asankae2257db2016-10-11 22:03:1613842 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213843 // Non-authenticating HTTPS server with a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3113844 {__LINE__,
13845 kProxy,
asankac93076192016-10-03 15:46:0213846 AUTH_NONE,
13847 OK,
13848 kSecureServer,
13849 AUTH_NONE,
13850 OK,
13851 1,
13852 0,
13853 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
13854 // Authenticating HTTPS server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3113855 {__LINE__,
13856 kProxy,
asankac93076192016-10-03 15:46:0213857 AUTH_NONE,
13858 OK,
13859 kSecureServer,
13860 AUTH_SYNC,
13861 OK,
13862 2,
13863 0,
13864 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513865 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113866 {__LINE__,
13867 kProxy,
asankac93076192016-10-03 15:46:0213868 AUTH_NONE,
13869 OK,
13870 kSecureServer,
13871 AUTH_SYNC,
13872 ERR_INVALID_AUTH_CREDENTIALS,
13873 2,
13874 0,
13875 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1613876 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113877 {__LINE__,
13878 kProxy,
asankac93076192016-10-03 15:46:0213879 AUTH_NONE,
13880 OK,
13881 kSecureServer,
13882 AUTH_ASYNC,
13883 OK,
13884 2,
13885 0,
13886 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513887 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113888 {__LINE__,
13889 kProxy,
asankac93076192016-10-03 15:46:0213890 AUTH_NONE,
13891 OK,
13892 kSecureServer,
13893 AUTH_ASYNC,
13894 ERR_INVALID_AUTH_CREDENTIALS,
13895 2,
13896 0,
13897 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1613898 TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213899 // Non-Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3113900 {__LINE__,
13901 kProxy,
asankac93076192016-10-03 15:46:0213902 AUTH_SYNC,
13903 OK,
13904 kSecureServer,
13905 AUTH_NONE,
13906 OK,
13907 2,
13908 1,
13909 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513910 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113911 {__LINE__,
13912 kProxy,
asankac93076192016-10-03 15:46:0213913 AUTH_SYNC,
13914 ERR_INVALID_AUTH_CREDENTIALS,
13915 kSecureServer,
13916 AUTH_NONE,
13917 OK,
13918 2,
13919 kNoSSL,
13920 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1613921 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113922 {__LINE__,
13923 kProxy,
asankae2257db2016-10-11 22:03:1613924 AUTH_SYNC,
13925 ERR_UNSUPPORTED_AUTH_SCHEME,
13926 kSecureServer,
13927 AUTH_NONE,
13928 OK,
13929 2,
13930 kNoSSL,
13931 {TestRound(kConnect, kProxyChallenge, OK),
13932 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113933 {__LINE__,
13934 kProxy,
asankae2257db2016-10-11 22:03:1613935 AUTH_SYNC,
13936 ERR_UNEXPECTED,
13937 kSecureServer,
13938 AUTH_NONE,
13939 OK,
13940 2,
13941 kNoSSL,
13942 {TestRound(kConnect, kProxyChallenge, OK),
13943 TestRound(kConnect, kProxyConnected, ERR_UNEXPECTED)}},
asanka463ca4262016-11-16 02:34:3113944 {__LINE__,
13945 kProxy,
asankac93076192016-10-03 15:46:0213946 AUTH_ASYNC,
13947 OK,
13948 kSecureServer,
13949 AUTH_NONE,
13950 OK,
13951 2,
13952 1,
13953 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513954 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113955 {__LINE__,
13956 kProxy,
asankac93076192016-10-03 15:46:0213957 AUTH_ASYNC,
13958 ERR_INVALID_AUTH_CREDENTIALS,
13959 kSecureServer,
13960 AUTH_NONE,
13961 OK,
13962 2,
13963 kNoSSL,
13964 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1613965 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asankac93076192016-10-03 15:46:0213966 // Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3113967 {__LINE__,
13968 kProxy,
asankac93076192016-10-03 15:46:0213969 AUTH_SYNC,
13970 OK,
13971 kSecureServer,
13972 AUTH_SYNC,
13973 OK,
13974 3,
13975 1,
13976 {TestRound(kConnect, kProxyChallenge, OK),
13977 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13978 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513979 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113980 {__LINE__,
13981 kProxy,
asankac93076192016-10-03 15:46:0213982 AUTH_SYNC,
13983 OK,
13984 kSecureServer,
13985 AUTH_SYNC,
13986 ERR_INVALID_AUTH_CREDENTIALS,
13987 3,
13988 1,
13989 {TestRound(kConnect, kProxyChallenge, OK),
13990 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13991 &kServerChallenge),
asankae2257db2016-10-11 22:03:1613992 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113993 {__LINE__,
13994 kProxy,
asankac93076192016-10-03 15:46:0213995 AUTH_ASYNC,
13996 OK,
13997 kSecureServer,
13998 AUTH_SYNC,
13999 OK,
14000 3,
14001 1,
14002 {TestRound(kConnect, kProxyChallenge, OK),
14003 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14004 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1514005 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114006 {__LINE__,
14007 kProxy,
asankac93076192016-10-03 15:46:0214008 AUTH_ASYNC,
14009 OK,
14010 kSecureServer,
14011 AUTH_SYNC,
14012 ERR_INVALID_AUTH_CREDENTIALS,
14013 3,
14014 1,
14015 {TestRound(kConnect, kProxyChallenge, OK),
14016 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14017 &kServerChallenge),
asankae2257db2016-10-11 22:03:1614018 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114019 {__LINE__,
14020 kProxy,
asankac93076192016-10-03 15:46:0214021 AUTH_SYNC,
14022 OK,
14023 kSecureServer,
14024 AUTH_ASYNC,
14025 OK,
14026 3,
14027 1,
14028 {TestRound(kConnect, kProxyChallenge, OK),
14029 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14030 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1514031 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114032 {__LINE__,
14033 kProxy,
asankac93076192016-10-03 15:46:0214034 AUTH_SYNC,
14035 OK,
14036 kSecureServer,
14037 AUTH_ASYNC,
14038 ERR_INVALID_AUTH_CREDENTIALS,
14039 3,
14040 1,
14041 {TestRound(kConnect, kProxyChallenge, OK),
14042 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14043 &kServerChallenge),
asankae2257db2016-10-11 22:03:1614044 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114045 {__LINE__,
14046 kProxy,
asankac93076192016-10-03 15:46:0214047 AUTH_ASYNC,
14048 OK,
14049 kSecureServer,
14050 AUTH_ASYNC,
14051 OK,
14052 3,
14053 1,
14054 {TestRound(kConnect, kProxyChallenge, OK),
14055 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14056 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1514057 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114058 {__LINE__,
14059 kProxy,
asankac93076192016-10-03 15:46:0214060 AUTH_ASYNC,
14061 OK,
14062 kSecureServer,
14063 AUTH_ASYNC,
14064 ERR_INVALID_AUTH_CREDENTIALS,
14065 3,
14066 1,
14067 {TestRound(kConnect, kProxyChallenge, OK),
14068 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14069 &kServerChallenge),
asankae2257db2016-10-11 22:03:1614070 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114071 {__LINE__,
14072 kProxy,
14073 AUTH_ASYNC,
14074 ERR_INVALID_AUTH_CREDENTIALS,
14075 kSecureServer,
14076 AUTH_ASYNC,
14077 ERR_INVALID_AUTH_CREDENTIALS,
14078 4,
14079 2,
14080 {TestRound(kConnect, kProxyChallenge, OK),
14081 TestRound(kConnect, kProxyChallenge, OK),
14082 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14083 &kServerChallenge),
14084 TestRound(kGet, kSuccess, OK)}},
[email protected]044de0642010-06-17 10:42:1514085 };
14086
asanka463ca4262016-11-16 02:34:3114087 for (const auto& test_config : test_configs) {
14088 SCOPED_TRACE(::testing::Message() << "Test config at "
14089 << test_config.line_number);
[email protected]2d01c262011-08-11 23:07:0814090 HttpAuthHandlerMock::Factory* auth_factory(
14091 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0714092 session_deps_.http_auth_handler_factory.reset(auth_factory);
asanka5ffd5d72016-03-23 16:20:4914093 SSLInfo empty_ssl_info;
[email protected]65d34382010-07-01 18:12:2614094
14095 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:1514096 if (test_config.proxy_auth_timing != AUTH_NONE) {
asanka463ca4262016-11-16 02:34:3114097 for (int n = 0; n < 3; n++) {
[email protected]2d01c262011-08-11 23:07:0814098 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
14099 std::string auth_challenge = "Mock realm=proxy";
14100 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:2414101 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
14102 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:0814103 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
tfarina42834112016-09-22 13:38:2014104 empty_ssl_info, origin,
14105 NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0814106 auth_handler->SetGenerateExpectation(
14107 test_config.proxy_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3114108 n == 0 ? test_config.first_generate_proxy_token_rv : OK);
[email protected]2d01c262011-08-11 23:07:0814109 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
14110 }
[email protected]044de0642010-06-17 10:42:1514111 }
14112 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:0014113 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:1514114 std::string auth_challenge = "Mock realm=server";
14115 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:2414116 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
14117 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:1514118 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2014119 empty_ssl_info, origin,
14120 NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1514121 auth_handler->SetGenerateExpectation(
14122 test_config.server_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3114123 test_config.first_generate_server_token_rv);
[email protected]2d01c262011-08-11 23:07:0814124 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
asankae2257db2016-10-11 22:03:1614125
14126 // The second handler always succeeds. It should only be used where there
14127 // are multiple auth sessions for server auth in the same network
14128 // transaction using the same auth scheme.
14129 std::unique_ptr<HttpAuthHandlerMock> second_handler =
Jeremy Roman0579ed62017-08-29 15:56:1914130 std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:1614131 second_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
14132 empty_ssl_info, origin,
14133 NetLogWithSource());
14134 second_handler->SetGenerateExpectation(true, OK);
14135 auth_factory->AddMockHandler(second_handler.release(),
14136 HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:1514137 }
14138 if (test_config.proxy_url) {
Lily Houghton8c2f97d2018-01-22 05:06:5914139 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4914140 ProxyResolutionService::CreateFixed(test_config.proxy_url,
14141 TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]044de0642010-06-17 10:42:1514142 } else {
Bence Béky53a5aef2018-03-29 21:54:1214143 session_deps_.proxy_resolution_service =
14144 ProxyResolutionService::CreateDirect();
[email protected]044de0642010-06-17 10:42:1514145 }
14146
14147 HttpRequestInfo request;
14148 request.method = "GET";
14149 request.url = GURL(test_config.server_url);
Ramin Halavatib5e433e2018-02-07 07:41:1014150 request.traffic_annotation =
14151 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]044de0642010-06-17 10:42:1514152
danakj1fd259a02016-04-16 03:17:0914153 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]044de0642010-06-17 10:42:1514154
rchcb68dc62015-05-21 04:45:3614155 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
14156
14157 std::vector<std::vector<MockRead>> mock_reads(1);
14158 std::vector<std::vector<MockWrite>> mock_writes(1);
[email protected]044de0642010-06-17 10:42:1514159 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2214160 SCOPED_TRACE(round);
[email protected]044de0642010-06-17 10:42:1514161 const TestRound& read_write_round = test_config.rounds[round];
14162
14163 // Set up expected reads and writes.
rchcb68dc62015-05-21 04:45:3614164 mock_reads.back().push_back(read_write_round.read);
14165 mock_writes.back().push_back(read_write_round.write);
14166
14167 // kProxyChallenge uses Proxy-Connection: close which means that the
14168 // socket is closed and a new one will be created for the next request.
mmenkee71e15332015-10-07 16:39:5414169 if (read_write_round.read.data == kProxyChallenge.data) {
rchcb68dc62015-05-21 04:45:3614170 mock_reads.push_back(std::vector<MockRead>());
14171 mock_writes.push_back(std::vector<MockWrite>());
[email protected]044de0642010-06-17 10:42:1514172 }
14173
rchcb68dc62015-05-21 04:45:3614174 if (read_write_round.extra_read) {
14175 mock_reads.back().push_back(*read_write_round.extra_read);
[email protected]044de0642010-06-17 10:42:1514176 }
rchcb68dc62015-05-21 04:45:3614177 if (read_write_round.extra_write) {
14178 mock_writes.back().push_back(*read_write_round.extra_write);
14179 }
[email protected]044de0642010-06-17 10:42:1514180
14181 // Add an SSL sequence if necessary.
[email protected]044de0642010-06-17 10:42:1514182 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0714183 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1514184 &ssl_socket_data_provider);
rchcb68dc62015-05-21 04:45:3614185 }
[email protected]044de0642010-06-17 10:42:1514186
danakj1fd259a02016-04-16 03:17:0914187 std::vector<std::unique_ptr<StaticSocketDataProvider>> data_providers;
rchcb68dc62015-05-21 04:45:3614188 for (size_t i = 0; i < mock_reads.size(); ++i) {
Jeremy Roman0579ed62017-08-29 15:56:1914189 data_providers.push_back(std::make_unique<StaticSocketDataProvider>(
Ryan Sleevib8d7ea02018-05-07 20:01:0114190 mock_reads[i], mock_writes[i]));
rchcb68dc62015-05-21 04:45:3614191 session_deps_.socket_factory->AddSocketDataProvider(
olli.raula525048c2015-12-10 07:38:3214192 data_providers.back().get());
rchcb68dc62015-05-21 04:45:3614193 }
14194
mmenkecc2298e2015-12-07 18:20:1814195 // Transaction must be created after DataProviders, so it's destroyed before
14196 // they are as well.
14197 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
14198
rchcb68dc62015-05-21 04:45:3614199 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2214200 SCOPED_TRACE(round);
rchcb68dc62015-05-21 04:45:3614201 const TestRound& read_write_round = test_config.rounds[round];
[email protected]044de0642010-06-17 10:42:1514202 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4114203 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1514204 int rv;
14205 if (round == 0) {
tfarina42834112016-09-22 13:38:2014206 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1514207 } else {
[email protected]49639fa2011-12-20 23:22:4114208 rv = trans.RestartWithAuth(
14209 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1514210 }
14211 if (rv == ERR_IO_PENDING)
14212 rv = callback.WaitForResult();
14213
14214 // Compare results with expected data.
asankae2257db2016-10-11 22:03:1614215 EXPECT_THAT(rv, IsError(read_write_round.expected_rv));
[email protected]0b0bf032010-09-21 18:08:5014216 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttlec0c828492015-05-15 01:25:5514217 if (read_write_round.expected_rv != OK) {
[email protected]044de0642010-06-17 10:42:1514218 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
14219 continue;
14220 }
14221 if (round + 1 < test_config.num_auth_rounds) {
wezca1070932016-05-26 20:30:5214222 EXPECT_TRUE(response->auth_challenge);
[email protected]044de0642010-06-17 10:42:1514223 } else {
wezca1070932016-05-26 20:30:5214224 EXPECT_FALSE(response->auth_challenge);
asankae2257db2016-10-11 22:03:1614225 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]044de0642010-06-17 10:42:1514226 }
14227 }
[email protected]e5ae96a2010-04-14 20:12:4514228 }
14229}
14230
bncd16676a2016-07-20 16:23:0114231TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1414232 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1414233 HttpAuthHandlerMock::Factory* auth_factory(
14234 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0714235 session_deps_.http_auth_handler_factory.reset(auth_factory);
Bence Béky53a5aef2018-03-29 21:54:1214236 session_deps_.proxy_resolution_service =
14237 ProxyResolutionService::CreateDirect();
[email protected]bb88e1d32013-05-03 23:11:0714238 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
[email protected]c871bce92010-07-15 21:51:1414239
14240 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
14241 auth_handler->set_connection_based(true);
14242 std::string auth_challenge = "Mock realm=server";
14243 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2414244 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
14245 auth_challenge.end());
asanka5ffd5d72016-03-23 16:20:4914246 SSLInfo empty_ssl_info;
[email protected]c871bce92010-07-15 21:51:1414247 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2014248 empty_ssl_info, origin, NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0814249 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1414250
[email protected]c871bce92010-07-15 21:51:1414251 int rv = OK;
14252 const HttpResponseInfo* response = NULL;
14253 HttpRequestInfo request;
14254 request.method = "GET";
14255 request.url = origin;
Ramin Halavatib5e433e2018-02-07 07:41:1014256 request.traffic_annotation =
14257 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2714258
danakj1fd259a02016-04-16 03:17:0914259 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1014260
14261 // Use a TCP Socket Pool with only one connection per group. This is used
14262 // to validate that the TCP socket is not released to the pool between
14263 // each round of multi-round authentication.
mmenkee65e7af2015-10-13 17:16:4214264 HttpNetworkSessionPeer session_peer(session.get());
[email protected]ab739042011-04-07 15:22:2814265 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
Tarun Bansala7635092019-02-20 10:00:5914266 50, // Max sockets for pool
14267 1, // Max sockets per group
14268 base::TimeDelta::FromSeconds(10), // unused_idle_socket_timeout
Matt Menkecb77b5402019-01-28 17:11:2314269 session_deps_.socket_factory.get(), session_deps_.host_resolver.get(),
Matt Menke1751ba72019-02-09 02:23:4614270 nullptr /* proxy_delegate */, session_deps_.cert_verifier.get(),
14271 session_deps_.channel_id_service.get(),
Matt Menkecb77b5402019-01-28 17:11:2314272 session_deps_.transport_security_state.get(),
14273 session_deps_.cert_transparency_verifier.get(),
14274 session_deps_.ct_policy_enforcer.get(),
Matt Menkec94d97b2019-02-01 19:28:2814275 nullptr /* ssl_client_session_cache */,
Daniel McArdleda3fa942019-02-15 16:41:2114276 nullptr /* ssl_client_session_cache_privacy_mode */,
Matt Menkefa9574f2019-01-28 18:55:2714277 session_deps_.ssl_config_service.get(),
Matt Menkecb77b5402019-01-28 17:11:2314278 nullptr /* socket_performance_watcher_factory */,
14279 nullptr /* network_quality_estimator */, session_deps_.net_log);
Jeremy Roman0579ed62017-08-29 15:56:1914280 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
[email protected]a42dbd142011-11-17 16:42:0214281 mock_pool_manager->SetTransportSocketPool(transport_pool);
dchengc7eeda422015-12-26 03:56:4814282 session_peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]7ef4cbbb2011-02-06 11:19:1014283
bnc691fda62016-08-12 00:43:1614284 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4114285 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1414286
14287 const MockWrite kGet(
14288 "GET / HTTP/1.1\r\n"
14289 "Host: www.example.com\r\n"
14290 "Connection: keep-alive\r\n\r\n");
14291 const MockWrite kGetAuth(
14292 "GET / HTTP/1.1\r\n"
14293 "Host: www.example.com\r\n"
14294 "Connection: keep-alive\r\n"
14295 "Authorization: auth_token\r\n\r\n");
14296
14297 const MockRead kServerChallenge(
14298 "HTTP/1.1 401 Unauthorized\r\n"
14299 "WWW-Authenticate: Mock realm=server\r\n"
14300 "Content-Type: text/html; charset=iso-8859-1\r\n"
14301 "Content-Length: 14\r\n\r\n"
14302 "Unauthorized\r\n");
14303 const MockRead kSuccess(
14304 "HTTP/1.1 200 OK\r\n"
14305 "Content-Type: text/html; charset=iso-8859-1\r\n"
14306 "Content-Length: 3\r\n\r\n"
14307 "Yes");
14308
14309 MockWrite writes[] = {
14310 // First round
14311 kGet,
14312 // Second round
14313 kGetAuth,
14314 // Third round
14315 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3014316 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1014317 kGetAuth,
14318 // Competing request
14319 kGet,
[email protected]c871bce92010-07-15 21:51:1414320 };
14321 MockRead reads[] = {
14322 // First round
14323 kServerChallenge,
14324 // Second round
14325 kServerChallenge,
14326 // Third round
[email protected]eca50e122010-09-11 14:03:3014327 kServerChallenge,
14328 // Fourth round
[email protected]c871bce92010-07-15 21:51:1414329 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1014330 // Competing response
14331 kSuccess,
[email protected]c871bce92010-07-15 21:51:1414332 };
Ryan Sleevib8d7ea02018-05-07 20:01:0114333 StaticSocketDataProvider data_provider(reads, writes);
[email protected]bb88e1d32013-05-03 23:11:0714334 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1414335
thestig9d3bb0c2015-01-24 00:49:5114336 const char kSocketGroup[] = "www.example.com:80";
[email protected]7ef4cbbb2011-02-06 11:19:1014337
14338 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1414339 auth_handler->SetGenerateExpectation(false, OK);
tfarina42834112016-09-22 13:38:2014340 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]c871bce92010-07-15 21:51:1414341 if (rv == ERR_IO_PENDING)
14342 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114343 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1614344 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214345 ASSERT_TRUE(response);
14346 EXPECT_TRUE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2814347 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3114348 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
14349 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1414350
[email protected]7ef4cbbb2011-02-06 11:19:1014351 // In between rounds, another request comes in for the same domain.
14352 // It should not be able to grab the TCP socket that trans has already
14353 // claimed.
bnc691fda62016-08-12 00:43:1614354 HttpNetworkTransaction trans_compete(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4114355 TestCompletionCallback callback_compete;
tfarina42834112016-09-22 13:38:2014356 rv = trans_compete.Start(&request, callback_compete.callback(),
14357 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114358 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7ef4cbbb2011-02-06 11:19:1014359 // callback_compete.WaitForResult at this point would stall forever,
14360 // since the HttpNetworkTransaction does not release the request back to
14361 // the pool until after authentication completes.
14362
14363 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1414364 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1614365 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1414366 if (rv == ERR_IO_PENDING)
14367 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114368 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1614369 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214370 ASSERT_TRUE(response);
14371 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2814372 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3114373 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
14374 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1414375
[email protected]7ef4cbbb2011-02-06 11:19:1014376 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1414377 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1614378 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1414379 if (rv == ERR_IO_PENDING)
14380 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114381 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1614382 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214383 ASSERT_TRUE(response);
14384 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2814385 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3114386 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
14387 auth_handler->state());
[email protected]eca50e122010-09-11 14:03:3014388
[email protected]7ef4cbbb2011-02-06 11:19:1014389 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3014390 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1614391 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3014392 if (rv == ERR_IO_PENDING)
14393 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114394 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1614395 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214396 ASSERT_TRUE(response);
14397 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2814398 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1014399
asanka463ca4262016-11-16 02:34:3114400 // In WAIT_FOR_CHALLENGE, although in reality the auth handler is done. A real
14401 // auth handler should transition to a DONE state in concert with the remote
14402 // server. But that's not something we can test here with a mock handler.
14403 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_CHALLENGE,
14404 auth_handler->state());
14405
[email protected]7ef4cbbb2011-02-06 11:19:1014406 // Read the body since the fourth round was successful. This will also
14407 // release the socket back to the pool.
Victor Costan9c7302b2018-08-27 16:39:4414408 scoped_refptr<IOBufferWithSize> io_buf =
14409 base::MakeRefCounted<IOBufferWithSize>(50);
bnc691fda62016-08-12 00:43:1614410 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1014411 if (rv == ERR_IO_PENDING)
14412 rv = callback.WaitForResult();
14413 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1614414 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1014415 EXPECT_EQ(0, rv);
14416 // There are still 0 idle sockets, since the trans_compete transaction
14417 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:2814418 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1014419
14420 // The competing request can now finish. Wait for the headers and then
14421 // read the body.
14422 rv = callback_compete.WaitForResult();
robpercival214763f2016-07-01 23:27:0114423 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1614424 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1014425 if (rv == ERR_IO_PENDING)
14426 rv = callback.WaitForResult();
14427 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1614428 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1014429 EXPECT_EQ(0, rv);
14430
14431 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:2814432 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1414433}
14434
[email protected]65041fa2010-05-21 06:56:5314435// This tests the case that a request is issued via http instead of spdy after
14436// npn is negotiated.
bncd16676a2016-07-20 16:23:0114437TEST_F(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]65041fa2010-05-21 06:56:5314438 HttpRequestInfo request;
14439 request.method = "GET";
bncce36dca22015-04-21 22:11:2314440 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1014441 request.traffic_annotation =
14442 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]65041fa2010-05-21 06:56:5314443
14444 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2314445 MockWrite(
14446 "GET / HTTP/1.1\r\n"
14447 "Host: www.example.org\r\n"
14448 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5314449 };
14450
14451 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5214452 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4314453 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5214454 MockRead("\r\n"),
14455 MockRead("hello world"),
14456 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5314457 };
14458
[email protected]8ddf8322012-02-23 18:08:0614459 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614460 ssl.next_proto = kProtoHTTP11;
[email protected]65041fa2010-05-21 06:56:5314461
[email protected]bb88e1d32013-05-03 23:11:0714462 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5314463
Ryan Sleevib8d7ea02018-05-07 20:01:0114464 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0714465 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5314466
[email protected]49639fa2011-12-20 23:22:4114467 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5314468
danakj1fd259a02016-04-16 03:17:0914469 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614470 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]65041fa2010-05-21 06:56:5314471
tfarina42834112016-09-22 13:38:2014472 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]65041fa2010-05-21 06:56:5314473
robpercival214763f2016-07-01 23:27:0114474 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14475 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]65041fa2010-05-21 06:56:5314476
bnc691fda62016-08-12 00:43:1614477 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214478 ASSERT_TRUE(response);
14479 ASSERT_TRUE(response->headers);
[email protected]65041fa2010-05-21 06:56:5314480 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
14481
14482 std::string response_data;
bnc691fda62016-08-12 00:43:1614483 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]65041fa2010-05-21 06:56:5314484 EXPECT_EQ("hello world", response_data);
14485
14486 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214487 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]65041fa2010-05-21 06:56:5314488}
[email protected]26ef6582010-06-24 02:30:4714489
bnc55ff9da2015-08-19 18:42:3514490// Simulate the SSL handshake completing with an NPN negotiation followed by an
14491// immediate server closing of the socket.
14492// Regression test for https://crbug.com/46369.
bncd16676a2016-07-20 16:23:0114493TEST_F(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:4714494 HttpRequestInfo request;
14495 request.method = "GET";
bncce36dca22015-04-21 22:11:2314496 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1014497 request.traffic_annotation =
14498 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]26ef6582010-06-24 02:30:4714499
[email protected]8ddf8322012-02-23 18:08:0614500 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614501 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0714502 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4714503
Ryan Hamilton0239aac2018-05-19 00:03:1314504 spdy::SpdySerializedFrame req(
14505 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4114506 MockWrite spdy_writes[] = {CreateMockWrite(req, 1)};
[email protected]26ef6582010-06-24 02:30:4714507
14508 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0614509 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4714510 };
14511
Ryan Sleevib8d7ea02018-05-07 20:01:0114512 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0714513 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4714514
[email protected]49639fa2011-12-20 23:22:4114515 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4714516
danakj1fd259a02016-04-16 03:17:0914517 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614518 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]26ef6582010-06-24 02:30:4714519
tfarina42834112016-09-22 13:38:2014520 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114521 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14522 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]26ef6582010-06-24 02:30:4714523}
[email protected]65d34382010-07-01 18:12:2614524
[email protected]795cbf82013-07-22 09:37:2714525// A subclass of HttpAuthHandlerMock that records the request URL when
14526// it gets it. This is needed since the auth handler may get destroyed
14527// before we get a chance to query it.
14528class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
14529 public:
14530 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
14531
Chris Watkins7a41d3552017-12-01 02:13:2714532 ~UrlRecordingHttpAuthHandlerMock() override = default;
[email protected]795cbf82013-07-22 09:37:2714533
14534 protected:
dchengb03027d2014-10-21 12:00:2014535 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
14536 const HttpRequestInfo* request,
Bence Béky7236fb72018-08-01 14:35:0914537 CompletionOnceCallback callback,
dchengb03027d2014-10-21 12:00:2014538 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2714539 *url_ = request->url;
14540 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
Bence Béky7236fb72018-08-01 14:35:0914541 credentials, request, std::move(callback), auth_token);
[email protected]795cbf82013-07-22 09:37:2714542 }
14543
14544 private:
14545 GURL* url_;
14546};
14547
[email protected]8e6441ca2010-08-19 05:56:3814548// Test that if we cancel the transaction as the connection is completing, that
14549// everything tears down correctly.
bncd16676a2016-07-20 16:23:0114550TEST_F(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3814551 // Setup everything about the connection to complete synchronously, so that
14552 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
14553 // for is the callback from the HttpStreamRequest.
14554 // Then cancel the transaction.
14555 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3614556 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3814557 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0614558 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
14559 MockRead(SYNCHRONOUS, "hello world"),
14560 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3814561 };
14562
[email protected]8e6441ca2010-08-19 05:56:3814563 HttpRequestInfo request;
14564 request.method = "GET";
bncce36dca22015-04-21 22:11:2314565 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1014566 request.traffic_annotation =
14567 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8e6441ca2010-08-19 05:56:3814568
danakj1fd259a02016-04-16 03:17:0914569 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5814570 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1914571 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2714572
Ryan Sleevib8d7ea02018-05-07 20:01:0114573 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]8e6441ca2010-08-19 05:56:3814574 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0714575 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3814576
[email protected]49639fa2011-12-20 23:22:4114577 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3814578
vishal.b62985ca92015-04-17 08:45:5114579 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4114580 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114581 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8e6441ca2010-08-19 05:56:3814582 trans.reset(); // Cancel the transaction here.
14583
fdoray92e35a72016-06-10 15:54:5514584 base::RunLoop().RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3014585}
14586
[email protected]ecab6e052014-05-16 14:58:1214587// Test that if a transaction is cancelled after receiving the headers, the
14588// stream is drained properly and added back to the socket pool. The main
14589// purpose of this test is to make sure that an HttpStreamParser can be read
14590// from after the HttpNetworkTransaction and the objects it owns have been
14591// deleted.
14592// See http://crbug.com/368418
bncd16676a2016-07-20 16:23:0114593TEST_F(HttpNetworkTransactionTest, CancelAfterHeaders) {
[email protected]ecab6e052014-05-16 14:58:1214594 MockRead data_reads[] = {
14595 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
14596 MockRead(ASYNC, "Content-Length: 2\r\n"),
14597 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
14598 MockRead(ASYNC, "1"),
14599 // 2 async reads are necessary to trigger a ReadResponseBody call after the
14600 // HttpNetworkTransaction has been deleted.
14601 MockRead(ASYNC, "2"),
14602 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
14603 };
Ryan Sleevib8d7ea02018-05-07 20:01:0114604 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]ecab6e052014-05-16 14:58:1214605 session_deps_.socket_factory->AddSocketDataProvider(&data);
14606
danakj1fd259a02016-04-16 03:17:0914607 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]ecab6e052014-05-16 14:58:1214608
14609 {
14610 HttpRequestInfo request;
14611 request.method = "GET";
bncce36dca22015-04-21 22:11:2314612 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1014613 request.traffic_annotation =
14614 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ecab6e052014-05-16 14:58:1214615
dcheng48459ac22014-08-26 00:46:4114616 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1214617 TestCompletionCallback callback;
14618
tfarina42834112016-09-22 13:38:2014619 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114620 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ecab6e052014-05-16 14:58:1214621 callback.WaitForResult();
14622
14623 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214624 ASSERT_TRUE(response);
14625 EXPECT_TRUE(response->headers);
[email protected]ecab6e052014-05-16 14:58:1214626 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
14627
14628 // The transaction and HttpRequestInfo are deleted.
14629 }
14630
14631 // Let the HttpResponseBodyDrainer drain the socket.
fdoray92e35a72016-06-10 15:54:5514632 base::RunLoop().RunUntilIdle();
[email protected]ecab6e052014-05-16 14:58:1214633
14634 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4114635 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1214636}
14637
[email protected]76a505b2010-08-25 06:23:0014638// Test a basic GET request through a proxy.
bncd16676a2016-07-20 16:23:0114639TEST_F(HttpNetworkTransactionTest, ProxyGet) {
Lily Houghton8c2f97d2018-01-22 05:06:5914640 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4914641 ProxyResolutionService::CreateFixedFromPacResult(
14642 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5114643 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714644 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0914645 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0014646
[email protected]76a505b2010-08-25 06:23:0014647 HttpRequestInfo request;
14648 request.method = "GET";
bncce36dca22015-04-21 22:11:2314649 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1014650 request.traffic_annotation =
14651 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0014652
14653 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2314654 MockWrite(
14655 "GET http://www.example.org/ HTTP/1.1\r\n"
14656 "Host: www.example.org\r\n"
14657 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014658 };
14659
14660 MockRead data_reads1[] = {
14661 MockRead("HTTP/1.1 200 OK\r\n"),
14662 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14663 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0614664 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0014665 };
14666
Ryan Sleevib8d7ea02018-05-07 20:01:0114667 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:0714668 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0014669
[email protected]49639fa2011-12-20 23:22:4114670 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0014671
bnc691fda62016-08-12 00:43:1614672 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0914673 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1614674 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0914675 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
14676 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5014677
bnc691fda62016-08-12 00:43:1614678 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114679 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0014680
14681 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0114682 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:0014683
bnc691fda62016-08-12 00:43:1614684 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214685 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0014686
14687 EXPECT_TRUE(response->headers->IsKeepAlive());
14688 EXPECT_EQ(200, response->headers->response_code());
14689 EXPECT_EQ(100, response->headers->GetContentLength());
14690 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4714691 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
14692 HostPortPair::FromString("myproxy:70")),
14693 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0914694 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
14695 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
14696 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0014697 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2014698
14699 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1614700 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2014701 TestLoadTimingNotReusedWithPac(load_timing_info,
14702 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0014703}
14704
14705// Test a basic HTTPS GET request through a proxy.
bncd16676a2016-07-20 16:23:0114706TEST_F(HttpNetworkTransactionTest, ProxyTunnelGet) {
Lily Houghton8c2f97d2018-01-22 05:06:5914707 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4914708 ProxyResolutionService::CreateFixedFromPacResult(
14709 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5114710 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714711 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0914712 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0014713
[email protected]76a505b2010-08-25 06:23:0014714 HttpRequestInfo request;
14715 request.method = "GET";
bncce36dca22015-04-21 22:11:2314716 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1014717 request.traffic_annotation =
14718 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0014719
14720 // Since we have proxy, should try to establish tunnel.
14721 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1714722 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
14723 "Host: www.example.org:443\r\n"
14724 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014725
rsleevidb16bb02015-11-12 23:47:1714726 MockWrite("GET / HTTP/1.1\r\n"
14727 "Host: www.example.org\r\n"
14728 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014729 };
14730
14731 MockRead data_reads1[] = {
14732 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
14733
14734 MockRead("HTTP/1.1 200 OK\r\n"),
14735 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14736 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0614737 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0014738 };
14739
Ryan Sleevib8d7ea02018-05-07 20:01:0114740 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:0714741 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0614742 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0714743 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0014744
[email protected]49639fa2011-12-20 23:22:4114745 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0014746
bnc691fda62016-08-12 00:43:1614747 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0914748 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1614749 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0914750 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
14751 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5014752
bnc691fda62016-08-12 00:43:1614753 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114754 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0014755
14756 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0114757 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:4614758 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4014759 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0014760 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014761 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
14762 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0014763 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4014764 entries, pos,
mikecirone8b85c432016-09-08 19:11:0014765 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
14766 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0014767
bnc691fda62016-08-12 00:43:1614768 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214769 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0014770
14771 EXPECT_TRUE(response->headers->IsKeepAlive());
14772 EXPECT_EQ(200, response->headers->response_code());
14773 EXPECT_EQ(100, response->headers->GetContentLength());
14774 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
14775 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4714776 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
14777 HostPortPair::FromString("myproxy:70")),
14778 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0914779 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
14780 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
14781 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]029c83b62013-01-24 05:28:2014782
14783 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1614784 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2014785 TestLoadTimingNotReusedWithPac(load_timing_info,
14786 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0014787}
14788
rsleevidb16bb02015-11-12 23:47:1714789// Test a basic HTTPS GET request through a proxy, connecting to an IPv6
14790// literal host.
bncd16676a2016-07-20 16:23:0114791TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetIPv6) {
Lily Houghton8c2f97d2018-01-22 05:06:5914792 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4914793 ProxyResolutionService::CreateFixedFromPacResult(
14794 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
rsleevidb16bb02015-11-12 23:47:1714795 BoundTestNetLog log;
14796 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0914797 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
rsleevidb16bb02015-11-12 23:47:1714798
14799 HttpRequestInfo request;
14800 request.method = "GET";
Eric Romanda790f92018-11-07 19:17:1514801 request.url = GURL("https://[::2]:443/");
Ramin Halavatib5e433e2018-02-07 07:41:1014802 request.traffic_annotation =
14803 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rsleevidb16bb02015-11-12 23:47:1714804
14805 // Since we have proxy, should try to establish tunnel.
14806 MockWrite data_writes1[] = {
Eric Romanda790f92018-11-07 19:17:1514807 MockWrite("CONNECT [::2]:443 HTTP/1.1\r\n"
14808 "Host: [::2]:443\r\n"
rsleevidb16bb02015-11-12 23:47:1714809 "Proxy-Connection: keep-alive\r\n\r\n"),
14810
14811 MockWrite("GET / HTTP/1.1\r\n"
Eric Romanda790f92018-11-07 19:17:1514812 "Host: [::2]\r\n"
rsleevidb16bb02015-11-12 23:47:1714813 "Connection: keep-alive\r\n\r\n"),
14814 };
14815
14816 MockRead data_reads1[] = {
14817 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
14818
14819 MockRead("HTTP/1.1 200 OK\r\n"),
14820 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14821 MockRead("Content-Length: 100\r\n\r\n"),
14822 MockRead(SYNCHRONOUS, OK),
14823 };
14824
Ryan Sleevib8d7ea02018-05-07 20:01:0114825 StaticSocketDataProvider data1(data_reads1, data_writes1);
rsleevidb16bb02015-11-12 23:47:1714826 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14827 SSLSocketDataProvider ssl(ASYNC, OK);
14828 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14829
14830 TestCompletionCallback callback1;
14831
bnc691fda62016-08-12 00:43:1614832 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
rsleevidb16bb02015-11-12 23:47:1714833
bnc691fda62016-08-12 00:43:1614834 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114835 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rsleevidb16bb02015-11-12 23:47:1714836
14837 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0114838 EXPECT_THAT(rv, IsOk());
rsleevidb16bb02015-11-12 23:47:1714839 TestNetLogEntry::List entries;
14840 log.GetEntries(&entries);
14841 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014842 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
14843 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1714844 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014845 entries, pos,
14846 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
14847 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1714848
bnc691fda62016-08-12 00:43:1614849 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214850 ASSERT_TRUE(response);
rsleevidb16bb02015-11-12 23:47:1714851
14852 EXPECT_TRUE(response->headers->IsKeepAlive());
14853 EXPECT_EQ(200, response->headers->response_code());
14854 EXPECT_EQ(100, response->headers->GetContentLength());
14855 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
14856 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4714857 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
14858 HostPortPair::FromString("myproxy:70")),
14859 response->proxy_server);
rsleevidb16bb02015-11-12 23:47:1714860
14861 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1614862 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
rsleevidb16bb02015-11-12 23:47:1714863 TestLoadTimingNotReusedWithPac(load_timing_info,
14864 CONNECT_TIMING_HAS_SSL_TIMES);
14865}
14866
[email protected]76a505b2010-08-25 06:23:0014867// Test a basic HTTPS GET request through a proxy, but the server hangs up
14868// while establishing the tunnel.
bncd16676a2016-07-20 16:23:0114869TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
Ramin Halavatica8d5252018-03-12 05:33:4914870 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
14871 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5114872 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714873 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0914874 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0014875
[email protected]76a505b2010-08-25 06:23:0014876 HttpRequestInfo request;
14877 request.method = "GET";
bncce36dca22015-04-21 22:11:2314878 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1014879 request.traffic_annotation =
14880 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0014881
14882 // Since we have proxy, should try to establish tunnel.
14883 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1714884 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
14885 "Host: www.example.org:443\r\n"
14886 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014887
rsleevidb16bb02015-11-12 23:47:1714888 MockWrite("GET / HTTP/1.1\r\n"
14889 "Host: www.example.org\r\n"
14890 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014891 };
14892
14893 MockRead data_reads1[] = {
[email protected]76a505b2010-08-25 06:23:0014894 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0614895 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0014896 };
14897
Ryan Sleevib8d7ea02018-05-07 20:01:0114898 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:0714899 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0614900 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0714901 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0014902
[email protected]49639fa2011-12-20 23:22:4114903 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0014904
bnc691fda62016-08-12 00:43:1614905 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5014906
bnc691fda62016-08-12 00:43:1614907 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114908 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0014909
14910 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0114911 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
mmenke43758e62015-05-04 21:09:4614912 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4014913 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0014914 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014915 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
14916 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0014917 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4014918 entries, pos,
mikecirone8b85c432016-09-08 19:11:0014919 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
14920 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0014921}
14922
[email protected]749eefa82010-09-13 22:14:0314923// Test for crbug.com/55424.
bncd16676a2016-07-20 16:23:0114924TEST_F(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
Ryan Hamilton0239aac2018-05-19 00:03:1314925 spdy::SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4914926 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4114927 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]749eefa82010-09-13 22:14:0314928
Ryan Hamilton0239aac2018-05-19 00:03:1314929 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
14930 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0314931 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114932 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0314933 };
14934
Ryan Sleevib8d7ea02018-05-07 20:01:0114935 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0714936 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0314937
[email protected]8ddf8322012-02-23 18:08:0614938 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614939 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0714940 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0314941
danakj1fd259a02016-04-16 03:17:0914942 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0314943
14944 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2314945 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4014946 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
Matt Menke2436b2f2018-12-11 18:07:1114947 PRIVACY_MODE_DISABLED,
14948 SpdySessionKey::IsProxySession::kFalse, SocketTag());
[email protected]795cbf82013-07-22 09:37:2714949 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:5214950 CreateSpdySession(session.get(), key, NetLogWithSource());
[email protected]749eefa82010-09-13 22:14:0314951
14952 HttpRequestInfo request;
14953 request.method = "GET";
bncce36dca22015-04-21 22:11:2314954 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1014955 request.traffic_annotation =
14956 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]749eefa82010-09-13 22:14:0314957
bnc691fda62016-08-12 00:43:1614958 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]749eefa82010-09-13 22:14:0314959
[email protected]41d64e82013-07-03 22:44:2614960 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014961 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114962 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14963 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]749eefa82010-09-13 22:14:0314964}
14965
[email protected]73b8dd222010-11-11 19:55:2414966// Given a net error, cause that error to be returned from the first Write()
bnc691fda62016-08-12 00:43:1614967// call and verify that the HttpNetworkTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0214968void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0714969 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2914970 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2714971 request_info.url = GURL("https://www.example.com/");
14972 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914973 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:1014974 request_info.traffic_annotation =
14975 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2714976
[email protected]8ddf8322012-02-23 18:08:0614977 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2914978 MockWrite data_writes[] = {
14979 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2414980 };
Ryan Sleevib8d7ea02018-05-07 20:01:0114981 StaticSocketDataProvider data(base::span<MockRead>(), data_writes);
[email protected]bb88e1d32013-05-03 23:11:0714982 session_deps_.socket_factory->AddSocketDataProvider(&data);
14983 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2414984
danakj1fd259a02016-04-16 03:17:0914985 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614986 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]73b8dd222010-11-11 19:55:2414987
[email protected]49639fa2011-12-20 23:22:4114988 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014989 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
ttuttle859dc7a2015-04-23 19:42:2914990 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2414991 rv = callback.WaitForResult();
14992 ASSERT_EQ(error, rv);
14993}
14994
bncd16676a2016-07-20 16:23:0114995TEST_F(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2414996 // Just check a grab bag of cert errors.
14997 static const int kErrors[] = {
14998 ERR_CERT_COMMON_NAME_INVALID,
14999 ERR_CERT_AUTHORITY_INVALID,
15000 ERR_CERT_DATE_INVALID,
15001 };
Avi Drissman4365a4782018-12-28 19:26:2415002 for (size_t i = 0; i < base::size(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0615003 CheckErrorIsPassedBack(kErrors[i], ASYNC);
15004 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2415005 }
15006}
15007
[email protected]bd0b6772011-01-11 19:59:3015008// Ensure that a client certificate is removed from the SSL client auth
15009// cache when:
15010// 1) No proxy is involved.
15011// 2) TLS False Start is disabled.
15012// 3) The initial TLS handshake requests a client certificate.
15013// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0115014TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_NoFalseStart) {
ttuttle859dc7a2015-04-23 19:42:2915015 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2715016 request_info.url = GURL("https://www.example.com/");
15017 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2915018 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:1015019 request_info.traffic_annotation =
15020 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2715021
[email protected]bd0b6772011-01-11 19:59:3015022 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4115023 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3015024
15025 // [ssl_]data1 contains the data for the first SSL handshake. When a
15026 // CertificateRequest is received for the first time, the handshake will
15027 // be aborted to allow the caller to provide a certificate.
ttuttle859dc7a2015-04-23 19:42:2915028 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3015029 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715030 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
Ryan Sleevib8d7ea02018-05-07 20:01:0115031 StaticSocketDataProvider data1;
[email protected]bb88e1d32013-05-03 23:11:0715032 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3015033
15034 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
15035 // False Start is not being used, the result of the SSL handshake will be
15036 // returned as part of the SSLClientSocket::Connect() call. This test
15037 // matches the result of a server sending a handshake_failure alert,
15038 // rather than a Finished message, because it requires a client
15039 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2915040 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3015041 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715042 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
Ryan Sleevib8d7ea02018-05-07 20:01:0115043 StaticSocketDataProvider data2;
[email protected]bb88e1d32013-05-03 23:11:0715044 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3015045
15046 // [ssl_]data3 contains the data for the third SSL handshake. When a
15047 // connection to a server fails during an SSL handshake,
Steven Valdez0ef94d02018-11-19 23:28:1315048 // HttpNetworkTransaction will attempt to fallback to TLSv1.2 if the previous
15049 // connection was attempted with TLSv1.3. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3015050 // of the HttpNetworkTransaction. Because this test failure is due to
15051 // requiring a client certificate, this fallback handshake should also
15052 // fail.
ttuttle859dc7a2015-04-23 19:42:2915053 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
Steven Valdez0ef94d02018-11-19 23:28:1315054 ssl_data3.expected_ssl_version_max = SSL_PROTOCOL_VERSION_TLS1_2;
[email protected]bd0b6772011-01-11 19:59:3015055 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715056 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
Ryan Sleevib8d7ea02018-05-07 20:01:0115057 StaticSocketDataProvider data3;
[email protected]bb88e1d32013-05-03 23:11:0715058 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3015059
[email protected]80c75f682012-05-26 16:22:1715060 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
15061 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4215062 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
15063 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]80c75f682012-05-26 16:22:1715064 // of the HttpNetworkTransaction. Because this test failure is due to
15065 // requiring a client certificate, this fallback handshake should also
15066 // fail.
ttuttle859dc7a2015-04-23 19:42:2915067 SSLSocketDataProvider ssl_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1715068 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715069 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
Ryan Sleevib8d7ea02018-05-07 20:01:0115070 StaticSocketDataProvider data4;
[email protected]bb88e1d32013-05-03 23:11:0715071 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1715072
danakj1fd259a02016-04-16 03:17:0915073 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615074 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3015075
[email protected]bd0b6772011-01-11 19:59:3015076 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4115077 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2015078 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115079 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3015080
15081 // Complete the SSL handshake, which should abort due to requiring a
15082 // client certificate.
15083 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115084 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3015085
15086 // Indicate that no certificate should be supplied. From the perspective
15087 // of SSLClientCertCache, NULL is just as meaningful as a real
15088 // certificate, so this is the same as supply a
15089 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1615090 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0115091 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3015092
15093 // Ensure the certificate was added to the client auth cache before
15094 // allowing the connection to continue restarting.
15095 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5415096 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4115097 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415098 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5215099 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3015100
15101 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1715102 // then consume ssl_data3 and ssl_data4, both of which should also fail.
15103 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3015104 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115105 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3015106
15107 // Ensure that the client certificate is removed from the cache on a
15108 // handshake failure.
[email protected]791879c2013-12-17 07:22:4115109 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415110 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3015111}
15112
15113// Ensure that a client certificate is removed from the SSL client auth
15114// cache when:
15115// 1) No proxy is involved.
15116// 2) TLS False Start is enabled.
15117// 3) The initial TLS handshake requests a client certificate.
15118// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0115119TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2915120 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2715121 request_info.url = GURL("https://www.example.com/");
15122 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2915123 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:1015124 request_info.traffic_annotation =
15125 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2715126
[email protected]bd0b6772011-01-11 19:59:3015127 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4115128 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3015129
15130 // When TLS False Start is used, SSLClientSocket::Connect() calls will
15131 // return successfully after reading up to the peer's Certificate message.
15132 // This is to allow the caller to call SSLClientSocket::Write(), which can
15133 // enqueue application data to be sent in the same packet as the
15134 // ChangeCipherSpec and Finished messages.
15135 // The actual handshake will be finished when SSLClientSocket::Read() is
15136 // called, which expects to process the peer's ChangeCipherSpec and
15137 // Finished messages. If there was an error negotiating with the peer,
15138 // such as due to the peer requiring a client certificate when none was
15139 // supplied, the alert sent by the peer won't be processed until Read() is
15140 // called.
15141
15142 // Like the non-False Start case, when a client certificate is requested by
15143 // the peer, the handshake is aborted during the Connect() call.
15144 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2915145 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3015146 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715147 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
Ryan Sleevib8d7ea02018-05-07 20:01:0115148 StaticSocketDataProvider data1;
[email protected]bb88e1d32013-05-03 23:11:0715149 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3015150
15151 // When a client certificate is supplied, Connect() will not be aborted
15152 // when the peer requests the certificate. Instead, the handshake will
15153 // artificially succeed, allowing the caller to write the HTTP request to
15154 // the socket. The handshake messages are not processed until Read() is
15155 // called, which then detects that the handshake was aborted, due to the
15156 // peer sending a handshake_failure because it requires a client
15157 // certificate.
ttuttle859dc7a2015-04-23 19:42:2915158 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3015159 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715160 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2915161 MockRead data2_reads[] = {
15162 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3015163 };
Ryan Sleevib8d7ea02018-05-07 20:01:0115164 StaticSocketDataProvider data2(data2_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0715165 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3015166
15167 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1715168 // the data for the SSL handshake once the TLSv1.1 connection falls back to
15169 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2915170 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3015171 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715172 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
Ryan Sleevib8d7ea02018-05-07 20:01:0115173 StaticSocketDataProvider data3(data2_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0715174 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3015175
[email protected]80c75f682012-05-26 16:22:1715176 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
15177 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2915178 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1715179 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715180 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
Ryan Sleevib8d7ea02018-05-07 20:01:0115181 StaticSocketDataProvider data4(data2_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0715182 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1715183
[email protected]7799de12013-05-30 05:52:5115184 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2915185 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5115186 ssl_data5.cert_request_info = cert_request.get();
15187 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
Ryan Sleevib8d7ea02018-05-07 20:01:0115188 StaticSocketDataProvider data5(data2_reads, base::span<MockWrite>());
[email protected]7799de12013-05-30 05:52:5115189 session_deps_.socket_factory->AddSocketDataProvider(&data5);
15190
danakj1fd259a02016-04-16 03:17:0915191 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615192 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3015193
[email protected]bd0b6772011-01-11 19:59:3015194 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4115195 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2015196 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115197 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3015198
15199 // Complete the SSL handshake, which should abort due to requiring a
15200 // client certificate.
15201 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115202 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3015203
15204 // Indicate that no certificate should be supplied. From the perspective
15205 // of SSLClientCertCache, NULL is just as meaningful as a real
15206 // certificate, so this is the same as supply a
15207 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1615208 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0115209 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3015210
15211 // Ensure the certificate was added to the client auth cache before
15212 // allowing the connection to continue restarting.
15213 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5415214 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4115215 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415216 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5215217 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3015218
[email protected]bd0b6772011-01-11 19:59:3015219 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1715220 // then consume ssl_data3 and ssl_data4, both of which should also fail.
15221 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3015222 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115223 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3015224
15225 // Ensure that the client certificate is removed from the cache on a
15226 // handshake failure.
[email protected]791879c2013-12-17 07:22:4115227 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415228 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3015229}
15230
[email protected]8c405132011-01-11 22:03:1815231// Ensure that a client certificate is removed from the SSL client auth
15232// cache when:
15233// 1) An HTTPS proxy is involved.
15234// 3) The HTTPS proxy requests a client certificate.
15235// 4) The client supplies an invalid/unacceptable certificate for the
15236// proxy.
15237// The test is repeated twice, first for connecting to an HTTPS endpoint,
15238// then for connecting to an HTTP endpoint.
bncd16676a2016-07-20 16:23:0115239TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
Ramin Halavatica8d5252018-03-12 05:33:4915240 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
15241 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5115242 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0715243 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1815244
15245 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4115246 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1815247
15248 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
15249 // [ssl_]data[1-3]. Rather than represending the endpoint
15250 // (www.example.com:443), they represent failures with the HTTPS proxy
15251 // (proxy:70).
ttuttle859dc7a2015-04-23 19:42:2915252 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1815253 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715254 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
Ryan Sleevib8d7ea02018-05-07 20:01:0115255 StaticSocketDataProvider data1;
[email protected]bb88e1d32013-05-03 23:11:0715256 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1815257
ttuttle859dc7a2015-04-23 19:42:2915258 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1815259 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715260 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
Ryan Sleevib8d7ea02018-05-07 20:01:0115261 StaticSocketDataProvider data2;
[email protected]bb88e1d32013-05-03 23:11:0715262 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1815263
[email protected]80c75f682012-05-26 16:22:1715264 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
15265#if 0
ttuttle859dc7a2015-04-23 19:42:2915266 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1815267 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715268 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
Ryan Sleevib8d7ea02018-05-07 20:01:0115269 StaticSocketDataProvider data3;
[email protected]bb88e1d32013-05-03 23:11:0715270 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1715271#endif
[email protected]8c405132011-01-11 22:03:1815272
ttuttle859dc7a2015-04-23 19:42:2915273 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1815274 requests[0].url = GURL("https://www.example.com/");
15275 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2915276 requests[0].load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:1015277 requests[0].traffic_annotation =
15278 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c405132011-01-11 22:03:1815279
15280 requests[1].url = GURL("http://www.example.com/");
15281 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2915282 requests[1].load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:1015283 requests[1].traffic_annotation =
15284 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c405132011-01-11 22:03:1815285
Avi Drissman4365a4782018-12-28 19:26:2415286 for (size_t i = 0; i < base::size(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0715287 session_deps_.socket_factory->ResetNextMockIndexes();
danakj1fd259a02016-04-16 03:17:0915288 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615289 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]8c405132011-01-11 22:03:1815290
15291 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4115292 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2015293 int rv = trans.Start(&requests[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115294 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1815295
15296 // Complete the SSL handshake, which should abort due to requiring a
15297 // client certificate.
15298 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115299 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]8c405132011-01-11 22:03:1815300
15301 // Indicate that no certificate should be supplied. From the perspective
15302 // of SSLClientCertCache, NULL is just as meaningful as a real
15303 // certificate, so this is the same as supply a
15304 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1615305 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0115306 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1815307
15308 // Ensure the certificate was added to the client auth cache before
15309 // allowing the connection to continue restarting.
15310 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5415311 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4115312 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415313 HostPortPair("proxy", 70), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5215314 ASSERT_FALSE(client_cert);
[email protected]8c405132011-01-11 22:03:1815315 // Ensure the certificate was NOT cached for the endpoint. This only
15316 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4115317 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415318 HostPortPair("www.example.com", 443), &client_cert,
15319 &client_private_key));
[email protected]8c405132011-01-11 22:03:1815320
15321 // Restart the handshake. This will consume ssl_data2, which fails, and
15322 // then consume ssl_data3, which should also fail. The result code is
15323 // checked against what ssl_data3 should return.
15324 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115325 ASSERT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]8c405132011-01-11 22:03:1815326
15327 // Now that the new handshake has failed, ensure that the client
15328 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4115329 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415330 HostPortPair("proxy", 70), &client_cert, &client_private_key));
[email protected]791879c2013-12-17 07:22:4115331 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415332 HostPortPair("www.example.com", 443), &client_cert,
15333 &client_private_key));
[email protected]8c405132011-01-11 22:03:1815334 }
15335}
15336
bncd16676a2016-07-20 16:23:0115337TEST_F(HttpNetworkTransactionTest, UseIPConnectionPooling) {
[email protected]e3ceb682011-06-28 23:55:4615338 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1915339 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0915340 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4615341
bnc032658ba2016-09-26 18:17:1515342 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4615343
Ryan Hamilton0239aac2018-05-19 00:03:1315344 spdy::SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4915345 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3815346 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1315347 spdy::SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3715348 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4615349 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115350 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4615351 };
Ryan Hamilton0239aac2018-05-19 00:03:1315352 spdy::SpdySerializedFrame host1_resp(
15353 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
15354 spdy::SpdySerializedFrame host1_resp_body(
bncdf80d44fd2016-07-15 20:27:4115355 spdy_util_.ConstructSpdyDataFrame(1, true));
Ryan Hamilton0239aac2018-05-19 00:03:1315356 spdy::SpdySerializedFrame host2_resp(
15357 spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
15358 spdy::SpdySerializedFrame host2_resp_body(
bncdf80d44fd2016-07-15 20:27:4115359 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4615360 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115361 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
15362 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1315363 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4615364 };
15365
eroman36d84e54432016-03-17 03:23:0215366 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0215367 MockConnect connect(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115368 SequencedSocketData spdy_data(connect, spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0715369 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4615370
[email protected]aa22b242011-11-16 18:58:2915371 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4615372 HttpRequestInfo request1;
15373 request1.method = "GET";
bncce36dca22015-04-21 22:11:2315374 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4615375 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015376 request1.traffic_annotation =
15377 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015378 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4615379
tfarina42834112016-09-22 13:38:2015380 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115381 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15382 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615383
15384 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5215385 ASSERT_TRUE(response);
15386 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215387 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4615388
15389 std::string response_data;
robpercival214763f2016-07-01 23:27:0115390 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615391 EXPECT_EQ("hello!", response_data);
15392
bnca4d611d2016-09-22 19:55:3715393 // Preload mail.example.com into HostCache.
Eric Orthf4db66a2019-02-19 21:35:3315394 rv = session_deps_.host_resolver->LoadIntoCache(
15395 HostPortPair("mail.example.com", 443), base::nullopt);
robpercival214763f2016-07-01 23:27:0115396 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4615397
15398 HttpRequestInfo request2;
15399 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3715400 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4615401 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015402 request2.traffic_annotation =
15403 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015404 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4615405
tfarina42834112016-09-22 13:38:2015406 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115407 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15408 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615409
15410 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215411 ASSERT_TRUE(response);
15412 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215413 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4615414 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215415 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115416 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615417 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4615418}
15419
bncd16676a2016-07-20 16:23:0115420TEST_F(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d2b5f092012-06-08 23:55:0215421 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1915422 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0915423 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0215424
bnc032658ba2016-09-26 18:17:1515425 AddSSLSocketData();
[email protected]d2b5f092012-06-08 23:55:0215426
Ryan Hamilton0239aac2018-05-19 00:03:1315427 spdy::SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4915428 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3815429 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1315430 spdy::SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3715431 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0215432 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115433 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0215434 };
Ryan Hamilton0239aac2018-05-19 00:03:1315435 spdy::SpdySerializedFrame host1_resp(
15436 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
15437 spdy::SpdySerializedFrame host1_resp_body(
bncdf80d44fd2016-07-15 20:27:4115438 spdy_util_.ConstructSpdyDataFrame(1, true));
Ryan Hamilton0239aac2018-05-19 00:03:1315439 spdy::SpdySerializedFrame host2_resp(
15440 spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
15441 spdy::SpdySerializedFrame host2_resp_body(
bncdf80d44fd2016-07-15 20:27:4115442 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0215443 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115444 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
15445 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1315446 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0215447 };
15448
eroman36d84e54432016-03-17 03:23:0215449 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0215450 MockConnect connect(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115451 SequencedSocketData spdy_data(connect, spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0715452 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0215453
15454 TestCompletionCallback callback;
15455 HttpRequestInfo request1;
15456 request1.method = "GET";
bncce36dca22015-04-21 22:11:2315457 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0215458 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015459 request1.traffic_annotation =
15460 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015461 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0215462
tfarina42834112016-09-22 13:38:2015463 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115464 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15465 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0215466
15467 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5215468 ASSERT_TRUE(response);
15469 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215470 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0215471
15472 std::string response_data;
robpercival214763f2016-07-01 23:27:0115473 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0215474 EXPECT_EQ("hello!", response_data);
15475
15476 HttpRequestInfo request2;
15477 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3715478 request2.url = GURL("https://mail.example.com/");
[email protected]d2b5f092012-06-08 23:55:0215479 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015480 request2.traffic_annotation =
15481 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015482 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0215483
tfarina42834112016-09-22 13:38:2015484 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115485 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15486 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0215487
15488 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215489 ASSERT_TRUE(response);
15490 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215491 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0215492 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215493 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115494 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0215495 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0215496}
15497
bnc8016c1f2017-03-31 02:11:2915498// Regression test for https://crbug.com/546991.
15499// The server might not be able to serve an IP pooled request, and might send a
15500// 421 Misdirected Request response status to indicate this.
15501// HttpNetworkTransaction should reset the request and retry without IP pooling.
15502TEST_F(HttpNetworkTransactionTest, RetryWithoutConnectionPooling) {
15503 // Two hosts resolve to the same IP address.
15504 const std::string ip_addr = "1.2.3.4";
15505 IPAddress ip;
15506 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
15507 IPEndPoint peer_addr = IPEndPoint(ip, 443);
15508
Jeremy Roman0579ed62017-08-29 15:56:1915509 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
bnc8016c1f2017-03-31 02:11:2915510 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
15511 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
15512
15513 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15514
15515 // Two requests on the first connection.
Ryan Hamilton0239aac2018-05-19 00:03:1315516 spdy::SpdySerializedFrame req1(
bnc8016c1f2017-03-31 02:11:2915517 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
15518 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1315519 spdy::SpdySerializedFrame req2(
bnc8016c1f2017-03-31 02:11:2915520 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1315521 spdy::SpdySerializedFrame rst(
15522 spdy_util_.ConstructSpdyRstStream(3, spdy::ERROR_CODE_CANCEL));
bnc8016c1f2017-03-31 02:11:2915523 MockWrite writes1[] = {
15524 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
15525 CreateMockWrite(rst, 6),
15526 };
15527
15528 // The first one succeeds, the second gets error 421 Misdirected Request.
Ryan Hamilton0239aac2018-05-19 00:03:1315529 spdy::SpdySerializedFrame resp1(
15530 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
15531 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
15532 spdy::SpdyHeaderBlock response_headers;
15533 response_headers[spdy::kHttp2StatusHeader] = "421";
15534 spdy::SpdySerializedFrame resp2(
bnc8016c1f2017-03-31 02:11:2915535 spdy_util_.ConstructSpdyReply(3, std::move(response_headers)));
15536 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
15537 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
15538
15539 MockConnect connect1(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115540 SequencedSocketData data1(connect1, reads1, writes1);
bnc8016c1f2017-03-31 02:11:2915541 session_deps_.socket_factory->AddSocketDataProvider(&data1);
15542
15543 AddSSLSocketData();
15544
15545 // Retry the second request on a second connection.
15546 SpdyTestUtil spdy_util2;
Ryan Hamilton0239aac2018-05-19 00:03:1315547 spdy::SpdySerializedFrame req3(
bnc8016c1f2017-03-31 02:11:2915548 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
15549 MockWrite writes2[] = {
15550 CreateMockWrite(req3, 0),
15551 };
15552
Ryan Hamilton0239aac2018-05-19 00:03:1315553 spdy::SpdySerializedFrame resp3(
15554 spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
15555 spdy::SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
bnc8016c1f2017-03-31 02:11:2915556 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
15557 MockRead(ASYNC, 0, 3)};
15558
15559 MockConnect connect2(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115560 SequencedSocketData data2(connect2, reads2, writes2);
bnc8016c1f2017-03-31 02:11:2915561 session_deps_.socket_factory->AddSocketDataProvider(&data2);
15562
15563 AddSSLSocketData();
15564
15565 // Preload mail.example.org into HostCache.
Eric Orthf4db66a2019-02-19 21:35:3315566 int rv = session_deps_.host_resolver->LoadIntoCache(
15567 HostPortPair("mail.example.com", 443), base::nullopt);
bnc8016c1f2017-03-31 02:11:2915568 EXPECT_THAT(rv, IsOk());
15569
15570 HttpRequestInfo request1;
15571 request1.method = "GET";
15572 request1.url = GURL("https://www.example.org/");
15573 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015574 request1.traffic_annotation =
15575 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8016c1f2017-03-31 02:11:2915576 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
15577
Eric Orthf4db66a2019-02-19 21:35:3315578 TestCompletionCallback callback;
bnc8016c1f2017-03-31 02:11:2915579 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
15580 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15581 rv = callback.WaitForResult();
15582 EXPECT_THAT(rv, IsOk());
15583
15584 const HttpResponseInfo* response = trans1.GetResponseInfo();
15585 ASSERT_TRUE(response);
15586 ASSERT_TRUE(response->headers);
15587 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
15588 EXPECT_TRUE(response->was_fetched_via_spdy);
15589 EXPECT_TRUE(response->was_alpn_negotiated);
15590 std::string response_data;
15591 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
15592 EXPECT_EQ("hello!", response_data);
15593
15594 HttpRequestInfo request2;
15595 request2.method = "GET";
15596 request2.url = GURL("https://mail.example.org/");
15597 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015598 request2.traffic_annotation =
15599 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8016c1f2017-03-31 02:11:2915600 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
15601
15602 BoundTestNetLog log;
15603 rv = trans2.Start(&request2, callback.callback(), log.bound());
15604 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15605 rv = callback.WaitForResult();
15606 EXPECT_THAT(rv, IsOk());
15607
15608 response = trans2.GetResponseInfo();
15609 ASSERT_TRUE(response);
15610 ASSERT_TRUE(response->headers);
15611 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
15612 EXPECT_TRUE(response->was_fetched_via_spdy);
15613 EXPECT_TRUE(response->was_alpn_negotiated);
15614 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
15615 EXPECT_EQ("hello!", response_data);
15616
15617 TestNetLogEntry::List entries;
15618 log.GetEntries(&entries);
davidbence688ae2017-05-04 15:12:5915619 ExpectLogContainsSomewhere(
15620 entries, 0, NetLogEventType::HTTP_TRANSACTION_RESTART_MISDIRECTED_REQUEST,
bnc8016c1f2017-03-31 02:11:2915621 NetLogEventPhase::NONE);
davidbence688ae2017-05-04 15:12:5915622}
15623
15624// Test that HTTP 421 responses are properly returned to the caller if received
15625// on the retry as well. HttpNetworkTransaction should not infinite loop or lose
15626// portions of the response.
15627TEST_F(HttpNetworkTransactionTest, ReturnHTTP421OnRetry) {
15628 // Two hosts resolve to the same IP address.
15629 const std::string ip_addr = "1.2.3.4";
15630 IPAddress ip;
15631 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
15632 IPEndPoint peer_addr = IPEndPoint(ip, 443);
15633
Jeremy Roman0579ed62017-08-29 15:56:1915634 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
davidbence688ae2017-05-04 15:12:5915635 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
15636 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
15637
15638 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15639
15640 // Two requests on the first connection.
Ryan Hamilton0239aac2018-05-19 00:03:1315641 spdy::SpdySerializedFrame req1(
davidbence688ae2017-05-04 15:12:5915642 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
15643 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1315644 spdy::SpdySerializedFrame req2(
davidbence688ae2017-05-04 15:12:5915645 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1315646 spdy::SpdySerializedFrame rst(
15647 spdy_util_.ConstructSpdyRstStream(3, spdy::ERROR_CODE_CANCEL));
davidbence688ae2017-05-04 15:12:5915648 MockWrite writes1[] = {
15649 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
15650 CreateMockWrite(rst, 6),
15651 };
15652
15653 // The first one succeeds, the second gets error 421 Misdirected Request.
Ryan Hamilton0239aac2018-05-19 00:03:1315654 spdy::SpdySerializedFrame resp1(
15655 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
15656 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
15657 spdy::SpdyHeaderBlock response_headers;
15658 response_headers[spdy::kHttp2StatusHeader] = "421";
15659 spdy::SpdySerializedFrame resp2(
davidbence688ae2017-05-04 15:12:5915660 spdy_util_.ConstructSpdyReply(3, response_headers.Clone()));
15661 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
15662 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
15663
15664 MockConnect connect1(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115665 SequencedSocketData data1(connect1, reads1, writes1);
davidbence688ae2017-05-04 15:12:5915666 session_deps_.socket_factory->AddSocketDataProvider(&data1);
15667
15668 AddSSLSocketData();
15669
15670 // Retry the second request on a second connection. It returns 421 Misdirected
15671 // Retry again.
15672 SpdyTestUtil spdy_util2;
Ryan Hamilton0239aac2018-05-19 00:03:1315673 spdy::SpdySerializedFrame req3(
davidbence688ae2017-05-04 15:12:5915674 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
15675 MockWrite writes2[] = {
15676 CreateMockWrite(req3, 0),
15677 };
15678
Ryan Hamilton0239aac2018-05-19 00:03:1315679 spdy::SpdySerializedFrame resp3(
davidbence688ae2017-05-04 15:12:5915680 spdy_util2.ConstructSpdyReply(1, std::move(response_headers)));
Ryan Hamilton0239aac2018-05-19 00:03:1315681 spdy::SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
davidbence688ae2017-05-04 15:12:5915682 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
15683 MockRead(ASYNC, 0, 3)};
15684
15685 MockConnect connect2(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115686 SequencedSocketData data2(connect2, reads2, writes2);
davidbence688ae2017-05-04 15:12:5915687 session_deps_.socket_factory->AddSocketDataProvider(&data2);
15688
15689 AddSSLSocketData();
15690
15691 // Preload mail.example.org into HostCache.
Eric Orthf4db66a2019-02-19 21:35:3315692 int rv = session_deps_.host_resolver->LoadIntoCache(
15693 HostPortPair("mail.example.com", 443), base::nullopt);
davidbence688ae2017-05-04 15:12:5915694 EXPECT_THAT(rv, IsOk());
15695
15696 HttpRequestInfo request1;
15697 request1.method = "GET";
15698 request1.url = GURL("https://www.example.org/");
15699 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015700 request1.traffic_annotation =
15701 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
davidbence688ae2017-05-04 15:12:5915702 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
15703
Eric Orthf4db66a2019-02-19 21:35:3315704 TestCompletionCallback callback;
davidbence688ae2017-05-04 15:12:5915705 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
15706 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15707 rv = callback.WaitForResult();
15708 EXPECT_THAT(rv, IsOk());
15709
15710 const HttpResponseInfo* response = trans1.GetResponseInfo();
15711 ASSERT_TRUE(response);
15712 ASSERT_TRUE(response->headers);
15713 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
15714 EXPECT_TRUE(response->was_fetched_via_spdy);
15715 EXPECT_TRUE(response->was_alpn_negotiated);
15716 std::string response_data;
15717 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
15718 EXPECT_EQ("hello!", response_data);
15719
15720 HttpRequestInfo request2;
15721 request2.method = "GET";
15722 request2.url = GURL("https://mail.example.org/");
15723 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015724 request2.traffic_annotation =
15725 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
davidbence688ae2017-05-04 15:12:5915726 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
15727
15728 BoundTestNetLog log;
15729 rv = trans2.Start(&request2, callback.callback(), log.bound());
15730 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15731 rv = callback.WaitForResult();
15732 EXPECT_THAT(rv, IsOk());
15733
15734 // After a retry, the 421 Misdirected Request is reported back up to the
15735 // caller.
15736 response = trans2.GetResponseInfo();
15737 ASSERT_TRUE(response);
15738 ASSERT_TRUE(response->headers);
15739 EXPECT_EQ("HTTP/1.1 421", response->headers->GetStatusLine());
15740 EXPECT_TRUE(response->was_fetched_via_spdy);
15741 EXPECT_TRUE(response->was_alpn_negotiated);
15742 EXPECT_TRUE(response->ssl_info.cert);
15743 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
15744 EXPECT_EQ("hello!", response_data);
bnc8016c1f2017-03-31 02:11:2915745}
15746
bncd16676a2016-07-20 16:23:0115747TEST_F(HttpNetworkTransactionTest,
mmenke5c642132015-06-02 16:05:1315748 UseIPConnectionPoolingWithHostCacheExpiration) {
Eric Orth1da75de2019-02-20 21:10:3415749 // Set up HostResolver to invalidate cached entries after 1 cached resolve.
15750 session_deps_.host_resolver =
15751 std::make_unique<MockCachingHostResolver>(1 /* cache_invalidation_num */);
danakj1fd259a02016-04-16 03:17:0915752 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4615753
bnc032658ba2016-09-26 18:17:1515754 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4615755
Ryan Hamilton0239aac2018-05-19 00:03:1315756 spdy::SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4915757 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3815758 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1315759 spdy::SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3715760 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4615761 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115762 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4615763 };
Ryan Hamilton0239aac2018-05-19 00:03:1315764 spdy::SpdySerializedFrame host1_resp(
15765 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
15766 spdy::SpdySerializedFrame host1_resp_body(
bncdf80d44fd2016-07-15 20:27:4115767 spdy_util_.ConstructSpdyDataFrame(1, true));
Ryan Hamilton0239aac2018-05-19 00:03:1315768 spdy::SpdySerializedFrame host2_resp(
15769 spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
15770 spdy::SpdySerializedFrame host2_resp_body(
bncdf80d44fd2016-07-15 20:27:4115771 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4615772 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115773 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
15774 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1315775 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4615776 };
15777
eroman36d84e54432016-03-17 03:23:0215778 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0215779 MockConnect connect(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115780 SequencedSocketData spdy_data(connect, spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0715781 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4615782
[email protected]aa22b242011-11-16 18:58:2915783 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4615784 HttpRequestInfo request1;
15785 request1.method = "GET";
bncce36dca22015-04-21 22:11:2315786 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4615787 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015788 request1.traffic_annotation =
15789 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015790 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4615791
tfarina42834112016-09-22 13:38:2015792 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115793 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15794 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615795
15796 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5215797 ASSERT_TRUE(response);
15798 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215799 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4615800
15801 std::string response_data;
robpercival214763f2016-07-01 23:27:0115802 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615803 EXPECT_EQ("hello!", response_data);
15804
15805 // Preload cache entries into HostCache.
Eric Orthf4db66a2019-02-19 21:35:3315806 rv = session_deps_.host_resolver->LoadIntoCache(
15807 HostPortPair("mail.example.com", 443), base::nullopt);
robpercival214763f2016-07-01 23:27:0115808 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4615809
15810 HttpRequestInfo request2;
15811 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3715812 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4615813 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015814 request2.traffic_annotation =
15815 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015816 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4615817
tfarina42834112016-09-22 13:38:2015818 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115819 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15820 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615821
15822 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215823 ASSERT_TRUE(response);
15824 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215825 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4615826 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215827 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115828 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615829 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4615830}
15831
bncd16676a2016-07-20 16:23:0115832TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2315833 const std::string https_url = "https://www.example.org:8080/";
15834 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0415835
15836 // SPDY GET for HTTPS URL
Ryan Hamilton0239aac2018-05-19 00:03:1315837 spdy::SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4915838 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0415839
15840 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4115841 CreateMockWrite(req1, 0),
[email protected]8450d722012-07-02 19:14:0415842 };
15843
Ryan Hamilton0239aac2018-05-19 00:03:1315844 spdy::SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
15845 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
bncdf80d44fd2016-07-15 20:27:4115846 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
mmenkee24011922015-12-17 22:12:5915847 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)};
[email protected]8450d722012-07-02 19:14:0415848
Ryan Sleevib8d7ea02018-05-07 20:01:0115849 SequencedSocketData data1(reads1, writes1);
[email protected]8450d722012-07-02 19:14:0415850 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5715851 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0415852
15853 // HTTP GET for the HTTP URL
15854 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1315855 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3415856 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2315857 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3415858 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0415859 };
15860
15861 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1315862 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
15863 MockRead(ASYNC, 2, "hello"),
15864 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0415865 };
15866
Ryan Sleevib8d7ea02018-05-07 20:01:0115867 SequencedSocketData data2(reads2, writes2);
[email protected]8450d722012-07-02 19:14:0415868
[email protected]8450d722012-07-02 19:14:0415869 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615870 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0715871 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15872 session_deps_.socket_factory->AddSocketDataProvider(&data1);
15873 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0415874
danakj1fd259a02016-04-16 03:17:0915875 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0415876
15877 // Start the first transaction to set up the SpdySession
15878 HttpRequestInfo request1;
15879 request1.method = "GET";
15880 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0415881 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015882 request1.traffic_annotation =
15883 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015884 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0415885 TestCompletionCallback callback1;
15886 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015887 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5515888 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0415889
robpercival214763f2016-07-01 23:27:0115890 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0415891 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
15892
15893 // Now, start the HTTP request
15894 HttpRequestInfo request2;
15895 request2.method = "GET";
15896 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0415897 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015898 request2.traffic_annotation =
15899 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015900 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0415901 TestCompletionCallback callback2;
15902 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015903 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5515904 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0415905
robpercival214763f2016-07-01 23:27:0115906 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0415907 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
15908}
15909
bnc5452e2a2015-05-08 16:27:4215910// Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
15911// with the alternative server. That connection should not be used.
bncd16676a2016-07-20 16:23:0115912TEST_F(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
bnc8bef8da22016-05-30 01:28:2515913 url::SchemeHostPort server("https", "www.example.org", 443);
15914 HostPortPair alternative("www.example.org", 444);
bnc5452e2a2015-05-08 16:27:4215915
bnc8bef8da22016-05-30 01:28:2515916 // Negotiate HTTP/1.1 with alternative.
bnc5452e2a2015-05-08 16:27:4215917 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615918 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4215919 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15920
15921 // No data should be read from the alternative, because HTTP/1.1 is
15922 // negotiated.
15923 StaticSocketDataProvider data;
15924 session_deps_.socket_factory->AddSocketDataProvider(&data);
15925
15926 // This test documents that an alternate Job should not be used if HTTP/1.1 is
zhongyi3d4a55e72016-04-22 20:36:4615927 // negotiated. In order to test this, a failed connection to the server is
bnc5452e2a2015-05-08 16:27:4215928 // mocked. This way the request relies on the alternate Job.
15929 StaticSocketDataProvider data_refused;
15930 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
15931 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
15932
zhongyi3d4a55e72016-04-22 20:36:4615933 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0915934 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4015935 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4215936 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2115937 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1215938 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2115939 http_server_properties->SetHttp2AlternativeService(
15940 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4215941
bnc5452e2a2015-05-08 16:27:4215942 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4615943 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4215944 request.method = "GET";
bnc8bef8da22016-05-30 01:28:2515945 request.url = GURL("https://www.example.org:443");
Ramin Halavatib5e433e2018-02-07 07:41:1015946 request.traffic_annotation =
15947 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4215948 TestCompletionCallback callback;
15949
15950 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
bnc94c92842016-09-21 15:22:5215951 // negotiated, the alternate Job should fail with ERR_ALPN_NEGOTIATION_FAILED.
tfarina42834112016-09-22 13:38:2015952 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc94c92842016-09-21 15:22:5215953 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_ALPN_NEGOTIATION_FAILED));
bnc5452e2a2015-05-08 16:27:4215954}
15955
bnc40448a532015-05-11 19:13:1415956// A request to a server with an alternative service fires two Jobs: one to the
zhongyi3d4a55e72016-04-22 20:36:4615957// server, and an alternate one to the alternative server. If the former
bnc40448a532015-05-11 19:13:1415958// succeeds, the request should succeed, even if the latter fails because
15959// HTTP/1.1 is negotiated which is insufficient for alternative service.
bncd16676a2016-07-20 16:23:0115960TEST_F(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
bnc8bef8da22016-05-30 01:28:2515961 url::SchemeHostPort server("https", "www.example.org", 443);
15962 HostPortPair alternative("www.example.org", 444);
bnc40448a532015-05-11 19:13:1415963
15964 // Negotiate HTTP/1.1 with alternative.
15965 SSLSocketDataProvider alternative_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615966 alternative_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1415967 session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
15968
15969 // No data should be read from the alternative, because HTTP/1.1 is
15970 // negotiated.
15971 StaticSocketDataProvider data;
15972 session_deps_.socket_factory->AddSocketDataProvider(&data);
15973
zhongyi3d4a55e72016-04-22 20:36:4615974 // Negotiate HTTP/1.1 with server.
bnc40448a532015-05-11 19:13:1415975 SSLSocketDataProvider origin_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615976 origin_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1415977 session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
15978
15979 MockWrite http_writes[] = {
bnc8bef8da22016-05-30 01:28:2515980 MockWrite("GET / HTTP/1.1\r\n"
15981 "Host: www.example.org\r\n"
15982 "Connection: keep-alive\r\n\r\n"),
15983 MockWrite("GET /second HTTP/1.1\r\n"
15984 "Host: www.example.org\r\n"
15985 "Connection: keep-alive\r\n\r\n"),
bnc40448a532015-05-11 19:13:1415986 };
15987
15988 MockRead http_reads[] = {
15989 MockRead("HTTP/1.1 200 OK\r\n"),
15990 MockRead("Content-Type: text/html\r\n"),
15991 MockRead("Content-Length: 6\r\n\r\n"),
15992 MockRead("foobar"),
15993 MockRead("HTTP/1.1 200 OK\r\n"),
15994 MockRead("Content-Type: text/html\r\n"),
15995 MockRead("Content-Length: 7\r\n\r\n"),
15996 MockRead("another"),
15997 };
Ryan Sleevib8d7ea02018-05-07 20:01:0115998 StaticSocketDataProvider http_data(http_reads, http_writes);
bnc40448a532015-05-11 19:13:1415999 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16000
zhongyi3d4a55e72016-04-22 20:36:4616001 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0916002 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4016003 HttpServerProperties* http_server_properties =
bnc40448a532015-05-11 19:13:1416004 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2116005 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1216006 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2116007 http_server_properties->SetHttp2AlternativeService(
16008 server, alternative_service, expiration);
bnc40448a532015-05-11 19:13:1416009
16010 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
16011 HttpRequestInfo request1;
16012 request1.method = "GET";
bnc8bef8da22016-05-30 01:28:2516013 request1.url = GURL("https://www.example.org:443");
bnc40448a532015-05-11 19:13:1416014 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016015 request1.traffic_annotation =
16016 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc40448a532015-05-11 19:13:1416017 TestCompletionCallback callback1;
16018
tfarina42834112016-09-22 13:38:2016019 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1416020 rv = callback1.GetResult(rv);
robpercival214763f2016-07-01 23:27:0116021 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1416022
16023 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5216024 ASSERT_TRUE(response1);
16025 ASSERT_TRUE(response1->headers);
bnc40448a532015-05-11 19:13:1416026 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
16027
16028 std::string response_data1;
robpercival214763f2016-07-01 23:27:0116029 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc40448a532015-05-11 19:13:1416030 EXPECT_EQ("foobar", response_data1);
16031
16032 // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
16033 // for alternative service.
16034 EXPECT_TRUE(
16035 http_server_properties->IsAlternativeServiceBroken(alternative_service));
16036
zhongyi3d4a55e72016-04-22 20:36:4616037 // Since |alternative_service| is broken, a second transaction to server
bnc40448a532015-05-11 19:13:1416038 // should not start an alternate Job. It should pool to existing connection
zhongyi3d4a55e72016-04-22 20:36:4616039 // to server.
bnc40448a532015-05-11 19:13:1416040 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
16041 HttpRequestInfo request2;
16042 request2.method = "GET";
bnc8bef8da22016-05-30 01:28:2516043 request2.url = GURL("https://www.example.org:443/second");
bnc40448a532015-05-11 19:13:1416044 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016045 request2.traffic_annotation =
16046 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc40448a532015-05-11 19:13:1416047 TestCompletionCallback callback2;
16048
tfarina42834112016-09-22 13:38:2016049 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1416050 rv = callback2.GetResult(rv);
robpercival214763f2016-07-01 23:27:0116051 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1416052
16053 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5216054 ASSERT_TRUE(response2);
16055 ASSERT_TRUE(response2->headers);
bnc40448a532015-05-11 19:13:1416056 EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
16057
16058 std::string response_data2;
robpercival214763f2016-07-01 23:27:0116059 ASSERT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
bnc40448a532015-05-11 19:13:1416060 EXPECT_EQ("another", response_data2);
16061}
16062
bnc5452e2a2015-05-08 16:27:4216063// Alternative service requires HTTP/2 (or SPDY), but there is already a
16064// HTTP/1.1 socket open to the alternative server. That socket should not be
16065// used.
bncd16676a2016-07-20 16:23:0116066TEST_F(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
zhongyi3d4a55e72016-04-22 20:36:4616067 url::SchemeHostPort server("https", "origin.example.org", 443);
bnc5452e2a2015-05-08 16:27:4216068 HostPortPair alternative("alternative.example.org", 443);
16069 std::string origin_url = "https://origin.example.org:443";
16070 std::string alternative_url = "https://alternative.example.org:443";
16071
16072 // Negotiate HTTP/1.1 with alternative.example.org.
16073 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616074 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4216075 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16076
16077 // HTTP/1.1 data for |request1| and |request2|.
16078 MockWrite http_writes[] = {
16079 MockWrite(
16080 "GET / HTTP/1.1\r\n"
16081 "Host: alternative.example.org\r\n"
16082 "Connection: keep-alive\r\n\r\n"),
16083 MockWrite(
16084 "GET / HTTP/1.1\r\n"
16085 "Host: alternative.example.org\r\n"
16086 "Connection: keep-alive\r\n\r\n"),
16087 };
16088
16089 MockRead http_reads[] = {
16090 MockRead(
16091 "HTTP/1.1 200 OK\r\n"
16092 "Content-Type: text/html; charset=iso-8859-1\r\n"
16093 "Content-Length: 40\r\n\r\n"
16094 "first HTTP/1.1 response from alternative"),
16095 MockRead(
16096 "HTTP/1.1 200 OK\r\n"
16097 "Content-Type: text/html; charset=iso-8859-1\r\n"
16098 "Content-Length: 41\r\n\r\n"
16099 "second HTTP/1.1 response from alternative"),
16100 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116101 StaticSocketDataProvider http_data(http_reads, http_writes);
bnc5452e2a2015-05-08 16:27:4216102 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16103
16104 // This test documents that an alternate Job should not pool to an already
16105 // existing HTTP/1.1 connection. In order to test this, a failed connection
zhongyi3d4a55e72016-04-22 20:36:4616106 // to the server is mocked. This way |request2| relies on the alternate Job.
bnc5452e2a2015-05-08 16:27:4216107 StaticSocketDataProvider data_refused;
16108 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
16109 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
16110
zhongyi3d4a55e72016-04-22 20:36:4616111 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0916112 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4016113 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4216114 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2116115 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1216116 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2116117 http_server_properties->SetHttp2AlternativeService(
16118 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4216119
16120 // First transaction to alternative to open an HTTP/1.1 socket.
bnc5452e2a2015-05-08 16:27:4216121 HttpRequestInfo request1;
krasinc06a72a2016-12-21 03:42:4616122 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4216123 request1.method = "GET";
16124 request1.url = GURL(alternative_url);
16125 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016126 request1.traffic_annotation =
16127 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4216128 TestCompletionCallback callback1;
16129
tfarina42834112016-09-22 13:38:2016130 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116131 EXPECT_THAT(callback1.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1616132 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4216133 ASSERT_TRUE(response1);
wezca1070932016-05-26 20:30:5216134 ASSERT_TRUE(response1->headers);
bnc5452e2a2015-05-08 16:27:4216135 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5216136 EXPECT_TRUE(response1->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4216137 EXPECT_FALSE(response1->was_fetched_via_spdy);
16138 std::string response_data1;
bnc691fda62016-08-12 00:43:1616139 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc5452e2a2015-05-08 16:27:4216140 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
16141
16142 // Request for origin.example.org, which has an alternative service. This
16143 // will start two Jobs: the alternative looks for connections to pool to,
16144 // finds one which is HTTP/1.1, and should ignore it, and should not try to
zhongyi3d4a55e72016-04-22 20:36:4616145 // open other connections to alternative server. The Job to server fails, so
bnc5452e2a2015-05-08 16:27:4216146 // this request fails.
bnc5452e2a2015-05-08 16:27:4216147 HttpRequestInfo request2;
krasinc06a72a2016-12-21 03:42:4616148 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4216149 request2.method = "GET";
16150 request2.url = GURL(origin_url);
16151 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016152 request2.traffic_annotation =
16153 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4216154 TestCompletionCallback callback2;
16155
tfarina42834112016-09-22 13:38:2016156 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116157 EXPECT_THAT(callback2.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc5452e2a2015-05-08 16:27:4216158
16159 // Another transaction to alternative. This is to test that the HTTP/1.1
16160 // socket is still open and in the pool.
bnc5452e2a2015-05-08 16:27:4216161 HttpRequestInfo request3;
krasinc06a72a2016-12-21 03:42:4616162 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4216163 request3.method = "GET";
16164 request3.url = GURL(alternative_url);
16165 request3.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016166 request3.traffic_annotation =
16167 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4216168 TestCompletionCallback callback3;
16169
tfarina42834112016-09-22 13:38:2016170 rv = trans3.Start(&request3, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116171 EXPECT_THAT(callback3.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1616172 const HttpResponseInfo* response3 = trans3.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4216173 ASSERT_TRUE(response3);
wezca1070932016-05-26 20:30:5216174 ASSERT_TRUE(response3->headers);
bnc5452e2a2015-05-08 16:27:4216175 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5216176 EXPECT_TRUE(response3->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4216177 EXPECT_FALSE(response3->was_fetched_via_spdy);
16178 std::string response_data3;
bnc691fda62016-08-12 00:43:1616179 ASSERT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
bnc5452e2a2015-05-08 16:27:4216180 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
16181}
16182
bncd16676a2016-07-20 16:23:0116183TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2316184 const std::string https_url = "https://www.example.org:8080/";
16185 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0416186
rdsmithebb50aa2015-11-12 03:44:3816187 // Separate SPDY util instance for naked and wrapped requests.
bncd16676a2016-07-20 16:23:0116188 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:3816189
[email protected]8450d722012-07-02 19:14:0416190 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2316191 const HostPortPair host_port_pair("www.example.org", 8080);
Ryan Hamilton0239aac2018-05-19 00:03:1316192 spdy::SpdySerializedFrame connect(
lgarrona91df87f2014-12-05 00:51:3416193 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
Ryan Hamilton0239aac2018-05-19 00:03:1316194 spdy::SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4916195 spdy_util_wrapped.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1316196 spdy::SpdySerializedFrame wrapped_req1(
[email protected]23e482282013-06-14 16:08:0216197 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3916198
16199 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
Ryan Hamilton0239aac2018-05-19 00:03:1316200 spdy::SpdyHeaderBlock req2_block;
16201 req2_block[spdy::kHttp2MethodHeader] = "GET";
16202 req2_block[spdy::kHttp2AuthorityHeader] = "www.example.org:8080";
16203 req2_block[spdy::kHttp2SchemeHeader] = "http";
16204 req2_block[spdy::kHttp2PathHeader] = "/";
16205 spdy::SpdySerializedFrame req2(
bnc42331402016-07-25 13:36:1516206 spdy_util_.ConstructSpdyHeaders(3, std::move(req2_block), MEDIUM, true));
[email protected]8450d722012-07-02 19:14:0416207
16208 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4116209 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_req1, 2),
16210 CreateMockWrite(req2, 6),
[email protected]8450d722012-07-02 19:14:0416211 };
16212
Ryan Hamilton0239aac2018-05-19 00:03:1316213 spdy::SpdySerializedFrame conn_resp(
bnc42331402016-07-25 13:36:1516214 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316215 spdy::SpdySerializedFrame resp1(
bnc42331402016-07-25 13:36:1516216 spdy_util_wrapped.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316217 spdy::SpdySerializedFrame body1(
16218 spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
16219 spdy::SpdySerializedFrame wrapped_resp1(
rdsmithebb50aa2015-11-12 03:44:3816220 spdy_util_wrapped.ConstructWrappedSpdyFrame(resp1, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316221 spdy::SpdySerializedFrame wrapped_body1(
rdsmithebb50aa2015-11-12 03:44:3816222 spdy_util_wrapped.ConstructWrappedSpdyFrame(body1, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316223 spdy::SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
16224 spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
mmenke666a6fea2015-12-19 04:16:3316225 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4116226 CreateMockRead(conn_resp, 1),
mmenke666a6fea2015-12-19 04:16:3316227 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:4116228 CreateMockRead(wrapped_resp1, 4),
16229 CreateMockRead(wrapped_body1, 5),
mmenke666a6fea2015-12-19 04:16:3316230 MockRead(ASYNC, ERR_IO_PENDING, 7),
bncdf80d44fd2016-07-15 20:27:4116231 CreateMockRead(resp2, 8),
16232 CreateMockRead(body2, 9),
mmenke666a6fea2015-12-19 04:16:3316233 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 10),
16234 };
[email protected]8450d722012-07-02 19:14:0416235
Ryan Sleevib8d7ea02018-05-07 20:01:0116236 SequencedSocketData data1(reads1, writes1);
[email protected]8450d722012-07-02 19:14:0416237 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5716238 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0416239
Lily Houghton8c2f97d2018-01-22 05:06:5916240 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4916241 ProxyResolutionService::CreateFixedFromPacResult(
16242 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5116243 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0716244 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0416245 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3616246 ssl1.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3316247 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0416248 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3616249 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3316250 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
16251 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0416252
danakj1fd259a02016-04-16 03:17:0916253 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]8450d722012-07-02 19:14:0416254
16255 // Start the first transaction to set up the SpdySession
16256 HttpRequestInfo request1;
16257 request1.method = "GET";
16258 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0416259 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016260 request1.traffic_annotation =
16261 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016262 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0416263 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:2016264 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0416265
mmenke666a6fea2015-12-19 04:16:3316266 // This pause is a hack to avoid running into https://crbug.com/497228.
16267 data1.RunUntilPaused();
16268 base::RunLoop().RunUntilIdle();
16269 data1.Resume();
robpercival214763f2016-07-01 23:27:0116270 EXPECT_THAT(callback1.GetResult(rv), IsOk());
[email protected]8450d722012-07-02 19:14:0416271 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
16272
[email protected]f6c63db52013-02-02 00:35:2216273 LoadTimingInfo load_timing_info1;
16274 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
16275 TestLoadTimingNotReusedWithPac(load_timing_info1,
16276 CONNECT_TIMING_HAS_SSL_TIMES);
16277
mmenke666a6fea2015-12-19 04:16:3316278 // Now, start the HTTP request.
[email protected]8450d722012-07-02 19:14:0416279 HttpRequestInfo request2;
16280 request2.method = "GET";
16281 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0416282 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016283 request2.traffic_annotation =
16284 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016285 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0416286 TestCompletionCallback callback2;
tfarina42834112016-09-22 13:38:2016287 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0416288
mmenke666a6fea2015-12-19 04:16:3316289 // This pause is a hack to avoid running into https://crbug.com/497228.
16290 data1.RunUntilPaused();
16291 base::RunLoop().RunUntilIdle();
16292 data1.Resume();
robpercival214763f2016-07-01 23:27:0116293 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenke666a6fea2015-12-19 04:16:3316294
[email protected]8450d722012-07-02 19:14:0416295 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2216296
16297 LoadTimingInfo load_timing_info2;
16298 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
16299 // The established SPDY sessions is considered reused by the HTTP request.
16300 TestLoadTimingReusedWithPac(load_timing_info2);
16301 // HTTP requests over a SPDY session should have a different connection
16302 // socket_log_id than requests over a tunnel.
16303 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0416304}
16305
[email protected]2d88e7d2012-07-19 17:55:1716306// Test that in the case where we have a SPDY session to a SPDY proxy
16307// that we do not pool other origins that resolve to the same IP when
16308// the certificate does not match the new origin.
16309// http://crbug.com/134690
bncd16676a2016-07-20 16:23:0116310TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2316311 const std::string url1 = "http://www.example.org/";
16312 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1716313 const std::string ip_addr = "1.2.3.4";
16314
rdsmithebb50aa2015-11-12 03:44:3816315 // Second SpdyTestUtil instance for the second socket.
bncd16676a2016-07-20 16:23:0116316 SpdyTestUtil spdy_util_secure;
rdsmithebb50aa2015-11-12 03:44:3816317
[email protected]2d88e7d2012-07-19 17:55:1716318 // SPDY GET for HTTP URL (through SPDY proxy)
Ryan Hamilton0239aac2018-05-19 00:03:1316319 spdy::SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:2316320 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
Ryan Hamilton0239aac2018-05-19 00:03:1316321 spdy::SpdySerializedFrame req1(
bnc42331402016-07-25 13:36:1516322 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
[email protected]2d88e7d2012-07-19 17:55:1716323
16324 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4116325 CreateMockWrite(req1, 0),
[email protected]2d88e7d2012-07-19 17:55:1716326 };
16327
Ryan Hamilton0239aac2018-05-19 00:03:1316328 spdy::SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
16329 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1716330 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4116331 MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(resp1, 2),
16332 CreateMockRead(body1, 3), MockRead(ASYNC, OK, 4), // EOF
[email protected]2d88e7d2012-07-19 17:55:1716333 };
16334
Ryan Sleevib8d7ea02018-05-07 20:01:0116335 SequencedSocketData data1(reads1, writes1);
martijnfe9636e2016-02-06 14:33:3216336 IPAddress ip;
martijn654c8c42016-02-10 22:10:5916337 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
[email protected]2d88e7d2012-07-19 17:55:1716338 IPEndPoint peer_addr = IPEndPoint(ip, 443);
16339 MockConnect connect_data1(ASYNC, OK, peer_addr);
mmenke666a6fea2015-12-19 04:16:3316340 data1.set_connect_data(connect_data1);
[email protected]2d88e7d2012-07-19 17:55:1716341
16342 // SPDY GET for HTTPS URL (direct)
Ryan Hamilton0239aac2018-05-19 00:03:1316343 spdy::SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4916344 spdy_util_secure.ConstructSpdyGet(url2.c_str(), 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1716345
16346 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4116347 CreateMockWrite(req2, 0),
[email protected]2d88e7d2012-07-19 17:55:1716348 };
16349
Ryan Hamilton0239aac2018-05-19 00:03:1316350 spdy::SpdySerializedFrame resp2(
16351 spdy_util_secure.ConstructSpdyGetReply(NULL, 0, 1));
16352 spdy::SpdySerializedFrame body2(
16353 spdy_util_secure.ConstructSpdyDataFrame(1, true));
bncdf80d44fd2016-07-15 20:27:4116354 MockRead reads2[] = {CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
mmenke666a6fea2015-12-19 04:16:3316355 MockRead(ASYNC, OK, 3)};
[email protected]2d88e7d2012-07-19 17:55:1716356
Ryan Sleevib8d7ea02018-05-07 20:01:0116357 SequencedSocketData data2(reads2, writes2);
[email protected]2d88e7d2012-07-19 17:55:1716358 MockConnect connect_data2(ASYNC, OK);
mmenke666a6fea2015-12-19 04:16:3316359 data2.set_connect_data(connect_data2);
[email protected]2d88e7d2012-07-19 17:55:1716360
16361 // Set up a proxy config that sends HTTP requests to a proxy, and
16362 // all others direct.
16363 ProxyConfig proxy_config;
16364 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
Ramin Halavatica8d5252018-03-12 05:33:4916365 session_deps_.proxy_resolution_service =
16366 std::make_unique<ProxyResolutionService>(
16367 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
16368 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
16369 nullptr, nullptr);
[email protected]2d88e7d2012-07-19 17:55:1716370
bncce36dca22015-04-21 22:11:2316371 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3616372 ssl1.next_proto = kProtoHTTP2;
[email protected]2d88e7d2012-07-19 17:55:1716373 // Load a valid cert. Note, that this does not need to
16374 // be valid for proxy because the MockSSLClientSocket does
16375 // not actually verify it. But SpdySession will use this
16376 // to see if it is valid for the new origin
Ryan Sleevi4f832092017-11-21 23:25:4916377 ssl1.ssl_info.cert =
16378 ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
16379 ASSERT_TRUE(ssl1.ssl_info.cert);
mmenke666a6fea2015-12-19 04:16:3316380 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
16381 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d88e7d2012-07-19 17:55:1716382
16383 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3616384 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3316385 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
16386 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d88e7d2012-07-19 17:55:1716387
Jeremy Roman0579ed62017-08-29 15:56:1916388 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
bncce36dca22015-04-21 22:11:2316389 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0716390 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1716391
danakj1fd259a02016-04-16 03:17:0916392 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]2d88e7d2012-07-19 17:55:1716393
16394 // Start the first transaction to set up the SpdySession
16395 HttpRequestInfo request1;
16396 request1.method = "GET";
16397 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1716398 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016399 request1.traffic_annotation =
16400 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016401 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1716402 TestCompletionCallback callback1;
16403 ASSERT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016404 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
mmenke666a6fea2015-12-19 04:16:3316405 // This pause is a hack to avoid running into https://crbug.com/497228.
16406 data1.RunUntilPaused();
16407 base::RunLoop().RunUntilIdle();
16408 data1.Resume();
[email protected]2d88e7d2012-07-19 17:55:1716409
robpercival214763f2016-07-01 23:27:0116410 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1716411 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
16412
16413 // Now, start the HTTP request
16414 HttpRequestInfo request2;
16415 request2.method = "GET";
16416 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1716417 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016418 request2.traffic_annotation =
16419 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016420 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1716421 TestCompletionCallback callback2;
16422 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016423 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5516424 base::RunLoop().RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1716425
16426 ASSERT_TRUE(callback2.have_result());
robpercival214763f2016-07-01 23:27:0116427 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1716428 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
16429}
16430
[email protected]85f97342013-04-17 06:12:2416431// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
16432// error) in SPDY session, removes the socket from pool and closes the SPDY
16433// session. Verify that new url's from the same HttpNetworkSession (and a new
16434// SpdySession) do work. http://crbug.com/224701
bncd16676a2016-07-20 16:23:0116435TEST_F(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2316436 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2416437
16438 MockRead reads1[] = {
16439 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
16440 };
16441
Ryan Sleevib8d7ea02018-05-07 20:01:0116442 SequencedSocketData data1(reads1, base::span<MockWrite>());
[email protected]85f97342013-04-17 06:12:2416443
Ryan Hamilton0239aac2018-05-19 00:03:1316444 spdy::SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4916445 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2416446 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4116447 CreateMockWrite(req2, 0),
[email protected]85f97342013-04-17 06:12:2416448 };
16449
Ryan Hamilton0239aac2018-05-19 00:03:1316450 spdy::SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
16451 spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]85f97342013-04-17 06:12:2416452 MockRead reads2[] = {
bncdf80d44fd2016-07-15 20:27:4116453 CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
16454 MockRead(ASYNC, OK, 3) // EOF
[email protected]85f97342013-04-17 06:12:2416455 };
16456
Ryan Sleevib8d7ea02018-05-07 20:01:0116457 SequencedSocketData data2(reads2, writes2);
[email protected]85f97342013-04-17 06:12:2416458
[email protected]85f97342013-04-17 06:12:2416459 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616460 ssl1.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5016461 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
16462 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]85f97342013-04-17 06:12:2416463
16464 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616465 ssl2.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5016466 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
16467 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]85f97342013-04-17 06:12:2416468
danakj1fd259a02016-04-16 03:17:0916469 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:5016470 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]85f97342013-04-17 06:12:2416471
16472 // Start the first transaction to set up the SpdySession and verify that
16473 // connection was closed.
16474 HttpRequestInfo request1;
16475 request1.method = "GET";
16476 request1.url = GURL(https_url);
16477 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016478 request1.traffic_annotation =
16479 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016480 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2416481 TestCompletionCallback callback1;
16482 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016483 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0116484 EXPECT_THAT(callback1.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]85f97342013-04-17 06:12:2416485
16486 // Now, start the second request and make sure it succeeds.
16487 HttpRequestInfo request2;
16488 request2.method = "GET";
16489 request2.url = GURL(https_url);
16490 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016491 request2.traffic_annotation =
16492 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016493 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2416494 TestCompletionCallback callback2;
16495 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016496 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
[email protected]85f97342013-04-17 06:12:2416497
robpercival214763f2016-07-01 23:27:0116498 ASSERT_THAT(callback2.WaitForResult(), IsOk());
[email protected]85f97342013-04-17 06:12:2416499 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
16500}
16501
bncd16676a2016-07-20 16:23:0116502TEST_F(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]483fa202013-05-14 01:07:0316503 ClientSocketPoolManager::set_max_sockets_per_group(
16504 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16505 ClientSocketPoolManager::set_max_sockets_per_pool(
16506 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16507
16508 // Use two different hosts with different IPs so they don't get pooled.
16509 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
16510 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
danakj1fd259a02016-04-16 03:17:0916511 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]483fa202013-05-14 01:07:0316512
16513 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616514 ssl1.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0316515 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616516 ssl2.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0316517 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
16518 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
16519
Ryan Hamilton0239aac2018-05-19 00:03:1316520 spdy::SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4916521 spdy_util_.ConstructSpdyGet("https://www.a.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0316522 MockWrite spdy1_writes[] = {
bncdf80d44fd2016-07-15 20:27:4116523 CreateMockWrite(host1_req, 0),
[email protected]483fa202013-05-14 01:07:0316524 };
Ryan Hamilton0239aac2018-05-19 00:03:1316525 spdy::SpdySerializedFrame host1_resp(
16526 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
16527 spdy::SpdySerializedFrame host1_resp_body(
bncdf80d44fd2016-07-15 20:27:4116528 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0316529 MockRead spdy1_reads[] = {
bncdf80d44fd2016-07-15 20:27:4116530 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
mmenkee24011922015-12-17 22:12:5916531 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0316532 };
16533
rdsmithebb50aa2015-11-12 03:44:3816534 // Use a separate test instance for the separate SpdySession that will be
16535 // created.
bncd16676a2016-07-20 16:23:0116536 SpdyTestUtil spdy_util_2;
Ryan Sleevib8d7ea02018-05-07 20:01:0116537 SequencedSocketData spdy1_data(spdy1_reads, spdy1_writes);
Bence Béky53a5aef2018-03-29 21:54:1216538 session_deps_.socket_factory->AddSocketDataProvider(&spdy1_data);
[email protected]483fa202013-05-14 01:07:0316539
Ryan Hamilton0239aac2018-05-19 00:03:1316540 spdy::SpdySerializedFrame host2_req(
bnc38dcd392016-02-09 23:19:4916541 spdy_util_2.ConstructSpdyGet("https://www.b.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0316542 MockWrite spdy2_writes[] = {
bncdf80d44fd2016-07-15 20:27:4116543 CreateMockWrite(host2_req, 0),
[email protected]483fa202013-05-14 01:07:0316544 };
Ryan Hamilton0239aac2018-05-19 00:03:1316545 spdy::SpdySerializedFrame host2_resp(
16546 spdy_util_2.ConstructSpdyGetReply(NULL, 0, 1));
16547 spdy::SpdySerializedFrame host2_resp_body(
bncdf80d44fd2016-07-15 20:27:4116548 spdy_util_2.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0316549 MockRead spdy2_reads[] = {
bncdf80d44fd2016-07-15 20:27:4116550 CreateMockRead(host2_resp, 1), CreateMockRead(host2_resp_body, 2),
mmenkee24011922015-12-17 22:12:5916551 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0316552 };
16553
Ryan Sleevib8d7ea02018-05-07 20:01:0116554 SequencedSocketData spdy2_data(spdy2_reads, spdy2_writes);
Bence Béky53a5aef2018-03-29 21:54:1216555 session_deps_.socket_factory->AddSocketDataProvider(&spdy2_data);
[email protected]483fa202013-05-14 01:07:0316556
16557 MockWrite http_write[] = {
16558 MockWrite("GET / HTTP/1.1\r\n"
16559 "Host: www.a.com\r\n"
16560 "Connection: keep-alive\r\n\r\n"),
16561 };
16562
16563 MockRead http_read[] = {
16564 MockRead("HTTP/1.1 200 OK\r\n"),
16565 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
16566 MockRead("Content-Length: 6\r\n\r\n"),
16567 MockRead("hello!"),
16568 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116569 StaticSocketDataProvider http_data(http_read, http_write);
[email protected]483fa202013-05-14 01:07:0316570 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16571
16572 HostPortPair host_port_pair_a("www.a.com", 443);
Matt Menke2436b2f2018-12-11 18:07:1116573 SpdySessionKey spdy_session_key_a(
16574 host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
16575 SpdySessionKey::IsProxySession::kFalse, SocketTag());
[email protected]483fa202013-05-14 01:07:0316576 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616577 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0316578
16579 TestCompletionCallback callback;
16580 HttpRequestInfo request1;
16581 request1.method = "GET";
16582 request1.url = GURL("https://www.a.com/");
16583 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016584 request1.traffic_annotation =
16585 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5816586 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1916587 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0316588
tfarina42834112016-09-22 13:38:2016589 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116590 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16591 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0316592
16593 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5216594 ASSERT_TRUE(response);
16595 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0216596 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0316597 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5216598 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]483fa202013-05-14 01:07:0316599
16600 std::string response_data;
robpercival214763f2016-07-01 23:27:0116601 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0316602 EXPECT_EQ("hello!", response_data);
16603 trans.reset();
16604 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2616605 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0316606
16607 HostPortPair host_port_pair_b("www.b.com", 443);
Matt Menke2436b2f2018-12-11 18:07:1116608 SpdySessionKey spdy_session_key_b(
16609 host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
16610 SpdySessionKey::IsProxySession::kFalse, SocketTag());
[email protected]483fa202013-05-14 01:07:0316611 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616612 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0316613 HttpRequestInfo request2;
16614 request2.method = "GET";
16615 request2.url = GURL("https://www.b.com/");
16616 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016617 request2.traffic_annotation =
16618 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5816619 trans =
Jeremy Roman0579ed62017-08-29 15:56:1916620 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0316621
tfarina42834112016-09-22 13:38:2016622 rv = trans->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116623 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16624 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0316625
16626 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5216627 ASSERT_TRUE(response);
16628 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0216629 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0316630 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5216631 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0116632 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0316633 EXPECT_EQ("hello!", response_data);
16634 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616635 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0316636 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2616637 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0316638
16639 HostPortPair host_port_pair_a1("www.a.com", 80);
Matt Menke2436b2f2018-12-11 18:07:1116640 SpdySessionKey spdy_session_key_a1(
16641 host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
16642 SpdySessionKey::IsProxySession::kFalse, SocketTag());
[email protected]483fa202013-05-14 01:07:0316643 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616644 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0316645 HttpRequestInfo request3;
16646 request3.method = "GET";
16647 request3.url = GURL("http://www.a.com/");
16648 request3.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016649 request3.traffic_annotation =
16650 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5816651 trans =
Jeremy Roman0579ed62017-08-29 15:56:1916652 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0316653
tfarina42834112016-09-22 13:38:2016654 rv = trans->Start(&request3, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116655 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16656 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0316657
16658 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5216659 ASSERT_TRUE(response);
16660 ASSERT_TRUE(response->headers);
[email protected]483fa202013-05-14 01:07:0316661 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
16662 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5216663 EXPECT_FALSE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0116664 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0316665 EXPECT_EQ("hello!", response_data);
16666 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616667 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[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}
16671
bncd16676a2016-07-20 16:23:0116672TEST_F(HttpNetworkTransactionTest, HttpSyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0416673 HttpRequestInfo request;
16674 request.method = "GET";
bncce36dca22015-04-21 22:11:2316675 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016676 request.traffic_annotation =
16677 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416678
danakj1fd259a02016-04-16 03:17:0916679 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616680 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416681
ttuttled9dbc652015-09-29 20:00:5916682 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0416683 StaticSocketDataProvider data;
16684 data.set_connect_data(mock_connect);
16685 session_deps_.socket_factory->AddSocketDataProvider(&data);
16686
16687 TestCompletionCallback callback;
16688
tfarina42834112016-09-22 13:38:2016689 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116690 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416691
16692 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116693 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0416694
[email protected]79e1fd62013-06-20 06:50:0416695 // We don't care whether this succeeds or fails, but it shouldn't crash.
16696 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616697 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4716698
16699 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1616700 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4716701 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0116702 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5916703
16704 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1616705 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5916706 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0416707}
16708
bncd16676a2016-07-20 16:23:0116709TEST_F(HttpNetworkTransactionTest, HttpAsyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0416710 HttpRequestInfo request;
16711 request.method = "GET";
bncce36dca22015-04-21 22:11:2316712 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016713 request.traffic_annotation =
16714 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416715
danakj1fd259a02016-04-16 03:17:0916716 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616717 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416718
ttuttled9dbc652015-09-29 20:00:5916719 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0416720 StaticSocketDataProvider data;
16721 data.set_connect_data(mock_connect);
16722 session_deps_.socket_factory->AddSocketDataProvider(&data);
16723
16724 TestCompletionCallback callback;
16725
tfarina42834112016-09-22 13:38:2016726 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116727 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416728
16729 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116730 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0416731
[email protected]79e1fd62013-06-20 06:50:0416732 // We don't care whether this succeeds or fails, but it shouldn't crash.
16733 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616734 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4716735
16736 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1616737 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4716738 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0116739 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5916740
16741 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1616742 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5916743 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0416744}
16745
bncd16676a2016-07-20 16:23:0116746TEST_F(HttpNetworkTransactionTest, HttpSyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0416747 HttpRequestInfo request;
16748 request.method = "GET";
bncce36dca22015-04-21 22:11:2316749 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016750 request.traffic_annotation =
16751 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416752
danakj1fd259a02016-04-16 03:17:0916753 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616754 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416755
16756 MockWrite data_writes[] = {
16757 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16758 };
16759 MockRead data_reads[] = {
16760 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
16761 };
16762
Ryan Sleevib8d7ea02018-05-07 20:01:0116763 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0416764 session_deps_.socket_factory->AddSocketDataProvider(&data);
16765
16766 TestCompletionCallback callback;
16767
tfarina42834112016-09-22 13:38:2016768 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116769 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416770
16771 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116772 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416773
[email protected]79e1fd62013-06-20 06:50:0416774 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616775 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416776 EXPECT_TRUE(request_headers.HasHeader("Host"));
16777}
16778
bncd16676a2016-07-20 16:23:0116779TEST_F(HttpNetworkTransactionTest, HttpAsyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0416780 HttpRequestInfo request;
16781 request.method = "GET";
bncce36dca22015-04-21 22:11:2316782 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016783 request.traffic_annotation =
16784 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416785
danakj1fd259a02016-04-16 03:17:0916786 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616787 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416788
16789 MockWrite data_writes[] = {
16790 MockWrite(ASYNC, ERR_CONNECTION_RESET),
16791 };
16792 MockRead data_reads[] = {
16793 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
16794 };
16795
Ryan Sleevib8d7ea02018-05-07 20:01:0116796 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0416797 session_deps_.socket_factory->AddSocketDataProvider(&data);
16798
16799 TestCompletionCallback callback;
16800
tfarina42834112016-09-22 13:38:2016801 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116802 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416803
16804 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116805 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416806
[email protected]79e1fd62013-06-20 06:50:0416807 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616808 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416809 EXPECT_TRUE(request_headers.HasHeader("Host"));
16810}
16811
bncd16676a2016-07-20 16:23:0116812TEST_F(HttpNetworkTransactionTest, HttpSyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0416813 HttpRequestInfo request;
16814 request.method = "GET";
bncce36dca22015-04-21 22:11:2316815 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016816 request.traffic_annotation =
16817 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416818
danakj1fd259a02016-04-16 03:17:0916819 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616820 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416821
16822 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2316823 MockWrite(
16824 "GET / HTTP/1.1\r\n"
16825 "Host: www.example.org\r\n"
16826 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0416827 };
16828 MockRead data_reads[] = {
16829 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
16830 };
16831
Ryan Sleevib8d7ea02018-05-07 20:01:0116832 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0416833 session_deps_.socket_factory->AddSocketDataProvider(&data);
16834
16835 TestCompletionCallback callback;
16836
tfarina42834112016-09-22 13:38:2016837 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116838 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416839
16840 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116841 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416842
[email protected]79e1fd62013-06-20 06:50:0416843 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616844 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416845 EXPECT_TRUE(request_headers.HasHeader("Host"));
16846}
16847
bncd16676a2016-07-20 16:23:0116848TEST_F(HttpNetworkTransactionTest, HttpAsyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0416849 HttpRequestInfo request;
16850 request.method = "GET";
bncce36dca22015-04-21 22:11:2316851 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016852 request.traffic_annotation =
16853 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416854
danakj1fd259a02016-04-16 03:17:0916855 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616856 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416857
16858 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2316859 MockWrite(
16860 "GET / HTTP/1.1\r\n"
16861 "Host: www.example.org\r\n"
16862 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0416863 };
16864 MockRead data_reads[] = {
16865 MockRead(ASYNC, ERR_CONNECTION_RESET),
16866 };
16867
Ryan Sleevib8d7ea02018-05-07 20:01:0116868 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0416869 session_deps_.socket_factory->AddSocketDataProvider(&data);
16870
16871 TestCompletionCallback callback;
16872
tfarina42834112016-09-22 13:38:2016873 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116874 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416875
16876 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116877 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416878
[email protected]79e1fd62013-06-20 06:50:0416879 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616880 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416881 EXPECT_TRUE(request_headers.HasHeader("Host"));
16882}
16883
bncd16676a2016-07-20 16:23:0116884TEST_F(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
[email protected]79e1fd62013-06-20 06:50:0416885 HttpRequestInfo request;
16886 request.method = "GET";
bncce36dca22015-04-21 22:11:2316887 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0416888 request.extra_headers.SetHeader("X-Foo", "bar");
Ramin Halavatib5e433e2018-02-07 07:41:1016889 request.traffic_annotation =
16890 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416891
danakj1fd259a02016-04-16 03:17:0916892 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616893 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416894
16895 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2316896 MockWrite(
16897 "GET / HTTP/1.1\r\n"
16898 "Host: www.example.org\r\n"
16899 "Connection: keep-alive\r\n"
16900 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0416901 };
16902 MockRead data_reads[] = {
16903 MockRead("HTTP/1.1 200 OK\r\n"
16904 "Content-Length: 5\r\n\r\n"
16905 "hello"),
16906 MockRead(ASYNC, ERR_UNEXPECTED),
16907 };
16908
Ryan Sleevib8d7ea02018-05-07 20:01:0116909 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0416910 session_deps_.socket_factory->AddSocketDataProvider(&data);
16911
16912 TestCompletionCallback callback;
16913
tfarina42834112016-09-22 13:38:2016914 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116915 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416916
16917 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116918 EXPECT_THAT(rv, IsOk());
[email protected]79e1fd62013-06-20 06:50:0416919
16920 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616921 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416922 std::string foo;
16923 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
16924 EXPECT_EQ("bar", foo);
16925}
16926
[email protected]043b68c82013-08-22 23:41:5216927// Tests that when a used socket is returned to the SSL socket pool, it's closed
16928// if the transport socket pool is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0116929TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
[email protected]043b68c82013-08-22 23:41:5216930 ClientSocketPoolManager::set_max_sockets_per_group(
16931 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16932 ClientSocketPoolManager::set_max_sockets_per_pool(
16933 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16934
16935 // Set up SSL request.
16936
16937 HttpRequestInfo ssl_request;
16938 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2316939 ssl_request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016940 ssl_request.traffic_annotation =
16941 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5216942
16943 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2316944 MockWrite(
16945 "GET / HTTP/1.1\r\n"
16946 "Host: www.example.org\r\n"
16947 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5216948 };
16949 MockRead ssl_reads[] = {
16950 MockRead("HTTP/1.1 200 OK\r\n"),
16951 MockRead("Content-Length: 11\r\n\r\n"),
16952 MockRead("hello world"),
16953 MockRead(SYNCHRONOUS, OK),
16954 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116955 StaticSocketDataProvider ssl_data(ssl_reads, ssl_writes);
[email protected]043b68c82013-08-22 23:41:5216956 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
16957
16958 SSLSocketDataProvider ssl(ASYNC, OK);
16959 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16960
16961 // Set up HTTP request.
16962
16963 HttpRequestInfo http_request;
16964 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2316965 http_request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016966 http_request.traffic_annotation =
16967 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5216968
16969 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2316970 MockWrite(
16971 "GET / HTTP/1.1\r\n"
16972 "Host: www.example.org\r\n"
16973 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5216974 };
16975 MockRead http_reads[] = {
16976 MockRead("HTTP/1.1 200 OK\r\n"),
16977 MockRead("Content-Length: 7\r\n\r\n"),
16978 MockRead("falafel"),
16979 MockRead(SYNCHRONOUS, OK),
16980 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116981 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]043b68c82013-08-22 23:41:5216982 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16983
danakj1fd259a02016-04-16 03:17:0916984 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5216985
16986 // Start the SSL request.
16987 TestCompletionCallback ssl_callback;
bnc691fda62016-08-12 00:43:1616988 HttpNetworkTransaction ssl_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016989 ASSERT_EQ(ERR_IO_PENDING,
16990 ssl_trans.Start(&ssl_request, ssl_callback.callback(),
16991 NetLogWithSource()));
[email protected]043b68c82013-08-22 23:41:5216992
16993 // Start the HTTP request. Pool should stall.
16994 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1616995 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016996 ASSERT_EQ(ERR_IO_PENDING,
16997 http_trans.Start(&http_request, http_callback.callback(),
16998 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4116999 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5217000
17001 // Wait for response from SSL request.
robpercival214763f2016-07-01 23:27:0117002 ASSERT_THAT(ssl_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5217003 std::string response_data;
bnc691fda62016-08-12 00:43:1617004 ASSERT_THAT(ReadTransaction(&ssl_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5217005 EXPECT_EQ("hello world", response_data);
17006
17007 // The SSL socket should automatically be closed, so the HTTP request can
17008 // start.
Matt Menke9d5e2c92019-02-05 01:42:2317009 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
dcheng48459ac22014-08-26 00:46:4117010 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5217011
17012 // The HTTP request can now complete.
robpercival214763f2016-07-01 23:27:0117013 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
bnc691fda62016-08-12 00:43:1617014 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5217015 EXPECT_EQ("falafel", response_data);
17016
dcheng48459ac22014-08-26 00:46:4117017 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5217018}
17019
17020// Tests that when a SSL connection is established but there's no corresponding
17021// request that needs it, the new socket is closed if the transport socket pool
17022// is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0117023TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
[email protected]043b68c82013-08-22 23:41:5217024 ClientSocketPoolManager::set_max_sockets_per_group(
17025 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
17026 ClientSocketPoolManager::set_max_sockets_per_pool(
17027 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
17028
17029 // Set up an ssl request.
17030
17031 HttpRequestInfo ssl_request;
17032 ssl_request.method = "GET";
17033 ssl_request.url = GURL("https://www.foopy.com/");
Ramin Halavatib5e433e2018-02-07 07:41:1017034 ssl_request.traffic_annotation =
17035 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5217036
17037 // No data will be sent on the SSL socket.
17038 StaticSocketDataProvider ssl_data;
17039 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
17040
17041 SSLSocketDataProvider ssl(ASYNC, OK);
17042 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
17043
17044 // Set up HTTP request.
17045
17046 HttpRequestInfo http_request;
17047 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2317048 http_request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017049 http_request.traffic_annotation =
17050 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5217051
17052 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2317053 MockWrite(
17054 "GET / HTTP/1.1\r\n"
17055 "Host: www.example.org\r\n"
17056 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5217057 };
17058 MockRead http_reads[] = {
17059 MockRead("HTTP/1.1 200 OK\r\n"),
17060 MockRead("Content-Length: 7\r\n\r\n"),
17061 MockRead("falafel"),
17062 MockRead(SYNCHRONOUS, OK),
17063 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117064 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]043b68c82013-08-22 23:41:5217065 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
17066
danakj1fd259a02016-04-16 03:17:0917067 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5217068
17069 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
17070 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2917071 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
nharper8cdb0fb2016-04-22 21:34:5917072 http_stream_factory->PreconnectStreams(1, ssl_request);
Matt Menke9d5e2c92019-02-05 01:42:2317073 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5217074
17075 // Start the HTTP request. Pool should stall.
17076 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1617077 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2017078 ASSERT_EQ(ERR_IO_PENDING,
17079 http_trans.Start(&http_request, http_callback.callback(),
17080 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4117081 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5217082
17083 // The SSL connection will automatically be closed once the connection is
17084 // established, to let the HTTP request start.
robpercival214763f2016-07-01 23:27:0117085 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5217086 std::string response_data;
bnc691fda62016-08-12 00:43:1617087 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5217088 EXPECT_EQ("falafel", response_data);
17089
dcheng48459ac22014-08-26 00:46:4117090 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5217091}
17092
bncd16676a2016-07-20 16:23:0117093TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0917094 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217095 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917096 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217097 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417098
17099 HttpRequestInfo request;
17100 request.method = "POST";
17101 request.url = GURL("http://www.foo.com/");
17102 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017103 request.traffic_annotation =
17104 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417105
danakj1fd259a02016-04-16 03:17:0917106 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617107 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417108 // Send headers successfully, but get an error while sending the body.
17109 MockWrite data_writes[] = {
17110 MockWrite("POST / HTTP/1.1\r\n"
17111 "Host: www.foo.com\r\n"
17112 "Connection: keep-alive\r\n"
17113 "Content-Length: 3\r\n\r\n"),
17114 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17115 };
17116
17117 MockRead data_reads[] = {
17118 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
17119 MockRead("hello world"),
17120 MockRead(SYNCHRONOUS, OK),
17121 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117122 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417123 session_deps_.socket_factory->AddSocketDataProvider(&data);
17124
17125 TestCompletionCallback callback;
17126
tfarina42834112016-09-22 13:38:2017127 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117128 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417129
17130 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117131 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417132
bnc691fda62016-08-12 00:43:1617133 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5217134 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5417135
wezca1070932016-05-26 20:30:5217136 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5417137 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
17138
17139 std::string response_data;
bnc691fda62016-08-12 00:43:1617140 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0117141 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417142 EXPECT_EQ("hello world", response_data);
17143}
17144
17145// This test makes sure the retry logic doesn't trigger when reading an error
17146// response from a server that rejected a POST with a CONNECTION_RESET.
bncd16676a2016-07-20 16:23:0117147TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5417148 PostReadsErrorResponseAfterResetOnReusedSocket) {
danakj1fd259a02016-04-16 03:17:0917149 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5417150 MockWrite data_writes[] = {
17151 MockWrite("GET / HTTP/1.1\r\n"
17152 "Host: www.foo.com\r\n"
17153 "Connection: keep-alive\r\n\r\n"),
17154 MockWrite("POST / HTTP/1.1\r\n"
17155 "Host: www.foo.com\r\n"
17156 "Connection: keep-alive\r\n"
17157 "Content-Length: 3\r\n\r\n"),
17158 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17159 };
17160
17161 MockRead data_reads[] = {
17162 MockRead("HTTP/1.1 200 Peachy\r\n"
17163 "Content-Length: 14\r\n\r\n"),
17164 MockRead("first response"),
17165 MockRead("HTTP/1.1 400 Not OK\r\n"
17166 "Content-Length: 15\r\n\r\n"),
17167 MockRead("second response"),
17168 MockRead(SYNCHRONOUS, OK),
17169 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117170 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417171 session_deps_.socket_factory->AddSocketDataProvider(&data);
17172
17173 TestCompletionCallback callback;
17174 HttpRequestInfo request1;
17175 request1.method = "GET";
17176 request1.url = GURL("http://www.foo.com/");
17177 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1017178 request1.traffic_annotation =
17179 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417180
bnc87dcefc2017-05-25 12:47:5817181 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:1917182 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2017183 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117184 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417185
17186 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117187 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417188
17189 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:5217190 ASSERT_TRUE(response1);
[email protected]02d74a02014-04-23 18:10:5417191
wezca1070932016-05-26 20:30:5217192 EXPECT_TRUE(response1->headers);
[email protected]02d74a02014-04-23 18:10:5417193 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
17194
17195 std::string response_data1;
17196 rv = ReadTransaction(trans1.get(), &response_data1);
robpercival214763f2016-07-01 23:27:0117197 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417198 EXPECT_EQ("first response", response_data1);
17199 // Delete the transaction to release the socket back into the socket pool.
17200 trans1.reset();
17201
danakj1fd259a02016-04-16 03:17:0917202 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217203 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917204 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217205 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417206
17207 HttpRequestInfo request2;
17208 request2.method = "POST";
17209 request2.url = GURL("http://www.foo.com/");
17210 request2.upload_data_stream = &upload_data_stream;
17211 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1017212 request2.traffic_annotation =
17213 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417214
bnc691fda62016-08-12 00:43:1617215 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2017216 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117217 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417218
17219 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117220 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417221
bnc691fda62016-08-12 00:43:1617222 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5217223 ASSERT_TRUE(response2);
[email protected]02d74a02014-04-23 18:10:5417224
wezca1070932016-05-26 20:30:5217225 EXPECT_TRUE(response2->headers);
[email protected]02d74a02014-04-23 18:10:5417226 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
17227
17228 std::string response_data2;
bnc691fda62016-08-12 00:43:1617229 rv = ReadTransaction(&trans2, &response_data2);
robpercival214763f2016-07-01 23:27:0117230 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417231 EXPECT_EQ("second response", response_data2);
17232}
17233
bncd16676a2016-07-20 16:23:0117234TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5417235 PostReadsErrorResponseAfterResetPartialBodySent) {
danakj1fd259a02016-04-16 03:17:0917236 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217237 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917238 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217239 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417240
17241 HttpRequestInfo request;
17242 request.method = "POST";
17243 request.url = GURL("http://www.foo.com/");
17244 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017245 request.traffic_annotation =
17246 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417247
danakj1fd259a02016-04-16 03:17:0917248 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617249 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417250 // Send headers successfully, but get an error while sending the body.
17251 MockWrite data_writes[] = {
17252 MockWrite("POST / HTTP/1.1\r\n"
17253 "Host: www.foo.com\r\n"
17254 "Connection: keep-alive\r\n"
17255 "Content-Length: 3\r\n\r\n"
17256 "fo"),
17257 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17258 };
17259
17260 MockRead data_reads[] = {
17261 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
17262 MockRead("hello world"),
17263 MockRead(SYNCHRONOUS, OK),
17264 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117265 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417266 session_deps_.socket_factory->AddSocketDataProvider(&data);
17267
17268 TestCompletionCallback callback;
17269
tfarina42834112016-09-22 13:38:2017270 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117271 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417272
17273 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117274 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417275
bnc691fda62016-08-12 00:43:1617276 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5217277 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5417278
wezca1070932016-05-26 20:30:5217279 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5417280 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
17281
17282 std::string response_data;
bnc691fda62016-08-12 00:43:1617283 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0117284 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417285 EXPECT_EQ("hello world", response_data);
17286}
17287
17288// This tests the more common case than the previous test, where headers and
17289// body are not merged into a single request.
bncd16676a2016-07-20 16:23:0117290TEST_F(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
mmenkecbc2b712014-10-09 20:29:0717291 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5417292
17293 HttpRequestInfo request;
17294 request.method = "POST";
17295 request.url = GURL("http://www.foo.com/");
17296 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017297 request.traffic_annotation =
17298 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417299
danakj1fd259a02016-04-16 03:17:0917300 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617301 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417302 // Send headers successfully, but get an error while sending the body.
17303 MockWrite data_writes[] = {
17304 MockWrite("POST / HTTP/1.1\r\n"
17305 "Host: www.foo.com\r\n"
17306 "Connection: keep-alive\r\n"
17307 "Transfer-Encoding: chunked\r\n\r\n"),
17308 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17309 };
17310
17311 MockRead data_reads[] = {
17312 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
17313 MockRead("hello world"),
17314 MockRead(SYNCHRONOUS, OK),
17315 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117316 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417317 session_deps_.socket_factory->AddSocketDataProvider(&data);
17318
17319 TestCompletionCallback callback;
17320
tfarina42834112016-09-22 13:38:2017321 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117322 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417323 // Make sure the headers are sent before adding a chunk. This ensures that
17324 // they can't be merged with the body in a single send. Not currently
17325 // necessary since a chunked body is never merged with headers, but this makes
17326 // the test more future proof.
17327 base::RunLoop().RunUntilIdle();
17328
mmenkecbc2b712014-10-09 20:29:0717329 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5417330
17331 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117332 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417333
bnc691fda62016-08-12 00:43:1617334 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5217335 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5417336
wezca1070932016-05-26 20:30:5217337 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5417338 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
17339
17340 std::string response_data;
bnc691fda62016-08-12 00:43:1617341 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0117342 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417343 EXPECT_EQ("hello world", response_data);
17344}
17345
bncd16676a2016-07-20 16:23:0117346TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0917347 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217348 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917349 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217350 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417351
17352 HttpRequestInfo request;
17353 request.method = "POST";
17354 request.url = GURL("http://www.foo.com/");
17355 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017356 request.traffic_annotation =
17357 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417358
danakj1fd259a02016-04-16 03:17:0917359 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617360 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417361
17362 MockWrite data_writes[] = {
17363 MockWrite("POST / HTTP/1.1\r\n"
17364 "Host: www.foo.com\r\n"
17365 "Connection: keep-alive\r\n"
17366 "Content-Length: 3\r\n\r\n"),
17367 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17368 };
17369
17370 MockRead data_reads[] = {
17371 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
17372 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
17373 MockRead("hello world"),
17374 MockRead(SYNCHRONOUS, OK),
17375 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117376 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417377 session_deps_.socket_factory->AddSocketDataProvider(&data);
17378
17379 TestCompletionCallback callback;
17380
tfarina42834112016-09-22 13:38:2017381 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117382 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417383
17384 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117385 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417386
bnc691fda62016-08-12 00:43:1617387 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5217388 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5417389
wezca1070932016-05-26 20:30:5217390 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5417391 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
17392
17393 std::string response_data;
bnc691fda62016-08-12 00:43:1617394 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0117395 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417396 EXPECT_EQ("hello world", response_data);
17397}
17398
bncd16676a2016-07-20 16:23:0117399TEST_F(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0917400 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217401 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917402 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217403 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417404
17405 HttpRequestInfo request;
17406 request.method = "POST";
17407 request.url = GURL("http://www.foo.com/");
17408 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017409 request.traffic_annotation =
17410 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417411
danakj1fd259a02016-04-16 03:17:0917412 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617413 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417414 // Send headers successfully, but get an error while sending the body.
17415 MockWrite data_writes[] = {
17416 MockWrite("POST / HTTP/1.1\r\n"
17417 "Host: www.foo.com\r\n"
17418 "Connection: keep-alive\r\n"
17419 "Content-Length: 3\r\n\r\n"),
17420 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17421 };
17422
17423 MockRead data_reads[] = {
17424 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
17425 MockRead("hello world"),
17426 MockRead(SYNCHRONOUS, OK),
17427 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117428 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417429 session_deps_.socket_factory->AddSocketDataProvider(&data);
17430
17431 TestCompletionCallback callback;
17432
tfarina42834112016-09-22 13:38:2017433 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117434 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417435
17436 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117437 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417438}
17439
bncd16676a2016-07-20 16:23:0117440TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5417441 PostIgnoresNonErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0917442 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217443 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917444 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217445 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417446
17447 HttpRequestInfo request;
17448 request.method = "POST";
17449 request.url = GURL("http://www.foo.com/");
17450 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017451 request.traffic_annotation =
17452 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417453
danakj1fd259a02016-04-16 03:17:0917454 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617455 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417456 // Send headers successfully, but get an error while sending the body.
17457 MockWrite data_writes[] = {
17458 MockWrite("POST / HTTP/1.1\r\n"
17459 "Host: www.foo.com\r\n"
17460 "Connection: keep-alive\r\n"
17461 "Content-Length: 3\r\n\r\n"),
17462 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17463 };
17464
17465 MockRead data_reads[] = {
17466 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
17467 MockRead("HTTP/1.0 302 Redirect\r\n"),
17468 MockRead("Location: http://somewhere-else.com/\r\n"),
17469 MockRead("Content-Length: 0\r\n\r\n"),
17470 MockRead(SYNCHRONOUS, OK),
17471 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117472 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417473 session_deps_.socket_factory->AddSocketDataProvider(&data);
17474
17475 TestCompletionCallback callback;
17476
tfarina42834112016-09-22 13:38:2017477 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117478 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417479
17480 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117481 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417482}
17483
bncd16676a2016-07-20 16:23:0117484TEST_F(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0917485 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217486 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917487 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217488 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417489
17490 HttpRequestInfo request;
17491 request.method = "POST";
17492 request.url = GURL("http://www.foo.com/");
17493 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017494 request.traffic_annotation =
17495 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417496
danakj1fd259a02016-04-16 03:17:0917497 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617498 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417499 // Send headers successfully, but get an error while sending the body.
17500 MockWrite data_writes[] = {
17501 MockWrite("POST / HTTP/1.1\r\n"
17502 "Host: www.foo.com\r\n"
17503 "Connection: keep-alive\r\n"
17504 "Content-Length: 3\r\n\r\n"),
17505 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17506 };
17507
17508 MockRead data_reads[] = {
17509 MockRead("HTTP 0.9 rocks!"),
17510 MockRead(SYNCHRONOUS, OK),
17511 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117512 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417513 session_deps_.socket_factory->AddSocketDataProvider(&data);
17514
17515 TestCompletionCallback callback;
17516
tfarina42834112016-09-22 13:38:2017517 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117518 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417519
17520 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117521 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417522}
17523
bncd16676a2016-07-20 16:23:0117524TEST_F(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
danakj1fd259a02016-04-16 03:17:0917525 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217526 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917527 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217528 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417529
17530 HttpRequestInfo request;
17531 request.method = "POST";
17532 request.url = GURL("http://www.foo.com/");
17533 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017534 request.traffic_annotation =
17535 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417536
danakj1fd259a02016-04-16 03:17:0917537 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617538 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417539 // Send headers successfully, but get an error while sending the body.
17540 MockWrite data_writes[] = {
17541 MockWrite("POST / HTTP/1.1\r\n"
17542 "Host: www.foo.com\r\n"
17543 "Connection: keep-alive\r\n"
17544 "Content-Length: 3\r\n\r\n"),
17545 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17546 };
17547
17548 MockRead data_reads[] = {
17549 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
17550 MockRead(SYNCHRONOUS, OK),
17551 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117552 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417553 session_deps_.socket_factory->AddSocketDataProvider(&data);
17554
17555 TestCompletionCallback callback;
17556
tfarina42834112016-09-22 13:38:2017557 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117558 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417559
17560 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117561 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417562}
17563
Bence Békydca6bd92018-01-30 13:43:0617564#if BUILDFLAG(ENABLE_WEBSOCKETS)
17565
17566namespace {
17567
17568void AddWebSocketHeaders(HttpRequestHeaders* headers) {
17569 headers->SetHeader("Connection", "Upgrade");
17570 headers->SetHeader("Upgrade", "websocket");
17571 headers->SetHeader("Origin", "http://www.example.org");
17572 headers->SetHeader("Sec-WebSocket-Version", "13");
Bence Békydca6bd92018-01-30 13:43:0617573}
17574
17575} // namespace
17576
17577TEST_F(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
Bence Béky2fcf4fa2018-04-06 20:06:0117578 for (bool secure : {true, false}) {
17579 MockWrite data_writes[] = {
17580 MockWrite("GET / HTTP/1.1\r\n"
17581 "Host: www.example.org\r\n"
17582 "Connection: Upgrade\r\n"
17583 "Upgrade: websocket\r\n"
17584 "Origin: http://www.example.org\r\n"
17585 "Sec-WebSocket-Version: 13\r\n"
17586 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
17587 "Sec-WebSocket-Extensions: permessage-deflate; "
17588 "client_max_window_bits\r\n\r\n")};
17589
17590 MockRead data_reads[] = {
17591 MockRead("HTTP/1.1 101 Switching Protocols\r\n"
17592 "Upgrade: websocket\r\n"
17593 "Connection: Upgrade\r\n"
17594 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
17595
Ryan Sleevib8d7ea02018-05-07 20:01:0117596 StaticSocketDataProvider data(data_reads, data_writes);
Bence Béky2fcf4fa2018-04-06 20:06:0117597 session_deps_.socket_factory->AddSocketDataProvider(&data);
17598 SSLSocketDataProvider ssl(ASYNC, OK);
17599 if (secure)
17600 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
Bence Békydca6bd92018-01-30 13:43:0617601
17602 HttpRequestInfo request;
17603 request.method = "GET";
Bence Béky2fcf4fa2018-04-06 20:06:0117604 request.url =
17605 GURL(secure ? "ws://www.example.org/" : "wss://www.example.org/");
17606 AddWebSocketHeaders(&request.extra_headers);
Ramin Halavatib5e433e2018-02-07 07:41:1017607 request.traffic_annotation =
17608 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Békydca6bd92018-01-30 13:43:0617609
Bence Béky2fcf4fa2018-04-06 20:06:0117610 TestWebSocketHandshakeStreamCreateHelper
17611 websocket_handshake_stream_create_helper;
Bence Béky8d1c6052018-02-07 12:48:1517612
Bence Béky2fcf4fa2018-04-06 20:06:0117613 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Bence Békydca6bd92018-01-30 13:43:0617614 HttpNetworkTransaction trans(LOW, session.get());
17615 trans.SetWebSocketHandshakeStreamCreateHelper(
Bence Béky2fcf4fa2018-04-06 20:06:0117616 &websocket_handshake_stream_create_helper);
Bence Békydca6bd92018-01-30 13:43:0617617
17618 TestCompletionCallback callback;
Bence Béky2fcf4fa2018-04-06 20:06:0117619 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17620 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Bence Békydca6bd92018-01-30 13:43:0617621
Bence Béky2fcf4fa2018-04-06 20:06:0117622 const HttpStreamRequest* stream_request = trans.stream_request_.get();
17623 ASSERT_TRUE(stream_request);
17624 EXPECT_EQ(&websocket_handshake_stream_create_helper,
17625 stream_request->websocket_handshake_stream_create_helper());
17626
17627 rv = callback.WaitForResult();
17628 EXPECT_THAT(rv, IsOk());
17629
17630 EXPECT_TRUE(data.AllReadDataConsumed());
17631 EXPECT_TRUE(data.AllWriteDataConsumed());
Bence Békydca6bd92018-01-30 13:43:0617632 }
17633}
17634
Adam Rice425cf122015-01-19 06:18:2417635// Verify that proxy headers are not sent to the destination server when
17636// establishing a tunnel for a secure WebSocket connection.
bncd16676a2016-07-20 16:23:0117637TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
Adam Rice425cf122015-01-19 06:18:2417638 HttpRequestInfo request;
17639 request.method = "GET";
bncce36dca22015-04-21 22:11:2317640 request.url = GURL("wss://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017641 request.traffic_annotation =
17642 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417643 AddWebSocketHeaders(&request.extra_headers);
17644
17645 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:5917646 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4917647 ProxyResolutionService::CreateFixedFromPacResult(
17648 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417649
danakj1fd259a02016-04-16 03:17:0917650 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2417651
17652 // Since a proxy is configured, try to establish a tunnel.
17653 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1717654 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
17655 "Host: www.example.org:443\r\n"
17656 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417657
17658 // After calling trans->RestartWithAuth(), this is the request we should
17659 // be issuing -- the final header line contains the credentials.
rsleevidb16bb02015-11-12 23:47:1717660 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
17661 "Host: www.example.org:443\r\n"
17662 "Proxy-Connection: keep-alive\r\n"
17663 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417664
rsleevidb16bb02015-11-12 23:47:1717665 MockWrite("GET / HTTP/1.1\r\n"
17666 "Host: www.example.org\r\n"
17667 "Connection: Upgrade\r\n"
17668 "Upgrade: websocket\r\n"
17669 "Origin: http://www.example.org\r\n"
17670 "Sec-WebSocket-Version: 13\r\n"
Bence Béky8d1c6052018-02-07 12:48:1517671 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
17672 "Sec-WebSocket-Extensions: permessage-deflate; "
17673 "client_max_window_bits\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417674
17675 // The proxy responds to the connect with a 407, using a persistent
17676 // connection.
17677 MockRead data_reads[] = {
17678 // No credentials.
Bence Béky8d1c6052018-02-07 12:48:1517679 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"
17680 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
17681 "Content-Length: 0\r\n"
17682 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417683
17684 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
17685
Bence Béky8d1c6052018-02-07 12:48:1517686 MockRead("HTTP/1.1 101 Switching Protocols\r\n"
17687 "Upgrade: websocket\r\n"
17688 "Connection: Upgrade\r\n"
17689 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417690
Ryan Sleevib8d7ea02018-05-07 20:01:0117691 StaticSocketDataProvider data(data_reads, data_writes);
Adam Rice425cf122015-01-19 06:18:2417692 session_deps_.socket_factory->AddSocketDataProvider(&data);
17693 SSLSocketDataProvider ssl(ASYNC, OK);
17694 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
17695
Bence Béky8d1c6052018-02-07 12:48:1517696 TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
17697
bnc87dcefc2017-05-25 12:47:5817698 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917699 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2417700 trans->SetWebSocketHandshakeStreamCreateHelper(
17701 &websocket_stream_create_helper);
17702
17703 {
17704 TestCompletionCallback callback;
17705
tfarina42834112016-09-22 13:38:2017706 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117707 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2417708
17709 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117710 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2417711 }
17712
17713 const HttpResponseInfo* response = trans->GetResponseInfo();
17714 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5217715 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2417716 EXPECT_EQ(407, response->headers->response_code());
17717
17718 {
17719 TestCompletionCallback callback;
17720
17721 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
17722 callback.callback());
robpercival214763f2016-07-01 23:27:0117723 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2417724
17725 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117726 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2417727 }
17728
17729 response = trans->GetResponseInfo();
17730 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5217731 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2417732
17733 EXPECT_EQ(101, response->headers->response_code());
17734
17735 trans.reset();
17736 session->CloseAllConnections();
17737}
17738
17739// Verify that proxy headers are not sent to the destination server when
17740// establishing a tunnel for an insecure WebSocket connection.
17741// This requires the authentication info to be injected into the auth cache
17742// due to crbug.com/395064
17743// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
bncd16676a2016-07-20 16:23:0117744TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
Adam Rice425cf122015-01-19 06:18:2417745 HttpRequestInfo request;
17746 request.method = "GET";
bncce36dca22015-04-21 22:11:2317747 request.url = GURL("ws://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017748 request.traffic_annotation =
17749 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417750 AddWebSocketHeaders(&request.extra_headers);
17751
17752 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:5917753 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4917754 ProxyResolutionService::CreateFixedFromPacResult(
17755 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417756
danakj1fd259a02016-04-16 03:17:0917757 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2417758
17759 MockWrite data_writes[] = {
17760 // Try to establish a tunnel for the WebSocket connection, with
17761 // credentials. Because WebSockets have a separate set of socket pools,
17762 // they cannot and will not use the same TCP/IP connection as the
17763 // preflight HTTP request.
Bence Béky8d1c6052018-02-07 12:48:1517764 MockWrite("CONNECT www.example.org:80 HTTP/1.1\r\n"
17765 "Host: www.example.org:80\r\n"
17766 "Proxy-Connection: keep-alive\r\n"
17767 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417768
Bence Béky8d1c6052018-02-07 12:48:1517769 MockWrite("GET / HTTP/1.1\r\n"
17770 "Host: www.example.org\r\n"
17771 "Connection: Upgrade\r\n"
17772 "Upgrade: websocket\r\n"
17773 "Origin: http://www.example.org\r\n"
17774 "Sec-WebSocket-Version: 13\r\n"
17775 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
17776 "Sec-WebSocket-Extensions: permessage-deflate; "
17777 "client_max_window_bits\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417778
17779 MockRead data_reads[] = {
17780 // HTTP CONNECT with credentials.
17781 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
17782
17783 // WebSocket connection established inside tunnel.
Bence Béky8d1c6052018-02-07 12:48:1517784 MockRead("HTTP/1.1 101 Switching Protocols\r\n"
17785 "Upgrade: websocket\r\n"
17786 "Connection: Upgrade\r\n"
17787 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417788
Ryan Sleevib8d7ea02018-05-07 20:01:0117789 StaticSocketDataProvider data(data_reads, data_writes);
Adam Rice425cf122015-01-19 06:18:2417790 session_deps_.socket_factory->AddSocketDataProvider(&data);
17791
17792 session->http_auth_cache()->Add(
17793 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
17794 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
17795
Bence Béky8d1c6052018-02-07 12:48:1517796 TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
17797
bnc87dcefc2017-05-25 12:47:5817798 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917799 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2417800 trans->SetWebSocketHandshakeStreamCreateHelper(
17801 &websocket_stream_create_helper);
17802
17803 TestCompletionCallback callback;
17804
tfarina42834112016-09-22 13:38:2017805 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117806 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2417807
17808 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117809 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2417810
17811 const HttpResponseInfo* response = trans->GetResponseInfo();
17812 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5217813 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2417814
17815 EXPECT_EQ(101, response->headers->response_code());
17816
17817 trans.reset();
17818 session->CloseAllConnections();
17819}
17820
Bence Békydca6bd92018-01-30 13:43:0617821#endif // BUILDFLAG(ENABLE_WEBSOCKETS)
17822
bncd16676a2016-07-20 16:23:0117823TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost) {
danakj1fd259a02016-04-16 03:17:0917824 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217825 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917826 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217827 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2217828
17829 HttpRequestInfo request;
17830 request.method = "POST";
17831 request.url = GURL("http://www.foo.com/");
17832 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017833 request.traffic_annotation =
17834 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2217835
danakj1fd259a02016-04-16 03:17:0917836 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617837 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2217838 MockWrite data_writes[] = {
17839 MockWrite("POST / HTTP/1.1\r\n"
17840 "Host: www.foo.com\r\n"
17841 "Connection: keep-alive\r\n"
17842 "Content-Length: 3\r\n\r\n"),
17843 MockWrite("foo"),
17844 };
17845
17846 MockRead data_reads[] = {
17847 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
17848 MockRead(SYNCHRONOUS, OK),
17849 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117850 StaticSocketDataProvider data(data_reads, data_writes);
sclittlefb249892015-09-10 21:33:2217851 session_deps_.socket_factory->AddSocketDataProvider(&data);
17852
17853 TestCompletionCallback callback;
17854
17855 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017856 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0117857 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2217858
17859 std::string response_data;
bnc691fda62016-08-12 00:43:1617860 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2217861
Ryan Sleevib8d7ea02018-05-07 20:01:0117862 EXPECT_EQ(CountWriteBytes(data_writes), trans.GetTotalSentBytes());
17863 EXPECT_EQ(CountReadBytes(data_reads), trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2217864}
17865
bncd16676a2016-07-20 16:23:0117866TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost100Continue) {
danakj1fd259a02016-04-16 03:17:0917867 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217868 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917869 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217870 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2217871
17872 HttpRequestInfo request;
17873 request.method = "POST";
17874 request.url = GURL("http://www.foo.com/");
17875 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017876 request.traffic_annotation =
17877 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2217878
danakj1fd259a02016-04-16 03:17:0917879 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617880 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2217881 MockWrite data_writes[] = {
17882 MockWrite("POST / HTTP/1.1\r\n"
17883 "Host: www.foo.com\r\n"
17884 "Connection: keep-alive\r\n"
17885 "Content-Length: 3\r\n\r\n"),
17886 MockWrite("foo"),
17887 };
17888
17889 MockRead data_reads[] = {
17890 MockRead("HTTP/1.1 100 Continue\r\n\r\n"),
17891 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
17892 MockRead(SYNCHRONOUS, OK),
17893 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117894 StaticSocketDataProvider data(data_reads, data_writes);
sclittlefb249892015-09-10 21:33:2217895 session_deps_.socket_factory->AddSocketDataProvider(&data);
17896
17897 TestCompletionCallback callback;
17898
17899 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017900 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0117901 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2217902
17903 std::string response_data;
bnc691fda62016-08-12 00:43:1617904 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2217905
Ryan Sleevib8d7ea02018-05-07 20:01:0117906 EXPECT_EQ(CountWriteBytes(data_writes), trans.GetTotalSentBytes());
17907 EXPECT_EQ(CountReadBytes(data_reads), trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2217908}
17909
bncd16676a2016-07-20 16:23:0117910TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) {
sclittlefb249892015-09-10 21:33:2217911 ChunkedUploadDataStream upload_data_stream(0);
17912
17913 HttpRequestInfo request;
17914 request.method = "POST";
17915 request.url = GURL("http://www.foo.com/");
17916 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017917 request.traffic_annotation =
17918 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2217919
danakj1fd259a02016-04-16 03:17:0917920 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617921 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2217922 // Send headers successfully, but get an error while sending the body.
17923 MockWrite data_writes[] = {
17924 MockWrite("POST / HTTP/1.1\r\n"
17925 "Host: www.foo.com\r\n"
17926 "Connection: keep-alive\r\n"
17927 "Transfer-Encoding: chunked\r\n\r\n"),
17928 MockWrite("1\r\nf\r\n"), MockWrite("2\r\noo\r\n"), MockWrite("0\r\n\r\n"),
17929 };
17930
17931 MockRead data_reads[] = {
17932 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
17933 MockRead(SYNCHRONOUS, OK),
17934 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117935 StaticSocketDataProvider data(data_reads, data_writes);
sclittlefb249892015-09-10 21:33:2217936 session_deps_.socket_factory->AddSocketDataProvider(&data);
17937
17938 TestCompletionCallback callback;
17939
17940 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017941 trans.Start(&request, callback.callback(), NetLogWithSource()));
sclittlefb249892015-09-10 21:33:2217942
17943 base::RunLoop().RunUntilIdle();
17944 upload_data_stream.AppendData("f", 1, false);
17945
17946 base::RunLoop().RunUntilIdle();
17947 upload_data_stream.AppendData("oo", 2, true);
17948
robpercival214763f2016-07-01 23:27:0117949 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2217950
17951 std::string response_data;
bnc691fda62016-08-12 00:43:1617952 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2217953
Ryan Sleevib8d7ea02018-05-07 20:01:0117954 EXPECT_EQ(CountWriteBytes(data_writes), trans.GetTotalSentBytes());
17955 EXPECT_EQ(CountReadBytes(data_reads), trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2217956}
17957
eustasc7d27da2017-04-06 10:33:2017958void CheckContentEncodingMatching(SpdySessionDependencies* session_deps,
17959 const std::string& accept_encoding,
17960 const std::string& content_encoding,
sky50576f32017-05-01 19:28:0317961 const std::string& location,
eustasc7d27da2017-04-06 10:33:2017962 bool should_match) {
17963 HttpRequestInfo request;
17964 request.method = "GET";
17965 request.url = GURL("http://www.foo.com/");
17966 request.extra_headers.SetHeader(HttpRequestHeaders::kAcceptEncoding,
17967 accept_encoding);
Ramin Halavatib5e433e2018-02-07 07:41:1017968 request.traffic_annotation =
17969 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
eustasc7d27da2017-04-06 10:33:2017970
17971 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps));
17972 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17973 // Send headers successfully, but get an error while sending the body.
17974 MockWrite data_writes[] = {
17975 MockWrite("GET / HTTP/1.1\r\n"
17976 "Host: www.foo.com\r\n"
17977 "Connection: keep-alive\r\n"
17978 "Accept-Encoding: "),
17979 MockWrite(accept_encoding.data()), MockWrite("\r\n\r\n"),
17980 };
17981
sky50576f32017-05-01 19:28:0317982 std::string response_code = "200 OK";
17983 std::string extra;
17984 if (!location.empty()) {
17985 response_code = "301 Redirect\r\nLocation: ";
17986 response_code.append(location);
17987 }
17988
eustasc7d27da2017-04-06 10:33:2017989 MockRead data_reads[] = {
sky50576f32017-05-01 19:28:0317990 MockRead("HTTP/1.0 "),
17991 MockRead(response_code.data()),
17992 MockRead("\r\nContent-Encoding: "),
17993 MockRead(content_encoding.data()),
17994 MockRead("\r\n\r\n"),
eustasc7d27da2017-04-06 10:33:2017995 MockRead(SYNCHRONOUS, OK),
17996 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117997 StaticSocketDataProvider data(data_reads, data_writes);
eustasc7d27da2017-04-06 10:33:2017998 session_deps->socket_factory->AddSocketDataProvider(&data);
17999
18000 TestCompletionCallback callback;
18001
18002 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18003 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18004
18005 rv = callback.WaitForResult();
18006 if (should_match) {
18007 EXPECT_THAT(rv, IsOk());
18008 } else {
18009 EXPECT_THAT(rv, IsError(ERR_CONTENT_DECODING_FAILED));
18010 }
18011}
18012
18013TEST_F(HttpNetworkTransactionTest, MatchContentEncoding1) {
sky50576f32017-05-01 19:28:0318014 CheckContentEncodingMatching(&session_deps_, "gzip,sdch", "br", "", false);
eustasc7d27da2017-04-06 10:33:2018015}
18016
18017TEST_F(HttpNetworkTransactionTest, MatchContentEncoding2) {
sky50576f32017-05-01 19:28:0318018 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "", "",
18019 true);
eustasc7d27da2017-04-06 10:33:2018020}
18021
18022TEST_F(HttpNetworkTransactionTest, MatchContentEncoding3) {
18023 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
sky50576f32017-05-01 19:28:0318024 "", false);
18025}
18026
18027TEST_F(HttpNetworkTransactionTest, MatchContentEncoding4) {
18028 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
18029 "www.foo.com/other", true);
eustasc7d27da2017-04-06 10:33:2018030}
18031
xunjieli96f2a402017-06-05 17:24:2718032TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsSync) {
18033 ProxyConfig proxy_config;
18034 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
18035 proxy_config.set_pac_mandatory(true);
18036 MockAsyncProxyResolver resolver;
Lily Houghton8c2f97d2018-01-22 05:06:5918037 session_deps_.proxy_resolution_service.reset(new ProxyResolutionService(
Ramin Halavatica8d5252018-03-12 05:33:4918038 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
18039 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
Bence Béky8f9d7d3952017-10-09 19:58:0418040 std::make_unique<FailingProxyResolverFactory>(), nullptr));
xunjieli96f2a402017-06-05 17:24:2718041
18042 HttpRequestInfo request;
18043 request.method = "GET";
18044 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1018045 request.traffic_annotation =
18046 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2718047
18048 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18049 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18050
18051 TestCompletionCallback callback;
18052
18053 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18054 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18055 EXPECT_THAT(callback.WaitForResult(),
18056 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
18057}
18058
18059TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsAsync) {
18060 ProxyConfig proxy_config;
18061 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
18062 proxy_config.set_pac_mandatory(true);
18063 MockAsyncProxyResolverFactory* proxy_resolver_factory =
18064 new MockAsyncProxyResolverFactory(false);
18065 MockAsyncProxyResolver resolver;
Lily Houghton8c2f97d2018-01-22 05:06:5918066 session_deps_.proxy_resolution_service.reset(new ProxyResolutionService(
Ramin Halavatica8d5252018-03-12 05:33:4918067 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
18068 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
Lily Houghton8c2f97d2018-01-22 05:06:5918069 base::WrapUnique(proxy_resolver_factory), nullptr));
xunjieli96f2a402017-06-05 17:24:2718070 HttpRequestInfo request;
18071 request.method = "GET";
18072 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1018073 request.traffic_annotation =
18074 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2718075
18076 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18077 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18078
18079 TestCompletionCallback callback;
18080 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18081 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18082
18083 proxy_resolver_factory->pending_requests()[0]->CompleteNowWithForwarder(
18084 ERR_FAILED, &resolver);
18085 EXPECT_THAT(callback.WaitForResult(),
18086 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
18087}
18088
18089TEST_F(HttpNetworkTransactionTest, NoSupportedProxies) {
Lily Houghton8c2f97d2018-01-22 05:06:5918090 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4918091 ProxyResolutionService::CreateFixedFromPacResult(
18092 "QUIC myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2718093 session_deps_.enable_quic = false;
18094 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18095
18096 HttpRequestInfo request;
18097 request.method = "GET";
18098 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1018099 request.traffic_annotation =
18100 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2718101
18102 TestCompletionCallback callback;
18103 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18104 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18105 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18106
18107 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NO_SUPPORTED_PROXIES));
18108}
18109
Douglas Creager3cb042052018-11-06 23:08:5218110//-----------------------------------------------------------------------------
Douglas Creager134b52e2018-11-09 18:00:1418111// Reporting tests
18112
18113#if BUILDFLAG(ENABLE_REPORTING)
18114class HttpNetworkTransactionReportingTest : public HttpNetworkTransactionTest {
18115 protected:
18116 void SetUp() override {
Douglas Creageref5eecdc2018-11-09 20:50:3618117 HttpNetworkTransactionTest::SetUp();
Douglas Creager134b52e2018-11-09 18:00:1418118 auto test_reporting_context = std::make_unique<TestReportingContext>(
18119 &clock_, &tick_clock_, ReportingPolicy());
18120 test_reporting_context_ = test_reporting_context.get();
18121 session_deps_.reporting_service =
18122 ReportingService::CreateForTesting(std::move(test_reporting_context));
18123 }
18124
18125 TestReportingContext* reporting_context() const {
18126 return test_reporting_context_;
18127 }
18128
18129 void clear_reporting_service() {
18130 session_deps_.reporting_service.reset();
18131 test_reporting_context_ = nullptr;
18132 }
18133
18134 // Makes an HTTPS request that should install a valid Reporting policy.
Lily Chenfec60d92019-01-24 01:16:4218135 void RequestPolicy(CertStatus cert_status = 0) {
18136 HttpRequestInfo request;
18137 request.method = "GET";
18138 request.url = GURL(url_);
18139 request.traffic_annotation =
18140 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
18141
Douglas Creager134b52e2018-11-09 18:00:1418142 MockRead data_reads[] = {
18143 MockRead("HTTP/1.0 200 OK\r\n"),
18144 MockRead("Report-To: {\"group\": \"nel\", \"max_age\": 86400, "
18145 "\"endpoints\": [{\"url\": "
18146 "\"https://www.example.org/upload/\"}]}\r\n"),
18147 MockRead("\r\n"),
18148 MockRead("hello world"),
18149 MockRead(SYNCHRONOUS, OK),
18150 };
18151 MockWrite data_writes[] = {
18152 MockWrite("GET / HTTP/1.1\r\n"
18153 "Host: www.example.org\r\n"
18154 "Connection: keep-alive\r\n\r\n"),
18155 };
18156
Lily Chenfec60d92019-01-24 01:16:4218157 StaticSocketDataProvider reads(data_reads, data_writes);
18158 session_deps_.socket_factory->AddSocketDataProvider(&reads);
Douglas Creager134b52e2018-11-09 18:00:1418159
18160 SSLSocketDataProvider ssl(ASYNC, OK);
18161 if (request.url.SchemeIsCryptographic()) {
18162 ssl.ssl_info.cert =
18163 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
18164 ASSERT_TRUE(ssl.ssl_info.cert);
Lily Chenfec60d92019-01-24 01:16:4218165 ssl.ssl_info.cert_status = cert_status;
Douglas Creager134b52e2018-11-09 18:00:1418166 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
18167 }
18168
Douglas Creager134b52e2018-11-09 18:00:1418169 TestCompletionCallback callback;
18170 auto session = CreateSession(&session_deps_);
18171 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18172 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
Lily Chenfec60d92019-01-24 01:16:4218173 EXPECT_THAT(callback.GetResult(rv), IsOk());
Douglas Creager134b52e2018-11-09 18:00:1418174 }
18175
18176 protected:
18177 std::string url_ = "https://www.example.org/";
Douglas Creager134b52e2018-11-09 18:00:1418178
18179 private:
18180 TestReportingContext* test_reporting_context_;
18181};
18182
18183TEST_F(HttpNetworkTransactionReportingTest,
18184 DontProcessReportToHeaderNoService) {
18185 base::HistogramTester histograms;
18186 clear_reporting_service();
18187 RequestPolicy();
18188 histograms.ExpectBucketCount(
18189 ReportingHeaderParser::kHeaderOutcomeHistogram,
18190 ReportingHeaderParser::HeaderOutcome::DISCARDED_NO_REPORTING_SERVICE, 1);
18191}
18192
18193TEST_F(HttpNetworkTransactionReportingTest, DontProcessReportToHeaderHttp) {
18194 base::HistogramTester histograms;
18195 url_ = "http://www.example.org/";
18196 RequestPolicy();
18197 histograms.ExpectBucketCount(
18198 ReportingHeaderParser::kHeaderOutcomeHistogram,
18199 ReportingHeaderParser::HeaderOutcome::DISCARDED_INVALID_SSL_INFO, 1);
18200}
18201
18202TEST_F(HttpNetworkTransactionReportingTest, ProcessReportToHeaderHttps) {
18203 RequestPolicy();
18204 std::vector<const ReportingClient*> clients;
18205 reporting_context()->cache()->GetClients(&clients);
18206 ASSERT_EQ(1u, clients.size());
18207 const auto* client = clients[0];
18208 EXPECT_EQ(url::Origin::Create(GURL("https://www.example.org/")),
18209 client->origin);
18210 EXPECT_EQ(GURL("https://www.example.org/upload/"), client->endpoint);
18211 EXPECT_EQ("nel", client->group);
18212}
18213
18214TEST_F(HttpNetworkTransactionReportingTest,
18215 DontProcessReportToHeaderInvalidHttps) {
18216 base::HistogramTester histograms;
Lily Chenfec60d92019-01-24 01:16:4218217 CertStatus cert_status = CERT_STATUS_COMMON_NAME_INVALID;
18218 RequestPolicy(cert_status);
Douglas Creager134b52e2018-11-09 18:00:1418219 histograms.ExpectBucketCount(
18220 ReportingHeaderParser::kHeaderOutcomeHistogram,
18221 ReportingHeaderParser::HeaderOutcome::DISCARDED_CERT_STATUS_ERROR, 1);
18222}
18223#endif // BUILDFLAG(ENABLE_REPORTING)
18224
18225//-----------------------------------------------------------------------------
Douglas Creager3cb042052018-11-06 23:08:5218226// Network Error Logging tests
18227
18228#if BUILDFLAG(ENABLE_REPORTING)
Lily Chenfec60d92019-01-24 01:16:4218229namespace {
18230
18231const char kUserAgent[] = "Mozilla/1.0";
18232const char kReferrer[] = "https://www.referrer.org/";
18233
18234} // namespace
18235
Douglas Creager3cb042052018-11-06 23:08:5218236class HttpNetworkTransactionNetworkErrorLoggingTest
18237 : public HttpNetworkTransactionTest {
18238 protected:
18239 void SetUp() override {
Douglas Creageref5eecdc2018-11-09 20:50:3618240 HttpNetworkTransactionTest::SetUp();
Douglas Creager3cb042052018-11-06 23:08:5218241 auto network_error_logging_service =
18242 std::make_unique<TestNetworkErrorLoggingService>();
18243 test_network_error_logging_service_ = network_error_logging_service.get();
18244 session_deps_.network_error_logging_service =
18245 std::move(network_error_logging_service);
Lily Chenfec60d92019-01-24 01:16:4218246
18247 extra_headers_.SetHeader("User-Agent", kUserAgent);
18248 extra_headers_.SetHeader("Referer", kReferrer);
18249
18250 request_.method = "GET";
18251 request_.url = GURL(url_);
18252 request_.extra_headers = extra_headers_;
18253 request_.reporting_upload_depth = reporting_upload_depth_;
18254 request_.traffic_annotation =
18255 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Douglas Creager3cb042052018-11-06 23:08:5218256 }
18257
18258 TestNetworkErrorLoggingService* network_error_logging_service() const {
18259 return test_network_error_logging_service_;
18260 }
18261
18262 void clear_network_error_logging_service() {
18263 session_deps_.network_error_logging_service.reset();
18264 test_network_error_logging_service_ = nullptr;
18265 }
18266
18267 // Makes an HTTPS request that should install a valid NEL policy.
Lily Chenfec60d92019-01-24 01:16:4218268 void RequestPolicy(CertStatus cert_status = 0) {
Douglas Creageref5eecdc2018-11-09 20:50:3618269 std::string extra_header_string = extra_headers_.ToString();
Douglas Creager3cb042052018-11-06 23:08:5218270 MockRead data_reads[] = {
18271 MockRead("HTTP/1.0 200 OK\r\n"),
18272 MockRead("NEL: {\"report_to\": \"nel\", \"max_age\": 86400}\r\n"),
18273 MockRead("\r\n"),
18274 MockRead("hello world"),
18275 MockRead(SYNCHRONOUS, OK),
18276 };
18277 MockWrite data_writes[] = {
18278 MockWrite("GET / HTTP/1.1\r\n"
18279 "Host: www.example.org\r\n"
Douglas Creageref5eecdc2018-11-09 20:50:3618280 "Connection: keep-alive\r\n"),
18281 MockWrite(ASYNC, extra_header_string.data(),
18282 extra_header_string.size()),
Douglas Creager3cb042052018-11-06 23:08:5218283 };
18284
Lily Chenfec60d92019-01-24 01:16:4218285 StaticSocketDataProvider reads(data_reads, data_writes);
18286 session_deps_.socket_factory->AddSocketDataProvider(&reads);
Douglas Creager3cb042052018-11-06 23:08:5218287
18288 SSLSocketDataProvider ssl(ASYNC, OK);
Lily Chenfec60d92019-01-24 01:16:4218289 if (request_.url.SchemeIsCryptographic()) {
Douglas Creager3cb042052018-11-06 23:08:5218290 ssl.ssl_info.cert =
18291 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
18292 ASSERT_TRUE(ssl.ssl_info.cert);
Lily Chenfec60d92019-01-24 01:16:4218293 ssl.ssl_info.cert_status = cert_status;
Douglas Creager3cb042052018-11-06 23:08:5218294 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
18295 }
18296
Douglas Creager3cb042052018-11-06 23:08:5218297 TestCompletionCallback callback;
18298 auto session = CreateSession(&session_deps_);
18299 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
Lily Chenfec60d92019-01-24 01:16:4218300 int rv = trans.Start(&request_, callback.callback(), NetLogWithSource());
18301 EXPECT_THAT(callback.GetResult(rv), IsOk());
18302
18303 std::string response_data;
18304 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
18305 EXPECT_EQ("hello world", response_data);
18306 }
18307
18308 void CheckReport(size_t index,
18309 int status_code,
18310 int error_type,
18311 IPAddress server_ip = IPAddress::IPv4Localhost()) {
18312 ASSERT_LT(index, network_error_logging_service()->errors().size());
18313
18314 const NetworkErrorLoggingService::RequestDetails& error =
18315 network_error_logging_service()->errors()[index];
18316 EXPECT_EQ(url_, error.uri);
18317 EXPECT_EQ(kReferrer, error.referrer);
18318 EXPECT_EQ(kUserAgent, error.user_agent);
18319 EXPECT_EQ(server_ip, error.server_ip);
18320 EXPECT_EQ("http/1.1", error.protocol);
18321 EXPECT_EQ("GET", error.method);
18322 EXPECT_EQ(status_code, error.status_code);
18323 EXPECT_EQ(error_type, error.type);
18324 EXPECT_EQ(0, error.reporting_upload_depth);
Douglas Creager3cb042052018-11-06 23:08:5218325 }
18326
18327 protected:
18328 std::string url_ = "https://www.example.org/";
18329 CertStatus cert_status_ = 0;
Lily Chenfec60d92019-01-24 01:16:4218330 HttpRequestInfo request_;
Douglas Creageref5eecdc2018-11-09 20:50:3618331 HttpRequestHeaders extra_headers_;
18332 int reporting_upload_depth_ = 0;
Douglas Creager3cb042052018-11-06 23:08:5218333
18334 private:
18335 TestNetworkErrorLoggingService* test_network_error_logging_service_;
18336};
18337
18338TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18339 DontProcessNelHeaderNoService) {
18340 base::HistogramTester histograms;
18341 clear_network_error_logging_service();
18342 RequestPolicy();
18343 histograms.ExpectBucketCount(
18344 NetworkErrorLoggingService::kHeaderOutcomeHistogram,
18345 NetworkErrorLoggingService::HeaderOutcome::
18346 DISCARDED_NO_NETWORK_ERROR_LOGGING_SERVICE,
18347 1);
18348}
18349
18350TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18351 DontProcessNelHeaderHttp) {
18352 base::HistogramTester histograms;
18353 url_ = "http://www.example.org/";
Lily Chenfec60d92019-01-24 01:16:4218354 request_.url = GURL(url_);
Douglas Creager3cb042052018-11-06 23:08:5218355 RequestPolicy();
18356 histograms.ExpectBucketCount(
18357 NetworkErrorLoggingService::kHeaderOutcomeHistogram,
18358 NetworkErrorLoggingService::HeaderOutcome::DISCARDED_INVALID_SSL_INFO, 1);
18359}
18360
Lily Chen90ae93cc2019-02-14 01:15:3918361// Don't set NEL policies received on a proxied connection.
18362TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18363 DontProcessNelHeaderProxy) {
18364 session_deps_.proxy_resolution_service =
18365 ProxyResolutionService::CreateFixedFromPacResult(
18366 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
18367 BoundTestNetLog log;
18368 session_deps_.net_log = log.bound().net_log();
18369 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18370
18371 HttpRequestInfo request;
18372 request.method = "GET";
18373 request.url = GURL("https://www.example.org/");
18374 request.traffic_annotation =
18375 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
18376
18377 // Since we have proxy, should try to establish tunnel.
18378 MockWrite data_writes1[] = {
18379 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
18380 "Host: www.example.org:443\r\n"
18381 "Proxy-Connection: keep-alive\r\n\r\n"),
18382
18383 MockWrite("GET / HTTP/1.1\r\n"
18384 "Host: www.example.org\r\n"
18385 "Connection: keep-alive\r\n\r\n"),
18386 };
18387
18388 MockRead data_reads1[] = {
18389 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
18390
18391 MockRead("HTTP/1.1 200 OK\r\n"),
18392 MockRead("NEL: {\"report_to\": \"nel\", \"max_age\": 86400}\r\n"),
18393 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
18394 MockRead("Content-Length: 100\r\n\r\n"),
18395 MockRead(SYNCHRONOUS, OK),
18396 };
18397
18398 StaticSocketDataProvider data1(data_reads1, data_writes1);
18399 session_deps_.socket_factory->AddSocketDataProvider(&data1);
18400 SSLSocketDataProvider ssl(ASYNC, OK);
18401 ssl.ssl_info.cert =
18402 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
18403 ASSERT_TRUE(ssl.ssl_info.cert);
18404 ssl.ssl_info.cert_status = 0;
18405 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
18406
18407 TestCompletionCallback callback1;
18408 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18409
18410 int rv = trans.Start(&request, callback1.callback(), log.bound());
18411 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18412
18413 rv = callback1.WaitForResult();
18414 EXPECT_THAT(rv, IsOk());
18415
18416 const HttpResponseInfo* response = trans.GetResponseInfo();
18417 ASSERT_TRUE(response);
18418 EXPECT_EQ(200, response->headers->response_code());
18419 EXPECT_TRUE(response->was_fetched_via_proxy);
18420
18421 // No NEL header was set.
18422 EXPECT_EQ(0u, network_error_logging_service()->headers().size());
18423}
18424
Douglas Creager3cb042052018-11-06 23:08:5218425TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, ProcessNelHeaderHttps) {
18426 RequestPolicy();
18427 ASSERT_EQ(1u, network_error_logging_service()->headers().size());
18428 const auto& header = network_error_logging_service()->headers()[0];
18429 EXPECT_EQ(url::Origin::Create(GURL("https://www.example.org/")),
18430 header.origin);
18431 EXPECT_EQ(IPAddress::IPv4Localhost(), header.received_ip_address);
18432 EXPECT_EQ("{\"report_to\": \"nel\", \"max_age\": 86400}", header.value);
18433}
18434
18435TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18436 DontProcessNelHeaderInvalidHttps) {
18437 base::HistogramTester histograms;
Lily Chenfec60d92019-01-24 01:16:4218438 CertStatus cert_status = CERT_STATUS_COMMON_NAME_INVALID;
18439 RequestPolicy(cert_status);
Douglas Creager3cb042052018-11-06 23:08:5218440 histograms.ExpectBucketCount(
18441 NetworkErrorLoggingService::kHeaderOutcomeHistogram,
18442 NetworkErrorLoggingService::HeaderOutcome::DISCARDED_CERT_STATUS_ERROR,
18443 1);
18444}
Douglas Creageref5eecdc2018-11-09 20:50:3618445
Lily Chenfec60d92019-01-24 01:16:4218446TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, CreateReportSuccess) {
Douglas Creageref5eecdc2018-11-09 20:50:3618447 RequestPolicy();
18448 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
Lily Chenfec60d92019-01-24 01:16:4218449 CheckReport(0 /* index */, 200 /* status_code */, OK);
18450}
18451
18452TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18453 CreateReportErrorAfterStart) {
18454 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18455 auto trans =
18456 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18457
18458 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
18459 StaticSocketDataProvider data;
18460 data.set_connect_data(mock_connect);
18461 session_deps_.socket_factory->AddSocketDataProvider(&data);
18462
18463 TestCompletionCallback callback;
18464
18465 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
18466 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_NAME_NOT_RESOLVED));
18467
18468 trans.reset();
18469
18470 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18471 CheckReport(0 /* index */, 0 /* status_code */, ERR_NAME_NOT_RESOLVED,
18472 IPAddress() /* server_ip */);
18473}
18474
18475// Same as above except the error is ASYNC
18476TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18477 CreateReportErrorAfterStartAsync) {
18478 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18479 auto trans =
18480 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18481
18482 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
18483 StaticSocketDataProvider data;
18484 data.set_connect_data(mock_connect);
18485 session_deps_.socket_factory->AddSocketDataProvider(&data);
18486
18487 TestCompletionCallback callback;
18488
18489 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
18490 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_NAME_NOT_RESOLVED));
18491
18492 trans.reset();
18493
18494 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18495 CheckReport(0 /* index */, 0 /* status_code */, ERR_NAME_NOT_RESOLVED,
18496 IPAddress() /* server_ip */);
18497}
18498
18499TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18500 CreateReportReadBodyError) {
18501 std::string extra_header_string = extra_headers_.ToString();
18502 MockRead data_reads[] = {
18503 MockRead("HTTP/1.0 200 OK\r\n"),
18504 MockRead("Content-Length: 100\r\n\r\n"), // wrong content length
18505 MockRead("hello world"),
18506 MockRead(SYNCHRONOUS, OK),
18507 };
18508 MockWrite data_writes[] = {
18509 MockWrite("GET / HTTP/1.1\r\n"
18510 "Host: www.example.org\r\n"
18511 "Connection: keep-alive\r\n"),
18512 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18513 };
18514
18515 StaticSocketDataProvider reads(data_reads, data_writes);
18516 session_deps_.socket_factory->AddSocketDataProvider(&reads);
18517
18518 SSLSocketDataProvider ssl(ASYNC, OK);
18519 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
18520
18521 // Log start time
18522 base::TimeTicks start_time = base::TimeTicks::Now();
18523
18524 TestCompletionCallback callback;
18525 auto session = CreateSession(&session_deps_);
18526 auto trans =
18527 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18528 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
18529 EXPECT_THAT(callback.GetResult(rv), IsOk());
18530
18531 const HttpResponseInfo* response = trans->GetResponseInfo();
18532 ASSERT_TRUE(response);
18533
18534 EXPECT_TRUE(response->headers);
18535 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
18536
18537 std::string response_data;
18538 rv = ReadTransaction(trans.get(), &response_data);
18539 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
18540
18541 trans.reset();
18542
18543 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18544
18545 CheckReport(0 /* index */, 200 /* status_code */,
18546 ERR_CONTENT_LENGTH_MISMATCH);
18547 const NetworkErrorLoggingService::RequestDetails& error =
18548 network_error_logging_service()->errors()[0];
18549 EXPECT_LE(error.elapsed_time, base::TimeTicks::Now() - start_time);
18550}
18551
18552// Same as above except the final read is ASYNC.
18553TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18554 CreateReportReadBodyErrorAsync) {
18555 std::string extra_header_string = extra_headers_.ToString();
18556 MockRead data_reads[] = {
18557 MockRead("HTTP/1.0 200 OK\r\n"),
18558 MockRead("Content-Length: 100\r\n\r\n"), // wrong content length
18559 MockRead("hello world"),
18560 MockRead(ASYNC, OK),
18561 };
18562 MockWrite data_writes[] = {
18563 MockWrite("GET / HTTP/1.1\r\n"
18564 "Host: www.example.org\r\n"
18565 "Connection: keep-alive\r\n"),
18566 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18567 };
18568
18569 StaticSocketDataProvider reads(data_reads, data_writes);
18570 session_deps_.socket_factory->AddSocketDataProvider(&reads);
18571
18572 SSLSocketDataProvider ssl(ASYNC, OK);
18573 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
18574
18575 // Log start time
18576 base::TimeTicks start_time = base::TimeTicks::Now();
18577
18578 TestCompletionCallback callback;
18579 auto session = CreateSession(&session_deps_);
18580 auto trans =
18581 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18582 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
18583 EXPECT_THAT(callback.GetResult(rv), IsOk());
18584
18585 const HttpResponseInfo* response = trans->GetResponseInfo();
18586 ASSERT_TRUE(response);
18587
18588 EXPECT_TRUE(response->headers);
18589 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
18590
18591 std::string response_data;
18592 rv = ReadTransaction(trans.get(), &response_data);
18593 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
18594
18595 trans.reset();
18596
18597 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18598
18599 CheckReport(0 /* index */, 200 /* status_code */,
18600 ERR_CONTENT_LENGTH_MISMATCH);
18601 const NetworkErrorLoggingService::RequestDetails& error =
18602 network_error_logging_service()->errors()[0];
18603 EXPECT_LE(error.elapsed_time, base::TimeTicks::Now() - start_time);
18604}
18605
18606TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18607 CreateReportRestartWithAuth) {
18608 std::string extra_header_string = extra_headers_.ToString();
18609 static const base::TimeDelta kSleepDuration =
18610 base::TimeDelta::FromMilliseconds(10);
18611
18612 MockWrite data_writes1[] = {
18613 MockWrite("GET / HTTP/1.1\r\n"
18614 "Host: www.example.org\r\n"
18615 "Connection: keep-alive\r\n"),
18616 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18617 };
18618
18619 MockRead data_reads1[] = {
18620 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
18621 // Give a couple authenticate options (only the middle one is actually
18622 // supported).
18623 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
18624 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
18625 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
18626 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
18627 // Large content-length -- won't matter, as connection will be reset.
18628 MockRead("Content-Length: 10000\r\n\r\n"),
18629 MockRead(SYNCHRONOUS, ERR_FAILED),
18630 };
18631
18632 // After calling trans->RestartWithAuth(), this is the request we should
18633 // be issuing -- the final header line contains the credentials.
18634 MockWrite data_writes2[] = {
18635 MockWrite("GET / HTTP/1.1\r\n"
18636 "Host: www.example.org\r\n"
18637 "Connection: keep-alive\r\n"
18638 "Authorization: Basic Zm9vOmJhcg==\r\n"),
18639 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18640 };
18641
18642 // Lastly, the server responds with the actual content.
18643 MockRead data_reads2[] = {
18644 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
18645 MockRead("hello world"),
18646 MockRead(SYNCHRONOUS, OK),
18647 };
18648
18649 StaticSocketDataProvider data1(data_reads1, data_writes1);
18650 StaticSocketDataProvider data2(data_reads2, data_writes2);
18651 session_deps_.socket_factory->AddSocketDataProvider(&data1);
18652 session_deps_.socket_factory->AddSocketDataProvider(&data2);
18653
18654 SSLSocketDataProvider ssl1(ASYNC, OK);
18655 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
18656 SSLSocketDataProvider ssl2(ASYNC, OK);
18657 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
18658
18659 base::TimeTicks start_time = base::TimeTicks::Now();
18660 base::TimeTicks restart_time;
18661
18662 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18663 auto trans =
18664 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18665
18666 TestCompletionCallback callback1;
18667
18668 int rv = trans->Start(&request_, callback1.callback(), NetLogWithSource());
18669 EXPECT_THAT(callback1.GetResult(rv), IsOk());
18670
18671 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18672
18673 TestCompletionCallback callback2;
18674
18675 // Wait 10 ms then restart with auth
18676 FastForwardBy(kSleepDuration);
18677 restart_time = base::TimeTicks::Now();
18678 rv =
18679 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
18680 EXPECT_THAT(callback2.GetResult(rv), IsOk());
18681
18682 std::string response_data;
18683 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
18684 EXPECT_EQ("hello world", response_data);
18685
18686 trans.reset();
18687
18688 // One 401 report for the auth challenge, then a 200 report for the successful
18689 // retry. Note that we don't report the error draining the body, as the first
18690 // request already generated a report for the auth challenge.
18691 ASSERT_EQ(2u, network_error_logging_service()->errors().size());
18692
18693 // Check error report contents
18694 CheckReport(0 /* index */, 401 /* status_code */, OK);
18695 CheckReport(1 /* index */, 200 /* status_code */, OK);
18696
18697 const NetworkErrorLoggingService::RequestDetails& error1 =
18698 network_error_logging_service()->errors()[0];
18699 const NetworkErrorLoggingService::RequestDetails& error2 =
18700 network_error_logging_service()->errors()[1];
18701
18702 // Sanity-check elapsed time values
18703 EXPECT_EQ(error1.elapsed_time, restart_time - start_time - kSleepDuration);
18704 // Check that the start time is refreshed when restarting with auth.
18705 EXPECT_EQ(error2.elapsed_time, base::TimeTicks::Now() - restart_time);
18706}
18707
18708// Same as above, except draining the body before restarting fails
18709// asynchronously.
18710TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18711 CreateReportRestartWithAuthAsync) {
18712 std::string extra_header_string = extra_headers_.ToString();
18713 static const base::TimeDelta kSleepDuration =
18714 base::TimeDelta::FromMilliseconds(10);
18715
18716 MockWrite data_writes1[] = {
18717 MockWrite("GET / HTTP/1.1\r\n"
18718 "Host: www.example.org\r\n"
18719 "Connection: keep-alive\r\n"),
18720 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18721 };
18722
18723 MockRead data_reads1[] = {
18724 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
18725 // Give a couple authenticate options (only the middle one is actually
18726 // supported).
18727 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
18728 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
18729 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
18730 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
18731 // Large content-length -- won't matter, as connection will be reset.
18732 MockRead("Content-Length: 10000\r\n\r\n"),
18733 MockRead(ASYNC, ERR_FAILED),
18734 };
18735
18736 // After calling trans->RestartWithAuth(), this is the request we should
18737 // be issuing -- the final header line contains the credentials.
18738 MockWrite data_writes2[] = {
18739 MockWrite("GET / HTTP/1.1\r\n"
18740 "Host: www.example.org\r\n"
18741 "Connection: keep-alive\r\n"
18742 "Authorization: Basic Zm9vOmJhcg==\r\n"),
18743 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18744 };
18745
18746 // Lastly, the server responds with the actual content.
18747 MockRead data_reads2[] = {
18748 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
18749 MockRead("hello world"),
18750 MockRead(SYNCHRONOUS, OK),
18751 };
18752
18753 StaticSocketDataProvider data1(data_reads1, data_writes1);
18754 StaticSocketDataProvider data2(data_reads2, data_writes2);
18755 session_deps_.socket_factory->AddSocketDataProvider(&data1);
18756 session_deps_.socket_factory->AddSocketDataProvider(&data2);
18757
18758 SSLSocketDataProvider ssl1(ASYNC, OK);
18759 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
18760 SSLSocketDataProvider ssl2(ASYNC, OK);
18761 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
18762
18763 base::TimeTicks start_time = base::TimeTicks::Now();
18764 base::TimeTicks restart_time;
18765
18766 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18767 auto trans =
18768 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18769
18770 TestCompletionCallback callback1;
18771
18772 int rv = trans->Start(&request_, callback1.callback(), NetLogWithSource());
18773 EXPECT_THAT(callback1.GetResult(rv), IsOk());
18774
18775 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18776
18777 TestCompletionCallback callback2;
18778
18779 // Wait 10 ms then restart with auth
18780 FastForwardBy(kSleepDuration);
18781 restart_time = base::TimeTicks::Now();
18782 rv =
18783 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
18784 EXPECT_THAT(callback2.GetResult(rv), IsOk());
18785
18786 std::string response_data;
18787 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
18788 EXPECT_EQ("hello world", response_data);
18789
18790 trans.reset();
18791
18792 // One 401 report for the auth challenge, then a 200 report for the successful
18793 // retry. Note that we don't report the error draining the body, as the first
18794 // request already generated a report for the auth challenge.
18795 ASSERT_EQ(2u, network_error_logging_service()->errors().size());
18796
18797 // Check error report contents
18798 CheckReport(0 /* index */, 401 /* status_code */, OK);
18799 CheckReport(1 /* index */, 200 /* status_code */, OK);
18800
18801 const NetworkErrorLoggingService::RequestDetails& error1 =
18802 network_error_logging_service()->errors()[0];
18803 const NetworkErrorLoggingService::RequestDetails& error2 =
18804 network_error_logging_service()->errors()[1];
18805
18806 // Sanity-check elapsed time values
18807 EXPECT_EQ(error1.elapsed_time, restart_time - start_time - kSleepDuration);
18808 // Check that the start time is refreshed when restarting with auth.
18809 EXPECT_EQ(error2.elapsed_time, base::TimeTicks::Now() - restart_time);
18810}
18811
18812TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18813 CreateReportRetryKeepAliveConnectionReset) {
18814 std::string extra_header_string = extra_headers_.ToString();
18815 MockWrite data_writes1[] = {
18816 MockWrite("GET / HTTP/1.1\r\n"
18817 "Host: www.example.org\r\n"
18818 "Connection: keep-alive\r\n"),
18819 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18820 MockWrite("GET / HTTP/1.1\r\n"
18821 "Host: www.example.org\r\n"
18822 "Connection: keep-alive\r\n"),
18823 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18824 };
18825
18826 MockRead data_reads1[] = {
18827 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
18828 MockRead("hello"),
18829 // Connection is reset
18830 MockRead(ASYNC, ERR_CONNECTION_RESET),
18831 };
18832
18833 // Successful retry
18834 MockRead data_reads2[] = {
18835 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
18836 MockRead("world"),
18837 MockRead(ASYNC, OK),
18838 };
18839
18840 StaticSocketDataProvider data1(data_reads1, data_writes1);
18841 StaticSocketDataProvider data2(data_reads2, base::span<MockWrite>());
18842 session_deps_.socket_factory->AddSocketDataProvider(&data1);
18843 session_deps_.socket_factory->AddSocketDataProvider(&data2);
18844
18845 SSLSocketDataProvider ssl1(ASYNC, OK);
18846 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
18847 SSLSocketDataProvider ssl2(ASYNC, OK);
18848 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
18849
18850 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18851 auto trans1 =
18852 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18853
18854 TestCompletionCallback callback1;
18855
18856 int rv = trans1->Start(&request_, callback1.callback(), NetLogWithSource());
18857 EXPECT_THAT(callback1.GetResult(rv), IsOk());
18858
18859 std::string response_data;
18860 ASSERT_THAT(ReadTransaction(trans1.get(), &response_data), IsOk());
18861 EXPECT_EQ("hello", response_data);
18862
18863 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18864
18865 auto trans2 =
18866 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18867
18868 TestCompletionCallback callback2;
18869
18870 rv = trans2->Start(&request_, callback2.callback(), NetLogWithSource());
18871 EXPECT_THAT(callback2.GetResult(rv), IsOk());
18872
18873 ASSERT_THAT(ReadTransaction(trans2.get(), &response_data), IsOk());
18874 EXPECT_EQ("world", response_data);
18875
18876 trans1.reset();
18877 trans2.reset();
18878
18879 // One OK report from first request, then a ERR_CONNECTION_RESET report from
18880 // the second request, then an OK report from the successful retry.
18881 ASSERT_EQ(3u, network_error_logging_service()->errors().size());
18882
18883 // Check error report contents
18884 CheckReport(0 /* index */, 200 /* status_code */, OK);
18885 CheckReport(1 /* index */, 0 /* status_code */, ERR_CONNECTION_RESET);
18886 CheckReport(2 /* index */, 200 /* status_code */, OK);
18887}
18888
18889TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18890 CreateReportRetryKeepAlive408) {
18891 std::string extra_header_string = extra_headers_.ToString();
18892 MockWrite data_writes1[] = {
18893 MockWrite("GET / HTTP/1.1\r\n"
18894 "Host: www.example.org\r\n"
18895 "Connection: keep-alive\r\n"),
18896 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18897 MockWrite("GET / HTTP/1.1\r\n"
18898 "Host: www.example.org\r\n"
18899 "Connection: keep-alive\r\n"),
18900 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18901 };
18902
18903 MockRead data_reads1[] = {
18904 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
18905 MockRead("hello"),
18906 // 408 Request Timeout
18907 MockRead(SYNCHRONOUS,
18908 "HTTP/1.1 408 Request Timeout\r\n"
18909 "Connection: Keep-Alive\r\n"
18910 "Content-Length: 6\r\n\r\n"
18911 "Pickle"),
18912 };
18913
18914 // Successful retry
18915 MockRead data_reads2[] = {
18916 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
18917 MockRead("world"),
18918 MockRead(ASYNC, OK),
18919 };
18920
18921 StaticSocketDataProvider data1(data_reads1, data_writes1);
18922 StaticSocketDataProvider data2(data_reads2, base::span<MockWrite>());
18923 session_deps_.socket_factory->AddSocketDataProvider(&data1);
18924 session_deps_.socket_factory->AddSocketDataProvider(&data2);
18925
18926 SSLSocketDataProvider ssl1(ASYNC, OK);
18927 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
18928 SSLSocketDataProvider ssl2(ASYNC, OK);
18929 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
18930
18931 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18932 auto trans1 =
18933 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18934
18935 TestCompletionCallback callback1;
18936
18937 int rv = trans1->Start(&request_, callback1.callback(), NetLogWithSource());
18938 EXPECT_THAT(callback1.GetResult(rv), IsOk());
18939
18940 std::string response_data;
18941 ASSERT_THAT(ReadTransaction(trans1.get(), &response_data), IsOk());
18942 EXPECT_EQ("hello", response_data);
18943
18944 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18945
18946 auto trans2 =
18947 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18948
18949 TestCompletionCallback callback2;
18950
18951 rv = trans2->Start(&request_, callback2.callback(), NetLogWithSource());
18952 EXPECT_THAT(callback2.GetResult(rv), IsOk());
18953
18954 ASSERT_THAT(ReadTransaction(trans2.get(), &response_data), IsOk());
18955 EXPECT_EQ("world", response_data);
18956
18957 trans1.reset();
18958 trans2.reset();
18959
18960 // One 200 report from first request, then a 408 report from
18961 // the second request, then a 200 report from the successful retry.
18962 ASSERT_EQ(3u, network_error_logging_service()->errors().size());
18963
18964 // Check error report contents
18965 CheckReport(0 /* index */, 200 /* status_code */, OK);
18966 CheckReport(1 /* index */, 408 /* status_code */, OK);
18967 CheckReport(2 /* index */, 200 /* status_code */, OK);
18968}
18969
18970TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18971 CreateReportRetry421WithoutConnectionPooling) {
18972 // Two hosts resolve to the same IP address.
18973 const std::string ip_addr = "1.2.3.4";
18974 IPAddress ip;
18975 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
18976 IPEndPoint peer_addr = IPEndPoint(ip, 443);
18977
18978 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
18979 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
18980 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
18981
18982 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18983
18984 // Two requests on the first connection.
18985 spdy::SpdySerializedFrame req1(
18986 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
18987 spdy_util_.UpdateWithStreamDestruction(1);
18988 spdy::SpdySerializedFrame req2(
18989 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
18990 spdy::SpdySerializedFrame rst(
18991 spdy_util_.ConstructSpdyRstStream(3, spdy::ERROR_CODE_CANCEL));
18992 MockWrite writes1[] = {
18993 CreateMockWrite(req1, 0),
18994 CreateMockWrite(req2, 3),
18995 CreateMockWrite(rst, 6),
18996 };
18997
18998 // The first one succeeds, the second gets error 421 Misdirected Request.
18999 spdy::SpdySerializedFrame resp1(
19000 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
19001 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
19002 spdy::SpdyHeaderBlock response_headers;
19003 response_headers[spdy::kHttp2StatusHeader] = "421";
19004 spdy::SpdySerializedFrame resp2(
19005 spdy_util_.ConstructSpdyReply(3, std::move(response_headers)));
19006 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
19007 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
19008
19009 MockConnect connect1(ASYNC, OK, peer_addr);
19010 SequencedSocketData data1(connect1, reads1, writes1);
19011 session_deps_.socket_factory->AddSocketDataProvider(&data1);
19012
19013 AddSSLSocketData();
19014
19015 // Retry the second request on a second connection.
19016 SpdyTestUtil spdy_util2;
19017 spdy::SpdySerializedFrame req3(
19018 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
19019 MockWrite writes2[] = {
19020 CreateMockWrite(req3, 0),
19021 };
19022
19023 spdy::SpdySerializedFrame resp3(
19024 spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
19025 spdy::SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
19026 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
19027 MockRead(ASYNC, 0, 3)};
19028
19029 MockConnect connect2(ASYNC, OK, peer_addr);
19030 SequencedSocketData data2(connect2, reads2, writes2);
19031 session_deps_.socket_factory->AddSocketDataProvider(&data2);
19032
19033 AddSSLSocketData();
19034
19035 // Preload mail.example.org into HostCache.
Eric Orthf4db66a2019-02-19 21:35:3319036 int rv = session_deps_.host_resolver->LoadIntoCache(
19037 HostPortPair("mail.example.com", 443), base::nullopt);
19038 EXPECT_THAT(rv, IsOk());
Lily Chenfec60d92019-01-24 01:16:4219039
19040 HttpRequestInfo request1;
19041 request1.method = "GET";
19042 request1.url = GURL("https://www.example.org/");
19043 request1.load_flags = 0;
19044 request1.traffic_annotation =
19045 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19046 auto trans1 =
19047 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19048
Eric Orthf4db66a2019-02-19 21:35:3319049 TestCompletionCallback callback;
Lily Chenfec60d92019-01-24 01:16:4219050 rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
19051 EXPECT_THAT(callback.GetResult(rv), IsOk());
19052
19053 const HttpResponseInfo* response = trans1->GetResponseInfo();
19054 ASSERT_TRUE(response);
19055 ASSERT_TRUE(response->headers);
19056 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
19057 EXPECT_TRUE(response->was_fetched_via_spdy);
19058 EXPECT_TRUE(response->was_alpn_negotiated);
19059 std::string response_data;
19060 ASSERT_THAT(ReadTransaction(trans1.get(), &response_data), IsOk());
19061 EXPECT_EQ("hello!", response_data);
19062
19063 trans1.reset();
19064
19065 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
19066
19067 HttpRequestInfo request2;
19068 request2.method = "GET";
19069 request2.url = GURL("https://mail.example.org/");
19070 request2.load_flags = 0;
19071 request2.traffic_annotation =
19072 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19073 auto trans2 =
19074 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19075
19076 BoundTestNetLog log;
19077 rv = trans2->Start(&request2, callback.callback(), log.bound());
19078 EXPECT_THAT(callback.GetResult(rv), IsOk());
19079
19080 response = trans2->GetResponseInfo();
19081 ASSERT_TRUE(response);
19082 ASSERT_TRUE(response->headers);
19083 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
19084 EXPECT_TRUE(response->was_fetched_via_spdy);
19085 EXPECT_TRUE(response->was_alpn_negotiated);
19086 ASSERT_THAT(ReadTransaction(trans2.get(), &response_data), IsOk());
19087 EXPECT_EQ("hello!", response_data);
19088
19089 trans2.reset();
19090
19091 // One 200 report from the first request, then a 421 report from the
19092 // second request, then a 200 report from the successful retry.
19093 ASSERT_EQ(3u, network_error_logging_service()->errors().size());
19094
19095 // Check error report contents
19096 const NetworkErrorLoggingService::RequestDetails& error1 =
19097 network_error_logging_service()->errors()[0];
19098 EXPECT_EQ(GURL("https://www.example.org/"), error1.uri);
19099 EXPECT_TRUE(error1.referrer.is_empty());
19100 EXPECT_EQ("", error1.user_agent);
19101 EXPECT_EQ(ip, error1.server_ip);
19102 EXPECT_EQ("h2", error1.protocol);
19103 EXPECT_EQ("GET", error1.method);
19104 EXPECT_EQ(200, error1.status_code);
19105 EXPECT_EQ(OK, error1.type);
19106 EXPECT_EQ(0, error1.reporting_upload_depth);
19107
19108 const NetworkErrorLoggingService::RequestDetails& error2 =
19109 network_error_logging_service()->errors()[1];
19110 EXPECT_EQ(GURL("https://mail.example.org/"), error2.uri);
19111 EXPECT_TRUE(error2.referrer.is_empty());
19112 EXPECT_EQ("", error2.user_agent);
19113 EXPECT_EQ(ip, error2.server_ip);
19114 EXPECT_EQ("h2", error2.protocol);
19115 EXPECT_EQ("GET", error2.method);
19116 EXPECT_EQ(421, error2.status_code);
19117 EXPECT_EQ(OK, error2.type);
19118 EXPECT_EQ(0, error2.reporting_upload_depth);
19119
19120 const NetworkErrorLoggingService::RequestDetails& error3 =
19121 network_error_logging_service()->errors()[2];
19122 EXPECT_EQ(GURL("https://mail.example.org/"), error3.uri);
19123 EXPECT_TRUE(error3.referrer.is_empty());
19124 EXPECT_EQ("", error3.user_agent);
19125 EXPECT_EQ(ip, error3.server_ip);
19126 EXPECT_EQ("h2", error3.protocol);
19127 EXPECT_EQ("GET", error3.method);
19128 EXPECT_EQ(200, error3.status_code);
19129 EXPECT_EQ(OK, error3.type);
19130 EXPECT_EQ(0, error3.reporting_upload_depth);
Douglas Creageref5eecdc2018-11-09 20:50:3619131}
19132
Lily Chen00196ab62018-12-04 19:52:2919133TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, DontCreateReportHttp) {
19134 base::HistogramTester histograms;
19135 RequestPolicy();
19136 EXPECT_EQ(1u, network_error_logging_service()->headers().size());
19137 EXPECT_EQ(1u, network_error_logging_service()->errors().size());
19138
19139 // Make HTTP request
19140 std::string extra_header_string = extra_headers_.ToString();
19141 MockRead data_reads[] = {
19142 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
19143 MockRead("hello world"),
19144 MockRead(SYNCHRONOUS, OK),
19145 };
19146 MockWrite data_writes[] = {
19147 MockWrite("GET / HTTP/1.1\r\n"
19148 "Host: www.example.org\r\n"
19149 "Connection: keep-alive\r\n"),
19150 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
19151 };
19152
Lily Chen00196ab62018-12-04 19:52:2919153 StaticSocketDataProvider reads(data_reads, data_writes);
19154 session_deps_.socket_factory->AddSocketDataProvider(&reads);
19155
Lily Chenfec60d92019-01-24 01:16:4219156 // Insecure url
19157 url_ = "http://www.example.org/";
19158 request_.url = GURL(url_);
19159
Lily Chen00196ab62018-12-04 19:52:2919160 TestCompletionCallback callback;
19161 auto session = CreateSession(&session_deps_);
Lily Chenfec60d92019-01-24 01:16:4219162 auto trans =
19163 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19164 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
19165 EXPECT_THAT(callback.GetResult(rv), IsOk());
19166
19167 std::string response_data;
19168 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
19169 EXPECT_EQ("hello world", response_data);
Lily Chen00196ab62018-12-04 19:52:2919170
19171 // Insecure request does not generate a report
19172 histograms.ExpectBucketCount(
19173 NetworkErrorLoggingService::kRequestOutcomeHistogram,
19174 NetworkErrorLoggingService::RequestOutcome::DISCARDED_INSECURE_ORIGIN, 1);
19175
19176 EXPECT_EQ(1u, network_error_logging_service()->errors().size());
19177}
19178
19179TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
19180 DontCreateReportHttpError) {
19181 base::HistogramTester histograms;
19182 RequestPolicy();
19183 EXPECT_EQ(1u, network_error_logging_service()->headers().size());
19184 EXPECT_EQ(1u, network_error_logging_service()->errors().size());
19185
19186 // Make HTTP request that fails
19187 MockRead data_reads[] = {
19188 MockRead("hello world"),
19189 MockRead(SYNCHRONOUS, OK),
19190 };
19191
19192 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
19193 session_deps_.socket_factory->AddSocketDataProvider(&data);
19194
Lily Chenfec60d92019-01-24 01:16:4219195 url_ = "http://www.originwithoutpolicy.com:2000/";
19196 request_.url = GURL(url_);
19197
Lily Chen00196ab62018-12-04 19:52:2919198 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19199
Lily Chen00196ab62018-12-04 19:52:2919200 auto trans =
19201 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Lily Chen00196ab62018-12-04 19:52:2919202 TestCompletionCallback callback;
Lily Chenfec60d92019-01-24 01:16:4219203 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
Lily Chen00196ab62018-12-04 19:52:2919204 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_INVALID_HTTP_RESPONSE));
19205
19206 // Insecure request does not generate a report, regardless of existence of a
19207 // policy for the origin.
19208 histograms.ExpectBucketCount(
19209 NetworkErrorLoggingService::kRequestOutcomeHistogram,
19210 NetworkErrorLoggingService::RequestOutcome::DISCARDED_INSECURE_ORIGIN, 1);
19211
19212 EXPECT_EQ(1u, network_error_logging_service()->errors().size());
19213}
19214
Lily Chen90ae93cc2019-02-14 01:15:3919215// Don't report on proxy auth challenges, don't report if connecting through a
19216// proxy.
19217TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, DontCreateReportProxy) {
19218 HttpRequestInfo request;
19219 request.method = "GET";
19220 request.url = GURL("https://www.example.org/");
19221 request.traffic_annotation =
19222 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19223
19224 // Configure against proxy server "myproxy:70".
19225 session_deps_.proxy_resolution_service =
19226 ProxyResolutionService::CreateFixedFromPacResult(
19227 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
19228 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19229
19230 // Since we have proxy, should try to establish tunnel.
19231 MockWrite data_writes1[] = {
19232 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
19233 "Host: www.example.org:443\r\n"
19234 "Proxy-Connection: keep-alive\r\n\r\n"),
19235 };
19236
19237 // The proxy responds to the connect with a 407, using a non-persistent
19238 // connection.
19239 MockRead data_reads1[] = {
19240 // No credentials.
19241 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
19242 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
19243 MockRead("Proxy-Connection: close\r\n\r\n"),
19244 };
19245
19246 MockWrite data_writes2[] = {
19247 // After calling trans->RestartWithAuth(), this is the request we should
19248 // be issuing -- the final header line contains the credentials.
19249 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
19250 "Host: www.example.org:443\r\n"
19251 "Proxy-Connection: keep-alive\r\n"
19252 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
19253
19254 MockWrite("GET / HTTP/1.1\r\n"
19255 "Host: www.example.org\r\n"
19256 "Connection: keep-alive\r\n\r\n"),
19257 };
19258
19259 MockRead data_reads2[] = {
19260 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
19261
19262 MockRead("HTTP/1.1 200 OK\r\n"),
19263 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
19264 MockRead("Content-Length: 5\r\n\r\n"),
19265 MockRead(SYNCHRONOUS, "hello"),
19266 };
19267
19268 StaticSocketDataProvider data1(data_reads1, data_writes1);
19269 session_deps_.socket_factory->AddSocketDataProvider(&data1);
19270 StaticSocketDataProvider data2(data_reads2, data_writes2);
19271 session_deps_.socket_factory->AddSocketDataProvider(&data2);
19272 SSLSocketDataProvider ssl(ASYNC, OK);
19273 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
19274
19275 TestCompletionCallback callback1;
19276
19277 auto trans =
19278 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19279
19280 int rv = trans->Start(&request, callback1.callback(), NetLogWithSource());
19281 EXPECT_THAT(callback1.GetResult(rv), IsOk());
19282
19283 const HttpResponseInfo* response = trans->GetResponseInfo();
19284 EXPECT_EQ(407, response->headers->response_code());
19285
19286 std::string response_data;
19287 rv = ReadTransaction(trans.get(), &response_data);
19288 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
19289
19290 // No NEL report is generated for the 407.
19291 EXPECT_EQ(0u, network_error_logging_service()->errors().size());
19292
19293 TestCompletionCallback callback2;
19294
19295 rv =
19296 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
19297 EXPECT_THAT(callback2.GetResult(rv), IsOk());
19298
19299 response = trans->GetResponseInfo();
19300 EXPECT_EQ(200, response->headers->response_code());
19301
19302 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
19303 EXPECT_EQ("hello", response_data);
19304
19305 trans.reset();
19306
19307 // No NEL report is generated because we are behind a proxy.
19308 EXPECT_EQ(0u, network_error_logging_service()->errors().size());
19309}
19310
Douglas Creageref5eecdc2018-11-09 20:50:3619311TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
19312 ReportContainsUploadDepth) {
19313 reporting_upload_depth_ = 7;
Lily Chenfec60d92019-01-24 01:16:4219314 request_.reporting_upload_depth = reporting_upload_depth_;
Douglas Creageref5eecdc2018-11-09 20:50:3619315 RequestPolicy();
19316 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
Lily Chenfec60d92019-01-24 01:16:4219317 const NetworkErrorLoggingService::RequestDetails& error =
19318 network_error_logging_service()->errors()[0];
Douglas Creageref5eecdc2018-11-09 20:50:3619319 EXPECT_EQ(7, error.reporting_upload_depth);
19320}
19321
Lily Chenfec60d92019-01-24 01:16:4219322TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, ReportElapsedTime) {
19323 std::string extra_header_string = extra_headers_.ToString();
19324 static const base::TimeDelta kSleepDuration =
19325 base::TimeDelta::FromMilliseconds(10);
19326
19327 std::vector<MockWrite> data_writes = {
19328 MockWrite(ASYNC, 0,
19329 "GET / HTTP/1.1\r\n"
19330 "Host: www.example.org\r\n"
19331 "Connection: keep-alive\r\n"),
19332 MockWrite(ASYNC, 1, extra_header_string.data()),
19333 };
19334
19335 std::vector<MockRead> data_reads = {
19336 // Write one byte of the status line, followed by a pause.
19337 MockRead(ASYNC, 2, "H"),
19338 MockRead(ASYNC, ERR_IO_PENDING, 3),
19339 MockRead(ASYNC, 4, "TTP/1.1 200 OK\r\n\r\n"),
19340 MockRead(ASYNC, 5, "hello world"),
19341 MockRead(SYNCHRONOUS, OK, 6),
19342 };
19343
19344 SequencedSocketData data(data_reads, data_writes);
19345 session_deps_.socket_factory->AddSocketDataProvider(&data);
19346
19347 SSLSocketDataProvider ssl(ASYNC, OK);
19348 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
19349
19350 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19351
19352 auto trans =
19353 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19354
19355 TestCompletionCallback callback;
19356
19357 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
19358 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
19359
19360 data.RunUntilPaused();
19361 ASSERT_TRUE(data.IsPaused());
19362 FastForwardBy(kSleepDuration);
19363 data.Resume();
19364
19365 EXPECT_THAT(callback.GetResult(rv), IsOk());
19366
19367 std::string response_data;
19368 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
19369 EXPECT_EQ("hello world", response_data);
19370
19371 trans.reset();
19372
Douglas Creageref5eecdc2018-11-09 20:50:3619373 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
Lily Chenfec60d92019-01-24 01:16:4219374
19375 CheckReport(0 /* index */, 200 /* status_code */, OK);
19376
19377 const NetworkErrorLoggingService::RequestDetails& error =
19378 network_error_logging_service()->errors()[0];
19379
19380 // Sanity-check elapsed time in error report
19381 EXPECT_EQ(kSleepDuration, error.elapsed_time);
Douglas Creageref5eecdc2018-11-09 20:50:3619382}
Lily Chenfec60d92019-01-24 01:16:4219383
Douglas Creager3cb042052018-11-06 23:08:5219384#endif // BUILDFLAG(ENABLE_REPORTING)
19385
[email protected]89ceba9a2009-03-21 03:46:0619386} // namespace net