blob: ae5b2324085994a886c8c1a6f6fdbe03086dd52c [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
[email protected]68bf9152008-09-25 19:47:3017#include "base/compiler_specific.h"
[email protected]57999812013-02-24 05:40:5218#include "base/files/file_path.h"
thestigd8df0332014-09-04 06:33:2919#include "base/files/file_util.h"
[email protected]f3da152d2012-06-02 01:00:5720#include "base/json/json_writer.h"
Adam Rice425cf122015-01-19 06:18:2421#include "base/logging.h"
danakj1fd259a02016-04-16 03:17:0922#include "base/memory/ptr_util.h"
[email protected]bf828982013-08-14 18:01:4723#include "base/memory/weak_ptr.h"
[email protected]a34f61ee2014-03-18 20:59:4924#include "base/run_loop.h"
Avi Drissman4365a4782018-12-28 19:26:2425#include "base/stl_util.h"
Bence Békyd74f4382018-02-20 18:26:1926#include "base/strings/string_piece.h"
[email protected]125ef482013-06-11 18:32:4727#include "base/strings/string_util.h"
[email protected]750b2f3c2013-06-07 18:41:0528#include "base/strings/utf_string_conversions.h"
Douglas Creager3cb042052018-11-06 23:08:5229#include "base/test/metrics/histogram_tester.h"
Douglas Creager134b52e2018-11-09 18:00:1430#include "base/test/simple_test_clock.h"
31#include "base/test/simple_test_tick_clock.h"
[email protected]f36a8132011-09-02 18:36:3332#include "base/test/test_file_util.h"
gabf767595f2016-05-11 18:50:3533#include "base/threading/thread_task_runner_handle.h"
[email protected]277d5942010-08-11 21:02:3534#include "net/base/auth.h"
mmenkecbc2b712014-10-09 20:29:0735#include "net/base/chunked_upload_data_stream.h"
Bence Békya25e3f72018-02-13 21:13:3936#include "net/base/completion_once_callback.h"
mmenkecbc2b712014-10-09 20:29:0737#include "net/base/elements_upload_data_stream.h"
[email protected]58e32bb2013-01-21 18:23:2538#include "net/base/load_timing_info.h"
39#include "net/base/load_timing_info_test_util.h"
Adam Rice425cf122015-01-19 06:18:2440#include "net/base/net_errors.h"
tbansal28e68f82016-02-04 02:56:1541#include "net/base/proxy_delegate.h"
Lily Houghton582d4622018-01-22 22:43:4042#include "net/base/proxy_server.h"
[email protected]ac790b42009-12-02 04:31:3143#include "net/base/request_priority.h"
initial.commit586acc5fe2008-07-26 22:42:5244#include "net/base/test_completion_callback.h"
tbansal28e68f82016-02-04 02:56:1545#include "net/base/test_proxy_delegate.h"
[email protected]b2d26cfd2012-12-11 10:36:0646#include "net/base/upload_bytes_element_reader.h"
[email protected]d98961652012-09-11 20:27:2147#include "net/base/upload_file_element_reader.h"
Bence Béky230ac612017-08-30 19:17:0848#include "net/cert/cert_status_flags.h"
[email protected]6e7845ae2013-03-29 21:48:1149#include "net/cert/mock_cert_verifier.h"
[email protected]bc71b8772013-04-10 20:55:1650#include "net/dns/host_cache.h"
[email protected]f2cb3cf2013-03-21 01:40:5351#include "net/dns/mock_host_resolver.h"
[email protected]df41d0d82014-03-13 00:43:2452#include "net/http/http_auth_challenge_tokenizer.h"
[email protected]3c32c5f2010-05-18 15:18:1253#include "net/http/http_auth_handler_digest.h"
[email protected]3fd9dae2010-06-21 11:39:0054#include "net/http/http_auth_handler_mock.h"
[email protected]385a4672009-03-11 22:21:2955#include "net/http/http_auth_handler_ntlm.h"
aberentbba302d2015-12-03 10:20:1956#include "net/http/http_auth_scheme.h"
[email protected]0877e3d2009-10-17 22:29:5757#include "net/http/http_basic_stream.h"
initial.commit586acc5fe2008-07-26 22:42:5258#include "net/http/http_network_session.h"
[email protected]87bfa3f2010-09-30 14:54:5659#include "net/http/http_network_session_peer.h"
Adam Rice425cf122015-01-19 06:18:2460#include "net/http/http_request_headers.h"
mmenke5f94fda2016-06-02 20:54:1361#include "net/http/http_response_info.h"
[email protected]17291a022011-10-10 07:32:5362#include "net/http/http_server_properties_impl.h"
[email protected]0877e3d2009-10-17 22:29:5763#include "net/http/http_stream.h"
[email protected]8e6441ca2010-08-19 05:56:3864#include "net/http/http_stream_factory.h"
[email protected]c41737d2014-05-14 07:47:1965#include "net/http/http_transaction_test_util.h"
eroman87c53d62015-04-02 06:51:0766#include "net/log/net_log.h"
mikecirone8b85c432016-09-08 19:11:0067#include "net/log/net_log_event_type.h"
mikecironef22f9812016-10-04 03:40:1968#include "net/log/net_log_source.h"
vishal.b62985ca92015-04-17 08:45:5169#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4670#include "net/log/test_net_log_entry.h"
71#include "net/log/test_net_log_util.h"
Lily Houghton582d4622018-01-22 22:43:4072#include "net/proxy_resolution/mock_proxy_resolver.h"
73#include "net/proxy_resolution/proxy_config_service_fixed.h"
74#include "net/proxy_resolution/proxy_info.h"
Lily Houghtonffe89daa02018-03-09 18:30:0375#include "net/proxy_resolution/proxy_resolution_service.h"
Lily Houghton582d4622018-01-22 22:43:4076#include "net/proxy_resolution/proxy_resolver.h"
77#include "net/proxy_resolution/proxy_resolver_factory.h"
[email protected]f7984fc62009-06-22 23:26:4478#include "net/socket/client_socket_factory.h"
mmenked3641e12016-01-28 16:06:1579#include "net/socket/client_socket_pool.h"
[email protected]483fa202013-05-14 01:07:0380#include "net/socket/client_socket_pool_manager.h"
ttuttle1f2d7e92015-04-28 16:17:4781#include "net/socket/connection_attempts.h"
[email protected]a42dbd142011-11-17 16:42:0282#include "net/socket/mock_client_socket_pool_manager.h"
[email protected]bb88e1d32013-05-03 23:11:0783#include "net/socket/next_proto.h"
Paul Jensena457017a2018-01-19 23:52:0484#include "net/socket/socket_tag.h"
[email protected]f7984fc62009-06-22 23:26:4485#include "net/socket/socket_test_util.h"
86#include "net/socket/ssl_client_socket.h"
Bence Béky94658bf2018-05-11 19:22:5887#include "net/spdy/spdy_session.h"
88#include "net/spdy/spdy_session_pool.h"
89#include "net/spdy/spdy_test_util_common.h"
nharperb7441ef2016-01-25 23:54:1490#include "net/ssl/default_channel_id_store.h"
[email protected]536fd0b2013-03-14 17:41:5791#include "net/ssl/ssl_cert_request_info.h"
[email protected]e86839fd2013-08-14 18:29:0392#include "net/ssl/ssl_config_service.h"
[email protected]536fd0b2013-03-14 17:41:5793#include "net/ssl/ssl_info.h"
svaldez7872fd02015-11-19 21:10:5494#include "net/ssl/ssl_private_key.h"
[email protected]6e7845ae2013-03-29 21:48:1195#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:0196#include "net/test/gtest_util.h"
rsleevia69c79a2016-06-22 03:28:4397#include "net/test/test_data_directory.h"
Bence Béky98447b12018-05-08 03:14:0198#include "net/test/test_with_scoped_task_environment.h"
Victor Vasiliev27cc7712019-01-24 11:50:1499#include "net/third_party/quiche/src/spdy/core/spdy_framer.h"
[email protected]baee31a2018-01-18 06:10:23100#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
[email protected]831e4a32013-11-14 02:14:44101#include "net/websockets/websocket_handshake_stream_base.h"
Bence Békydca6bd92018-01-30 13:43:06102#include "net/websockets/websocket_test_util.h"
bncf4588402015-11-24 13:33:18103#include "testing/gmock/include/gmock/gmock.h"
initial.commit586acc5fe2008-07-26 22:42:52104#include "testing/gtest/include/gtest/gtest.h"
[email protected]23887f04f2008-12-02 19:20:15105#include "testing/platform_test.h"
[email protected]795cbf82013-07-22 09:37:27106#include "url/gurl.h"
initial.commit586acc5fe2008-07-26 22:42:52107
Zentaro Kavanagh5b27a6e22017-09-25 23:00:37108#if defined(NTLM_PORTABLE)
109#include "base/base64.h"
110#include "net/ntlm/ntlm_test_data.h"
111#endif
112
Douglas Creager3cb042052018-11-06 23:08:52113#if BUILDFLAG(ENABLE_REPORTING)
114#include "net/network_error_logging/network_error_logging_service.h"
115#include "net/network_error_logging/network_error_logging_test_util.h"
Douglas Creager134b52e2018-11-09 18:00:14116#include "net/reporting/reporting_cache.h"
117#include "net/reporting/reporting_client.h"
118#include "net/reporting/reporting_header_parser.h"
119#include "net/reporting/reporting_service.h"
120#include "net/reporting/reporting_test_util.h"
Douglas Creager3cb042052018-11-06 23:08:52121#endif // BUILDFLAG(ENABLE_REPORTING)
122
robpercival214763f2016-07-01 23:27:01123using net::test::IsError;
124using net::test::IsOk;
125
[email protected]ad65a3e2013-12-25 18:18:01126using base::ASCIIToUTF16;
127
initial.commit586acc5fe2008-07-26 22:42:52128//-----------------------------------------------------------------------------
129
ttuttle859dc7a2015-04-23 19:42:29130namespace net {
131
[email protected]13c8a092010-07-29 06:15:44132namespace {
133
[email protected]42cba2fb2013-03-29 19:58:57134const base::string16 kBar(ASCIIToUTF16("bar"));
135const base::string16 kBar2(ASCIIToUTF16("bar2"));
136const base::string16 kBar3(ASCIIToUTF16("bar3"));
137const base::string16 kBaz(ASCIIToUTF16("baz"));
138const base::string16 kFirst(ASCIIToUTF16("first"));
139const base::string16 kFoo(ASCIIToUTF16("foo"));
140const base::string16 kFoo2(ASCIIToUTF16("foo2"));
141const base::string16 kFoo3(ASCIIToUTF16("foo3"));
142const base::string16 kFou(ASCIIToUTF16("fou"));
143const base::string16 kSecond(ASCIIToUTF16("second"));
[email protected]42cba2fb2013-03-29 19:58:57144const base::string16 kWrongPassword(ASCIIToUTF16("wrongpassword"));
[email protected]13c8a092010-07-29 06:15:44145
bnc2df4b522016-07-08 18:17:43146const char kAlternativeServiceHttpHeader[] =
147 "Alt-Svc: h2=\"mail.example.org:443\"\r\n";
148
ttuttle859dc7a2015-04-23 19:42:29149int GetIdleSocketCountInTransportSocketPool(HttpNetworkSession* session) {
150 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
151 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02152}
153
ttuttle859dc7a2015-04-23 19:42:29154int GetIdleSocketCountInSSLSocketPool(HttpNetworkSession* session) {
155 return session->GetSSLSocketPool(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
[email protected]80a09a82012-11-16 17:40:06473 EXPECT_EQ("127.0.0.1", response->socket_address.host());
474 EXPECT_EQ(80, response->socket_address.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]e772db3f2010-07-12 18:11:13684typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
685CaptureGroupNameHttpProxySocketPool;
[email protected]2d731a32010-04-29 01:04:06686typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
[email protected]2227c692010-05-04 15:36:11687CaptureGroupNameSOCKSSocketPool;
[email protected]e60e47a2010-07-14 03:37:18688typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
689CaptureGroupNameSSLSocketPool;
690
rkaplowd90695c2015-03-25 22:12:41691template <typename ParentPool>
[email protected]e60e47a2010-07-14 03:37:18692CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34693 HostResolver* host_resolver,
694 CertVerifier* /* cert_verifier */)
tbansal7b403bcc2016-04-13 22:33:21695 : ParentPool(0, 0, host_resolver, NULL, NULL, NULL) {}
[email protected]e60e47a2010-07-14 03:37:18696
hashimoto0d3e4fb2015-01-09 05:02:50697template <>
[email protected]2df19bb2010-08-25 20:13:46698CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21699 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34700 CertVerifier* /* cert_verifier */)
Wojciech Dzierżanowski1f823562019-01-18 11:26:00701 : HttpProxyClientSocketPool(0, 0, NULL, NULL, NULL, NULL, NULL) {}
[email protected]2df19bb2010-08-25 20:13:46702
[email protected]007b3f82013-04-09 08:46:45703template <>
[email protected]e60e47a2010-07-14 03:37:18704CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21705 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34706 CertVerifier* cert_verifier)
[email protected]007b3f82013-04-09 08:46:45707 : SSLClientSocketPool(0,
708 0,
[email protected]007b3f82013-04-09 08:46:45709 cert_verifier,
710 NULL,
711 NULL,
[email protected]284303b62013-11-28 15:11:54712 NULL,
eranm6571b2b2014-12-03 15:53:23713 NULL,
[email protected]007b3f82013-04-09 08:46:45714 std::string(),
715 NULL,
716 NULL,
717 NULL,
718 NULL,
719 NULL,
Matt Menkec621aead02019-01-10 02:06:15720 NULL,
721 NULL) {}
[email protected]2227c692010-05-04 15:36:11722
[email protected]231d5a32008-09-13 00:45:27723//-----------------------------------------------------------------------------
724
[email protected]79cb5c12011-09-12 13:12:04725// Helper functions for validating that AuthChallengeInfo's are correctly
726// configured for common cases.
727bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
728 if (!auth_challenge)
729 return false;
730 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43731 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04732 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19733 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04734 return true;
735}
736
737bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
738 if (!auth_challenge)
739 return false;
740 EXPECT_TRUE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43741 EXPECT_EQ("http://myproxy:70", auth_challenge->challenger.Serialize());
742 EXPECT_EQ("MyRealm1", auth_challenge->realm);
743 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
744 return true;
745}
746
747bool CheckBasicSecureProxyAuth(const AuthChallengeInfo* auth_challenge) {
748 if (!auth_challenge)
749 return false;
750 EXPECT_TRUE(auth_challenge->is_proxy);
751 EXPECT_EQ("https://myproxy:70", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04752 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19753 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04754 return true;
755}
756
757bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
758 if (!auth_challenge)
759 return false;
760 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43761 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04762 EXPECT_EQ("digestive", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19763 EXPECT_EQ(kDigestAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04764 return true;
765}
766
thakis84dff942015-07-28 20:47:38767#if defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04768bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
769 if (!auth_challenge)
770 return false;
771 EXPECT_FALSE(auth_challenge->is_proxy);
Zentaro Kavanagh1890a3d2018-01-29 19:52:55772 EXPECT_EQ("https://server", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04773 EXPECT_EQ(std::string(), auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19774 EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04775 return true;
776}
David Benjamin5cb91132018-04-06 05:54:49777
778bool CheckNTLMProxyAuth(const AuthChallengeInfo* auth_challenge) {
779 if (!auth_challenge)
780 return false;
781 EXPECT_TRUE(auth_challenge->is_proxy);
782 EXPECT_EQ("http://server", auth_challenge->challenger.Serialize());
783 EXPECT_EQ(std::string(), auth_challenge->realm);
784 EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
785 return true;
786}
thakis84dff942015-07-28 20:47:38787#endif // defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04788
[email protected]448d4ca52012-03-04 04:12:23789} // namespace
790
bncd16676a2016-07-20 16:23:01791TEST_F(HttpNetworkTransactionTest, Basic) {
danakj1fd259a02016-04-16 03:17:09792 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16793 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]231d5a32008-09-13 00:45:27794}
795
bncd16676a2016-07-20 16:23:01796TEST_F(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27797 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35798 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
799 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06800 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27801 };
Ryan Sleevib8d7ea02018-05-07 20:01:01802 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01803 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27804 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
805 EXPECT_EQ("hello world", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01806 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22807 EXPECT_EQ(reads_size, out.total_received_bytes);
ttuttle1f2d7e92015-04-28 16:17:47808 EXPECT_EQ(0u, out.connection_attempts.size());
ttuttled9dbc652015-09-29 20:00:59809
810 EXPECT_FALSE(out.remote_endpoint_after_start.address().empty());
[email protected]231d5a32008-09-13 00:45:27811}
812
813// Response with no status line.
bncd16676a2016-07-20 16:23:01814TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27815 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35816 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06817 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27818 };
Ryan Sleevib8d7ea02018-05-07 20:01:01819 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41820 EXPECT_THAT(out.rv, IsOk());
821 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
822 EXPECT_EQ("hello world", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01823 int64_t reads_size = CountReadBytes(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41824 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27825}
826
mmenkea7da6da2016-09-01 21:56:52827// Response with no status line, and a weird port. Should fail by default.
828TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPort) {
829 MockRead data_reads[] = {
830 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
831 };
832
Ryan Sleevib8d7ea02018-05-07 20:01:01833 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
mmenkea7da6da2016-09-01 21:56:52834 session_deps_.socket_factory->AddSocketDataProvider(&data);
835
836 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
837
krasinc06a72a2016-12-21 03:42:46838 HttpRequestInfo request;
bnc87dcefc2017-05-25 12:47:58839 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:19840 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenkea7da6da2016-09-01 21:56:52841
mmenkea7da6da2016-09-01 21:56:52842 request.method = "GET";
843 request.url = GURL("http://www.example.com:2000/");
Ramin Halavatib5e433e2018-02-07 07:41:10844 request.traffic_annotation =
845 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
846
mmenkea7da6da2016-09-01 21:56:52847 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20848 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52849 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_INVALID_HTTP_RESPONSE));
850}
851
Shivani Sharmafdcaefd2017-11-02 00:12:26852// Tests that request info can be destroyed after the headers phase is complete.
853TEST_F(HttpNetworkTransactionTest, SimpleGETNoReadDestroyRequestInfo) {
854 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
855 auto trans =
856 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
857
858 MockRead data_reads[] = {
859 MockRead("HTTP/1.0 200 OK\r\n"), MockRead("Connection: keep-alive\r\n"),
860 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, 0),
861 };
Ryan Sleevib8d7ea02018-05-07 20:01:01862 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
Shivani Sharmafdcaefd2017-11-02 00:12:26863 session_deps_.socket_factory->AddSocketDataProvider(&data);
864
865 TestCompletionCallback callback;
866
867 {
868 auto request = std::make_unique<HttpRequestInfo>();
869 request->method = "GET";
870 request->url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:10871 request->traffic_annotation =
872 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Shivani Sharmafdcaefd2017-11-02 00:12:26873
874 int rv =
875 trans->Start(request.get(), callback.callback(), NetLogWithSource());
876
877 EXPECT_THAT(callback.GetResult(rv), IsOk());
878 } // Let request info be destroyed.
879
880 trans.reset();
881}
882
mmenkea7da6da2016-09-01 21:56:52883// Response with no status line, and a weird port. Option to allow weird ports
884// enabled.
885TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPortAllowed) {
886 MockRead data_reads[] = {
887 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
888 };
889
Ryan Sleevib8d7ea02018-05-07 20:01:01890 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
mmenkea7da6da2016-09-01 21:56:52891 session_deps_.socket_factory->AddSocketDataProvider(&data);
892 session_deps_.http_09_on_non_default_ports_enabled = true;
893 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
894
krasinc06a72a2016-12-21 03:42:46895 HttpRequestInfo request;
bnc87dcefc2017-05-25 12:47:58896 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:19897 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenkea7da6da2016-09-01 21:56:52898
mmenkea7da6da2016-09-01 21:56:52899 request.method = "GET";
900 request.url = GURL("http://www.example.com:2000/");
Ramin Halavatib5e433e2018-02-07 07:41:10901 request.traffic_annotation =
902 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
903
mmenkea7da6da2016-09-01 21:56:52904 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20905 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52906 EXPECT_THAT(callback.GetResult(rv), IsOk());
907
908 const HttpResponseInfo* info = trans->GetResponseInfo();
909 ASSERT_TRUE(info->headers);
910 EXPECT_EQ("HTTP/0.9 200 OK", info->headers->GetStatusLine());
911
912 // Don't bother to read the body - that's verified elsewhere, important thing
913 // is that the option to allow HTTP/0.9 on non-default ports is respected.
914}
915
[email protected]231d5a32008-09-13 00:45:27916// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01917TEST_F(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27918 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35919 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06920 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27921 };
Ryan Sleevib8d7ea02018-05-07 20:01:01922 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01923 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27924 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
925 EXPECT_EQ("DATA", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01926 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22927 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27928}
929
930// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01931TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27932 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35933 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06934 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27935 };
Ryan Sleevib8d7ea02018-05-07 20:01:01936 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01937 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27938 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
939 EXPECT_EQ("DATA", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01940 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22941 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27942}
943
944// Beyond 4 bytes of slop and it should fail to find a status line.
bncd16676a2016-07-20 16:23:01945TEST_F(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27946 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35947 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06948 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27949 };
Ryan Sleevib8d7ea02018-05-07 20:01:01950 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41951 EXPECT_THAT(out.rv, IsOk());
952 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
953 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01954 int64_t reads_size = CountReadBytes(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41955 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27956}
957
958// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
bncd16676a2016-07-20 16:23:01959TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27960 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35961 MockRead("\n"),
962 MockRead("\n"),
963 MockRead("Q"),
964 MockRead("J"),
965 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06966 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27967 };
Ryan Sleevib8d7ea02018-05-07 20:01:01968 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01969 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27970 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
971 EXPECT_EQ("DATA", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01972 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22973 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27974}
975
976// Close the connection before enough bytes to have a status line.
bncd16676a2016-07-20 16:23:01977TEST_F(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:27978 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35979 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:06980 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27981 };
Ryan Sleevib8d7ea02018-05-07 20:01:01982 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41983 EXPECT_THAT(out.rv, IsOk());
984 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
985 EXPECT_EQ("HTT", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01986 int64_t reads_size = CountReadBytes(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41987 EXPECT_EQ(reads_size, out.total_received_bytes);
initial.commit586acc5fe2008-07-26 22:42:52988}
989
[email protected]f9d44aa2008-09-23 23:57:17990// Simulate a 204 response, lacking a Content-Length header, sent over a
991// persistent connection. The response should still terminate since a 204
992// cannot have a response body.
bncd16676a2016-07-20 16:23:01993TEST_F(HttpNetworkTransactionTest, StopsReading204) {
[email protected]b8015c42013-12-24 15:18:19994 char junk[] = "junk";
[email protected]f9d44aa2008-09-23 23:57:17995 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35996 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
[email protected]b8015c42013-12-24 15:18:19997 MockRead(junk), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:06998 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:17999 };
Ryan Sleevib8d7ea02018-05-07 20:01:011000 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011001 EXPECT_THAT(out.rv, IsOk());
[email protected]f9d44aa2008-09-23 23:57:171002 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
1003 EXPECT_EQ("", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:011004 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:221005 int64_t response_size = reads_size - strlen(junk);
1006 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]f9d44aa2008-09-23 23:57:171007}
1008
[email protected]0877e3d2009-10-17 22:29:571009// A simple request using chunked encoding with some extra data after.
bncd16676a2016-07-20 16:23:011010TEST_F(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]b8015c42013-12-24 15:18:191011 std::string final_chunk = "0\r\n\r\n";
1012 std::string extra_data = "HTTP/1.1 200 OK\r\n";
1013 std::string last_read = final_chunk + extra_data;
[email protected]0877e3d2009-10-17 22:29:571014 MockRead data_reads[] = {
1015 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
1016 MockRead("5\r\nHello\r\n"),
1017 MockRead("1\r\n"),
1018 MockRead(" \r\n"),
1019 MockRead("5\r\nworld\r\n"),
[email protected]b8015c42013-12-24 15:18:191020 MockRead(last_read.data()),
[email protected]8ddf8322012-02-23 18:08:061021 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:571022 };
Ryan Sleevib8d7ea02018-05-07 20:01:011023 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011024 EXPECT_THAT(out.rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:571025 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1026 EXPECT_EQ("Hello world", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:011027 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:221028 int64_t response_size = reads_size - extra_data.size();
1029 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]0877e3d2009-10-17 22:29:571030}
1031
[email protected]9fe44f52010-09-23 18:36:001032// Next tests deal with http://crbug.com/56344.
1033
bncd16676a2016-07-20 16:23:011034TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001035 MultipleContentLengthHeadersNoTransferEncoding) {
1036 MockRead data_reads[] = {
1037 MockRead("HTTP/1.1 200 OK\r\n"),
1038 MockRead("Content-Length: 10\r\n"),
1039 MockRead("Content-Length: 5\r\n\r\n"),
1040 };
Ryan Sleevib8d7ea02018-05-07 20:01:011041 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011042 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]9fe44f52010-09-23 18:36:001043}
1044
bncd16676a2016-07-20 16:23:011045TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:041046 DuplicateContentLengthHeadersNoTransferEncoding) {
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\r\n"),
1051 MockRead("Hello"),
1052 };
Ryan Sleevib8d7ea02018-05-07 20:01:011053 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011054 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041055 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1056 EXPECT_EQ("Hello", out.response_data);
1057}
1058
bncd16676a2016-07-20 16:23:011059TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:041060 ComplexContentLengthHeadersNoTransferEncoding) {
1061 // More than 2 dupes.
1062 {
1063 MockRead data_reads[] = {
1064 MockRead("HTTP/1.1 200 OK\r\n"),
1065 MockRead("Content-Length: 5\r\n"),
1066 MockRead("Content-Length: 5\r\n"),
1067 MockRead("Content-Length: 5\r\n\r\n"),
1068 MockRead("Hello"),
1069 };
Ryan Sleevib8d7ea02018-05-07 20:01:011070 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011071 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041072 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1073 EXPECT_EQ("Hello", out.response_data);
1074 }
1075 // HTTP/1.0
1076 {
1077 MockRead data_reads[] = {
1078 MockRead("HTTP/1.0 200 OK\r\n"),
1079 MockRead("Content-Length: 5\r\n"),
1080 MockRead("Content-Length: 5\r\n"),
1081 MockRead("Content-Length: 5\r\n\r\n"),
1082 MockRead("Hello"),
1083 };
Ryan Sleevib8d7ea02018-05-07 20:01:011084 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011085 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041086 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
1087 EXPECT_EQ("Hello", out.response_data);
1088 }
1089 // 2 dupes and one mismatched.
1090 {
1091 MockRead data_reads[] = {
1092 MockRead("HTTP/1.1 200 OK\r\n"),
1093 MockRead("Content-Length: 10\r\n"),
1094 MockRead("Content-Length: 10\r\n"),
1095 MockRead("Content-Length: 5\r\n\r\n"),
1096 };
Ryan Sleevib8d7ea02018-05-07 20:01:011097 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011098 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]44b52042010-10-29 22:48:041099 }
1100}
1101
bncd16676a2016-07-20 16:23:011102TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001103 MultipleContentLengthHeadersTransferEncoding) {
1104 MockRead data_reads[] = {
1105 MockRead("HTTP/1.1 200 OK\r\n"),
1106 MockRead("Content-Length: 666\r\n"),
1107 MockRead("Content-Length: 1337\r\n"),
1108 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
1109 MockRead("5\r\nHello\r\n"),
1110 MockRead("1\r\n"),
1111 MockRead(" \r\n"),
1112 MockRead("5\r\nworld\r\n"),
1113 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:061114 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:001115 };
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]9fe44f52010-09-23 18:36:001118 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1119 EXPECT_EQ("Hello world", out.response_data);
1120}
1121
[email protected]1628fe92011-10-04 23:04:551122// Next tests deal with http://crbug.com/98895.
1123
1124// Checks that a single Content-Disposition header results in no error.
bncd16676a2016-07-20 16:23:011125TEST_F(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:551126 MockRead data_reads[] = {
1127 MockRead("HTTP/1.1 200 OK\r\n"),
1128 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
1129 MockRead("Content-Length: 5\r\n\r\n"),
1130 MockRead("Hello"),
1131 };
Ryan Sleevib8d7ea02018-05-07 20:01:011132 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011133 EXPECT_THAT(out.rv, IsOk());
[email protected]1628fe92011-10-04 23:04:551134 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1135 EXPECT_EQ("Hello", out.response_data);
1136}
1137
[email protected]54a9c6e52012-03-21 20:10:591138// Checks that two identical Content-Disposition headers result in no error.
bncd16676a2016-07-20 16:23:011139TEST_F(HttpNetworkTransactionTest, TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551140 MockRead data_reads[] = {
1141 MockRead("HTTP/1.1 200 OK\r\n"),
1142 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1143 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1144 MockRead("Content-Length: 5\r\n\r\n"),
1145 MockRead("Hello"),
1146 };
Ryan Sleevib8d7ea02018-05-07 20:01:011147 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011148 EXPECT_THAT(out.rv, IsOk());
[email protected]54a9c6e52012-03-21 20:10:591149 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1150 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:551151}
1152
1153// Checks that two distinct Content-Disposition headers result in an error.
bncd16676a2016-07-20 16:23:011154TEST_F(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551155 MockRead data_reads[] = {
1156 MockRead("HTTP/1.1 200 OK\r\n"),
1157 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1158 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
1159 MockRead("Content-Length: 5\r\n\r\n"),
1160 MockRead("Hello"),
1161 };
Ryan Sleevib8d7ea02018-05-07 20:01:011162 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011163 EXPECT_THAT(out.rv,
1164 IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION));
[email protected]1628fe92011-10-04 23:04:551165}
1166
[email protected]54a9c6e52012-03-21 20:10:591167// Checks that two identical Location headers result in no error.
1168// Also tests Location header behavior.
bncd16676a2016-07-20 16:23:011169TEST_F(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551170 MockRead data_reads[] = {
1171 MockRead("HTTP/1.1 302 Redirect\r\n"),
1172 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:591173 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:551174 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061175 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551176 };
1177
1178 HttpRequestInfo request;
1179 request.method = "GET";
1180 request.url = GURL("http://redirect.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101181 request.traffic_annotation =
1182 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1628fe92011-10-04 23:04:551183
danakj1fd259a02016-04-16 03:17:091184 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161185 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1628fe92011-10-04 23:04:551186
Ryan Sleevib8d7ea02018-05-07 20:01:011187 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071188 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:551189
[email protected]49639fa2011-12-20 23:22:411190 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:551191
tfarina42834112016-09-22 13:38:201192 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011193 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1628fe92011-10-04 23:04:551194
robpercival214763f2016-07-01 23:27:011195 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]1628fe92011-10-04 23:04:551196
bnc691fda62016-08-12 00:43:161197 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521198 ASSERT_TRUE(response);
1199 ASSERT_TRUE(response->headers);
[email protected]1628fe92011-10-04 23:04:551200 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
1201 std::string url;
1202 EXPECT_TRUE(response->headers->IsRedirect(&url));
1203 EXPECT_EQ("http://good.com/", url);
tbansal2ecbbc72016-10-06 17:15:471204 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]1628fe92011-10-04 23:04:551205}
1206
[email protected]1628fe92011-10-04 23:04:551207// Checks that two distinct Location headers result in an error.
bncd16676a2016-07-20 16:23:011208TEST_F(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551209 MockRead data_reads[] = {
1210 MockRead("HTTP/1.1 302 Redirect\r\n"),
1211 MockRead("Location: http://good.com/\r\n"),
1212 MockRead("Location: http://evil.com/\r\n"),
1213 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061214 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551215 };
Ryan Sleevib8d7ea02018-05-07 20:01:011216 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011217 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION));
[email protected]1628fe92011-10-04 23:04:551218}
1219
[email protected]ef0faf2e72009-03-05 23:27:231220// Do a request using the HEAD method. Verify that we don't try to read the
1221// message body (since HEAD has none).
bncd16676a2016-07-20 16:23:011222TEST_F(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:421223 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:231224 request.method = "HEAD";
bncce36dca22015-04-21 22:11:231225 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:101226 request.traffic_annotation =
1227 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ef0faf2e72009-03-05 23:27:231228
danakj1fd259a02016-04-16 03:17:091229 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161230 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:091231 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:161232 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:091233 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
1234 base::Unretained(&headers_handler)));
[email protected]cb9bf6ca2011-01-28 13:15:271235
[email protected]ef0faf2e72009-03-05 23:27:231236 MockWrite data_writes1[] = {
csharrisonf473dd192015-08-18 13:54:131237 MockWrite("HEAD / HTTP/1.1\r\n"
1238 "Host: www.example.org\r\n"
1239 "Connection: keep-alive\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231240 };
1241 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:231242 MockRead("HTTP/1.1 404 Not Found\r\n"), MockRead("Server: Blah\r\n"),
1243 MockRead("Content-Length: 1234\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231244
mmenked39192ee2015-12-09 00:57:231245 // No response body because the test stops reading here.
1246 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]ef0faf2e72009-03-05 23:27:231247 };
1248
Ryan Sleevib8d7ea02018-05-07 20:01:011249 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:071250 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:231251
[email protected]49639fa2011-12-20 23:22:411252 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:231253
tfarina42834112016-09-22 13:38:201254 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011255 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ef0faf2e72009-03-05 23:27:231256
1257 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:011258 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231259
bnc691fda62016-08-12 00:43:161260 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521261 ASSERT_TRUE(response);
[email protected]ef0faf2e72009-03-05 23:27:231262
1263 // Check that the headers got parsed.
wezca1070932016-05-26 20:30:521264 EXPECT_TRUE(response->headers);
[email protected]ef0faf2e72009-03-05 23:27:231265 EXPECT_EQ(1234, response->headers->GetContentLength());
1266 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471267 EXPECT_TRUE(response->proxy_server.is_direct());
ryansturm49a8cb12016-06-15 16:51:091268 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
1269 EXPECT_FALSE(headers_handler.observed_before_headers_sent_with_proxy());
[email protected]ef0faf2e72009-03-05 23:27:231270
1271 std::string server_header;
olli.raulaee489a52016-01-25 08:37:101272 size_t iter = 0;
[email protected]ef0faf2e72009-03-05 23:27:231273 bool has_server_header = response->headers->EnumerateHeader(
1274 &iter, "Server", &server_header);
1275 EXPECT_TRUE(has_server_header);
1276 EXPECT_EQ("Blah", server_header);
1277
1278 // Reading should give EOF right away, since there is no message body
1279 // (despite non-zero content-length).
1280 std::string response_data;
bnc691fda62016-08-12 00:43:161281 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011282 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231283 EXPECT_EQ("", response_data);
1284}
1285
bncd16676a2016-07-20 16:23:011286TEST_F(HttpNetworkTransactionTest, ReuseConnection) {
danakj1fd259a02016-04-16 03:17:091287 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:521288
1289 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351290 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1291 MockRead("hello"),
1292 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1293 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061294 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521295 };
Ryan Sleevib8d7ea02018-05-07 20:01:011296 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071297 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521298
[email protected]0b0bf032010-09-21 18:08:501299 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521300 "hello", "world"
1301 };
1302
1303 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:421304 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521305 request.method = "GET";
bncce36dca22015-04-21 22:11:231306 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:101307 request.traffic_annotation =
1308 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:521309
bnc691fda62016-08-12 00:43:161310 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271311
[email protected]49639fa2011-12-20 23:22:411312 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521313
tfarina42834112016-09-22 13:38:201314 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011315 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521316
1317 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011318 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521319
bnc691fda62016-08-12 00:43:161320 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521321 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521322
wezca1070932016-05-26 20:30:521323 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251324 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471325 EXPECT_TRUE(response->proxy_server.is_direct());
initial.commit586acc5fe2008-07-26 22:42:521326
1327 std::string response_data;
bnc691fda62016-08-12 00:43:161328 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011329 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251330 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521331 }
1332}
1333
bncd16676a2016-07-20 16:23:011334TEST_F(HttpNetworkTransactionTest, Ignores100) {
danakj1fd259a02016-04-16 03:17:091335 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:221336 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:191337 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:221338 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:271339
[email protected]1c773ea12009-04-28 19:58:421340 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521341 request.method = "POST";
1342 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271343 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:101344 request.traffic_annotation =
1345 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:521346
shivanishab9a143952016-09-19 17:23:411347 // Check the upload progress returned before initialization is correct.
1348 UploadProgress progress = request.upload_data_stream->GetUploadProgress();
1349 EXPECT_EQ(0u, progress.size());
1350 EXPECT_EQ(0u, progress.position());
1351
danakj1fd259a02016-04-16 03:17:091352 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161353 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271354
initial.commit586acc5fe2008-07-26 22:42:521355 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351356 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1357 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1358 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061359 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521360 };
Ryan Sleevib8d7ea02018-05-07 20:01:011361 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071362 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521363
[email protected]49639fa2011-12-20 23:22:411364 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521365
tfarina42834112016-09-22 13:38:201366 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011367 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521368
1369 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011370 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521371
bnc691fda62016-08-12 00:43:161372 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521373 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521374
wezca1070932016-05-26 20:30:521375 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251376 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521377
1378 std::string response_data;
bnc691fda62016-08-12 00:43:161379 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011380 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251381 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521382}
1383
[email protected]3a2d3662009-03-27 03:49:141384// This test is almost the same as Ignores100 above, but the response contains
1385// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571386// HTTP/1.1 and the two status headers are read in one read.
bncd16676a2016-07-20 16:23:011387TEST_F(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421388 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141389 request.method = "GET";
1390 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101391 request.traffic_annotation =
1392 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3a2d3662009-03-27 03:49:141393
danakj1fd259a02016-04-16 03:17:091394 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161395 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271396
[email protected]3a2d3662009-03-27 03:49:141397 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571398 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1399 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141400 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061401 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141402 };
Ryan Sleevib8d7ea02018-05-07 20:01:011403 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071404 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141405
[email protected]49639fa2011-12-20 23:22:411406 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141407
tfarina42834112016-09-22 13:38:201408 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011409 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3a2d3662009-03-27 03:49:141410
1411 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011412 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141413
bnc691fda62016-08-12 00:43:161414 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521415 ASSERT_TRUE(response);
[email protected]3a2d3662009-03-27 03:49:141416
wezca1070932016-05-26 20:30:521417 EXPECT_TRUE(response->headers);
[email protected]3a2d3662009-03-27 03:49:141418 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1419
1420 std::string response_data;
bnc691fda62016-08-12 00:43:161421 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011422 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141423 EXPECT_EQ("hello world", response_data);
1424}
1425
Andrew Comminos517a92c2019-01-14 17:49:561426TEST_F(HttpNetworkTransactionTest, LoadTimingMeasuresTimeToFirstByteForHttp) {
1427 static const base::TimeDelta kDelayAfterFirstByte =
Andrew Comminos1f2ff1cc2018-12-14 05:22:381428 base::TimeDelta::FromMilliseconds(10);
1429
1430 HttpRequestInfo request;
1431 request.method = "GET";
1432 request.url = GURL("http://www.foo.com/");
1433 request.traffic_annotation =
1434 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1435
1436 std::vector<MockWrite> data_writes = {
1437 MockWrite(ASYNC, 0,
1438 "GET / HTTP/1.1\r\n"
1439 "Host: www.foo.com\r\n"
1440 "Connection: keep-alive\r\n\r\n"),
1441 };
1442
1443 std::vector<MockRead> data_reads = {
1444 // Write one byte of the status line, followed by a pause.
1445 MockRead(ASYNC, 1, "H"),
1446 MockRead(ASYNC, ERR_IO_PENDING, 2),
1447 MockRead(ASYNC, 3, "TTP/1.1 200 OK\r\n\r\n"),
1448 MockRead(ASYNC, 4, "hello world"),
1449 MockRead(SYNCHRONOUS, OK, 5),
1450 };
1451
1452 SequencedSocketData data(data_reads, data_writes);
1453 session_deps_.socket_factory->AddSocketDataProvider(&data);
1454
1455 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1456
1457 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1458
1459 TestCompletionCallback callback;
1460
1461 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1462 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1463
1464 data.RunUntilPaused();
1465 ASSERT_TRUE(data.IsPaused());
Andrew Comminos517a92c2019-01-14 17:49:561466 FastForwardBy(kDelayAfterFirstByte);
Andrew Comminos1f2ff1cc2018-12-14 05:22:381467 data.Resume();
1468
1469 rv = callback.WaitForResult();
1470 EXPECT_THAT(rv, IsOk());
1471
1472 const HttpResponseInfo* response = trans.GetResponseInfo();
1473 ASSERT_TRUE(response);
1474
1475 EXPECT_TRUE(response->headers);
1476 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1477
1478 LoadTimingInfo load_timing_info;
1479 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
1480 EXPECT_FALSE(load_timing_info.receive_headers_start.is_null());
1481 EXPECT_FALSE(load_timing_info.connect_timing.connect_end.is_null());
Andrew Comminos517a92c2019-01-14 17:49:561482 // Ensure we didn't include the delay in the TTFB time.
1483 EXPECT_EQ(load_timing_info.receive_headers_start,
1484 load_timing_info.connect_timing.connect_end);
1485 // Ensure that the mock clock advanced at all.
1486 EXPECT_EQ(base::TimeTicks::Now() - load_timing_info.receive_headers_start,
1487 kDelayAfterFirstByte);
Andrew Comminos1f2ff1cc2018-12-14 05:22:381488
1489 std::string response_data;
1490 rv = ReadTransaction(&trans, &response_data);
1491 EXPECT_THAT(rv, IsOk());
1492 EXPECT_EQ("hello world", response_data);
1493}
1494
1495// Tests that the time-to-first-byte reported in a transaction's load timing
1496// info uses the first response, even if 1XX/informational.
1497void HttpNetworkTransactionTest::Check100ResponseTiming(bool use_spdy) {
Andrew Comminos517a92c2019-01-14 17:49:561498 static const base::TimeDelta kDelayAfter100Response =
Andrew Comminos1f2ff1cc2018-12-14 05:22:381499 base::TimeDelta::FromMilliseconds(10);
1500
1501 HttpRequestInfo request;
1502 request.method = "GET";
1503 request.url = GURL("https://www.foo.com/");
1504 request.traffic_annotation =
1505 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1506
1507 SSLSocketDataProvider ssl(ASYNC, OK);
1508 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
1509
1510 std::vector<MockWrite> data_writes;
1511 std::vector<MockRead> data_reads;
1512
1513 spdy::SpdySerializedFrame spdy_req(
1514 spdy_util_.ConstructSpdyGet(request.url.spec().c_str(), 1, LOWEST));
1515
1516 spdy::SpdyHeaderBlock spdy_resp1_headers;
1517 spdy_resp1_headers[spdy::kHttp2StatusHeader] = "100";
1518 spdy::SpdySerializedFrame spdy_resp1(
1519 spdy_util_.ConstructSpdyReply(1, spdy_resp1_headers.Clone()));
1520 spdy::SpdySerializedFrame spdy_resp2(
1521 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
1522 spdy::SpdySerializedFrame spdy_data(
1523 spdy_util_.ConstructSpdyDataFrame(1, "hello world", true));
1524
1525 if (use_spdy) {
1526 ssl.next_proto = kProtoHTTP2;
1527
1528 data_writes = {CreateMockWrite(spdy_req, 0)};
1529
1530 data_reads = {
1531 CreateMockRead(spdy_resp1, 1), MockRead(ASYNC, ERR_IO_PENDING, 2),
1532 CreateMockRead(spdy_resp2, 3), CreateMockRead(spdy_data, 4),
1533 MockRead(SYNCHRONOUS, OK, 5),
1534 };
1535 } else {
1536 data_writes = {
1537 MockWrite(ASYNC, 0,
1538 "GET / HTTP/1.1\r\n"
1539 "Host: www.foo.com\r\n"
1540 "Connection: keep-alive\r\n\r\n"),
1541 };
1542
1543 data_reads = {
1544 MockRead(ASYNC, 1, "HTTP/1.1 100 Continue\r\n\r\n"),
1545 MockRead(ASYNC, ERR_IO_PENDING, 2),
1546
1547 MockRead(ASYNC, 3, "HTTP/1.1 200 OK\r\n\r\n"),
1548 MockRead(ASYNC, 4, "hello world"),
1549 MockRead(SYNCHRONOUS, OK, 5),
1550 };
1551 }
1552
1553 SequencedSocketData data(data_reads, data_writes);
1554 session_deps_.socket_factory->AddSocketDataProvider(&data);
1555
1556 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1557
1558 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1559
1560 TestCompletionCallback callback;
1561
1562 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1563 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1564
1565 data.RunUntilPaused();
1566 // We should now have parsed the 100 response and hit ERR_IO_PENDING. Insert
1567 // the delay before parsing the 200 response.
1568 ASSERT_TRUE(data.IsPaused());
Andrew Comminos517a92c2019-01-14 17:49:561569 FastForwardBy(kDelayAfter100Response);
Andrew Comminos1f2ff1cc2018-12-14 05:22:381570 data.Resume();
1571
1572 rv = callback.WaitForResult();
1573 EXPECT_THAT(rv, IsOk());
1574
1575 const HttpResponseInfo* response = trans.GetResponseInfo();
1576 ASSERT_TRUE(response);
1577
1578 LoadTimingInfo load_timing_info;
1579 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
1580 EXPECT_FALSE(load_timing_info.receive_headers_start.is_null());
1581 EXPECT_FALSE(load_timing_info.connect_timing.connect_end.is_null());
Andrew Comminos517a92c2019-01-14 17:49:561582 // Ensure we didn't include the delay in the TTFB time.
1583 EXPECT_EQ(load_timing_info.receive_headers_start,
1584 load_timing_info.connect_timing.connect_end);
1585 // Ensure that the mock clock advanced at all.
1586 EXPECT_EQ(base::TimeTicks::Now() - load_timing_info.receive_headers_start,
1587 kDelayAfter100Response);
Andrew Comminos1f2ff1cc2018-12-14 05:22:381588
1589 std::string response_data;
1590 rv = ReadTransaction(&trans, &response_data);
1591 EXPECT_THAT(rv, IsOk());
1592 EXPECT_EQ("hello world", response_data);
1593}
1594
Andrew Comminos517a92c2019-01-14 17:49:561595TEST_F(HttpNetworkTransactionTest, MeasuresTimeToFirst100ResponseForHttp) {
Andrew Comminos1f2ff1cc2018-12-14 05:22:381596 Check100ResponseTiming(false /* use_spdy */);
1597}
1598
Andrew Comminos517a92c2019-01-14 17:49:561599TEST_F(HttpNetworkTransactionTest, MeasuresTimeToFirst100ResponseForSpdy) {
Andrew Comminos1f2ff1cc2018-12-14 05:22:381600 Check100ResponseTiming(true /* use_spdy */);
1601}
1602
bncd16676a2016-07-20 16:23:011603TEST_F(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
zmo9528c9f42015-08-04 22:12:081604 HttpRequestInfo request;
1605 request.method = "POST";
1606 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101607 request.traffic_annotation =
1608 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
zmo9528c9f42015-08-04 22:12:081609
danakj1fd259a02016-04-16 03:17:091610 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161611 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zmo9528c9f42015-08-04 22:12:081612
1613 MockRead data_reads[] = {
1614 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1615 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381616 };
Ryan Sleevib8d7ea02018-05-07 20:01:011617 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
zmo9528c9f42015-08-04 22:12:081618 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381619
zmo9528c9f42015-08-04 22:12:081620 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381621
tfarina42834112016-09-22 13:38:201622 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011623 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381624
zmo9528c9f42015-08-04 22:12:081625 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011626 EXPECT_THAT(rv, IsOk());
[email protected]ee9410e72010-01-07 01:42:381627
zmo9528c9f42015-08-04 22:12:081628 std::string response_data;
bnc691fda62016-08-12 00:43:161629 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011630 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:081631 EXPECT_EQ("", response_data);
[email protected]ee9410e72010-01-07 01:42:381632}
1633
bncd16676a2016-07-20 16:23:011634TEST_F(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381635 HttpRequestInfo request;
1636 request.method = "POST";
1637 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101638 request.traffic_annotation =
1639 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ee9410e72010-01-07 01:42:381640
danakj1fd259a02016-04-16 03:17:091641 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161642 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271643
[email protected]ee9410e72010-01-07 01:42:381644 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061645 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381646 };
Ryan Sleevib8d7ea02018-05-07 20:01:011647 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071648 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381649
[email protected]49639fa2011-12-20 23:22:411650 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381651
tfarina42834112016-09-22 13:38:201652 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011653 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381654
1655 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011656 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]ee9410e72010-01-07 01:42:381657}
1658
[email protected]23e482282013-06-14 16:08:021659void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511660 const MockWrite* write_failure,
1661 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421662 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521663 request.method = "GET";
1664 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101665 request.traffic_annotation =
1666 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:521667
vishal.b62985ca92015-04-17 08:45:511668 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071669 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091670 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271671
[email protected]202965992011-12-07 23:04:511672 // Written data for successfully sending both requests.
1673 MockWrite data1_writes[] = {
1674 MockWrite("GET / HTTP/1.1\r\n"
1675 "Host: www.foo.com\r\n"
1676 "Connection: keep-alive\r\n\r\n"),
1677 MockWrite("GET / HTTP/1.1\r\n"
1678 "Host: www.foo.com\r\n"
1679 "Connection: keep-alive\r\n\r\n")
1680 };
1681
1682 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521683 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351684 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1685 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061686 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521687 };
[email protected]202965992011-12-07 23:04:511688
1689 if (write_failure) {
[email protected]a34f61ee2014-03-18 20:59:491690 ASSERT_FALSE(read_failure);
[email protected]202965992011-12-07 23:04:511691 data1_writes[1] = *write_failure;
1692 } else {
1693 ASSERT_TRUE(read_failure);
1694 data1_reads[2] = *read_failure;
1695 }
1696
Ryan Sleevib8d7ea02018-05-07 20:01:011697 StaticSocketDataProvider data1(data1_reads, data1_writes);
[email protected]bb88e1d32013-05-03 23:11:071698 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521699
1700 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351701 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1702 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061703 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521704 };
Ryan Sleevib8d7ea02018-05-07 20:01:011705 StaticSocketDataProvider data2(data2_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071706 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521707
thestig9d3bb0c2015-01-24 00:49:511708 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521709 "hello", "world"
1710 };
1711
mikecironef22f9812016-10-04 03:40:191712 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521713 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411714 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521715
bnc691fda62016-08-12 00:43:161716 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
initial.commit586acc5fe2008-07-26 22:42:521717
tfarina42834112016-09-22 13:38:201718 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011719 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521720
1721 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011722 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521723
[email protected]58e32bb2013-01-21 18:23:251724 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161725 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:251726 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1727 if (i == 0) {
1728 first_socket_log_id = load_timing_info.socket_log_id;
1729 } else {
1730 // The second request should be using a new socket.
1731 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1732 }
1733
bnc691fda62016-08-12 00:43:161734 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521735 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521736
wezca1070932016-05-26 20:30:521737 EXPECT_TRUE(response->headers);
tbansal2ecbbc72016-10-06 17:15:471738 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]3d2a59b2008-09-26 19:44:251739 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521740
1741 std::string response_data;
bnc691fda62016-08-12 00:43:161742 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011743 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251744 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521745 }
1746}
[email protected]3d2a59b2008-09-26 19:44:251747
[email protected]a34f61ee2014-03-18 20:59:491748void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1749 const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:101750 const MockRead* read_failure,
1751 bool use_spdy) {
[email protected]a34f61ee2014-03-18 20:59:491752 HttpRequestInfo request;
1753 request.method = "GET";
[email protected]09356c652014-03-25 15:36:101754 request.url = GURL("https://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101755 request.traffic_annotation =
1756 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]a34f61ee2014-03-18 20:59:491757
vishal.b62985ca92015-04-17 08:45:511758 TestNetLog net_log;
[email protected]a34f61ee2014-03-18 20:59:491759 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091760 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a34f61ee2014-03-18 20:59:491761
[email protected]09356c652014-03-25 15:36:101762 SSLSocketDataProvider ssl1(ASYNC, OK);
1763 SSLSocketDataProvider ssl2(ASYNC, OK);
1764 if (use_spdy) {
bnc3cf2a592016-08-11 14:48:361765 ssl1.next_proto = kProtoHTTP2;
1766 ssl2.next_proto = kProtoHTTP2;
[email protected]09356c652014-03-25 15:36:101767 }
1768 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1769 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]a34f61ee2014-03-18 20:59:491770
[email protected]09356c652014-03-25 15:36:101771 // SPDY versions of the request and response.
Ryan Hamilton0239aac2018-05-19 00:03:131772 spdy::SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
bnc38dcd392016-02-09 23:19:491773 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
Ryan Hamilton0239aac2018-05-19 00:03:131774 spdy::SpdySerializedFrame spdy_response(
bnc42331402016-07-25 13:36:151775 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:131776 spdy::SpdySerializedFrame spdy_data(
Bence Békyd74f4382018-02-20 18:26:191777 spdy_util_.ConstructSpdyDataFrame(1, "hello", true));
[email protected]a34f61ee2014-03-18 20:59:491778
[email protected]09356c652014-03-25 15:36:101779 // HTTP/1.1 versions of the request and response.
1780 const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1781 "Host: www.foo.com\r\n"
1782 "Connection: keep-alive\r\n\r\n";
1783 const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1784 const char kHttpData[] = "hello";
1785
1786 std::vector<MockRead> data1_reads;
1787 std::vector<MockWrite> data1_writes;
[email protected]a34f61ee2014-03-18 20:59:491788 if (write_failure) {
1789 ASSERT_FALSE(read_failure);
[email protected]09356c652014-03-25 15:36:101790 data1_writes.push_back(*write_failure);
1791 data1_reads.push_back(MockRead(ASYNC, OK));
[email protected]a34f61ee2014-03-18 20:59:491792 } else {
1793 ASSERT_TRUE(read_failure);
[email protected]09356c652014-03-25 15:36:101794 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411795 data1_writes.push_back(CreateMockWrite(spdy_request));
[email protected]09356c652014-03-25 15:36:101796 } else {
1797 data1_writes.push_back(MockWrite(kHttpRequest));
1798 }
1799 data1_reads.push_back(*read_failure);
[email protected]a34f61ee2014-03-18 20:59:491800 }
1801
Ryan Sleevib8d7ea02018-05-07 20:01:011802 StaticSocketDataProvider data1(data1_reads, data1_writes);
[email protected]a34f61ee2014-03-18 20:59:491803 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1804
[email protected]09356c652014-03-25 15:36:101805 std::vector<MockRead> data2_reads;
1806 std::vector<MockWrite> data2_writes;
1807
1808 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411809 data2_writes.push_back(CreateMockWrite(spdy_request, 0, ASYNC));
[email protected]09356c652014-03-25 15:36:101810
bncdf80d44fd2016-07-15 20:27:411811 data2_reads.push_back(CreateMockRead(spdy_response, 1, ASYNC));
1812 data2_reads.push_back(CreateMockRead(spdy_data, 2, ASYNC));
[email protected]09356c652014-03-25 15:36:101813 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1814 } else {
1815 data2_writes.push_back(
1816 MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1817
1818 data2_reads.push_back(
1819 MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1820 data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1821 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1822 }
Ryan Sleevib8d7ea02018-05-07 20:01:011823 SequencedSocketData data2(data2_reads, data2_writes);
[email protected]a34f61ee2014-03-18 20:59:491824 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1825
1826 // Preconnect a socket.
nharper8cdb0fb2016-04-22 21:34:591827 session->http_stream_factory()->PreconnectStreams(1, request);
[email protected]a34f61ee2014-03-18 20:59:491828 // Wait for the preconnect to complete.
1829 // TODO(davidben): Some way to wait for an idle socket count might be handy.
1830 base::RunLoop().RunUntilIdle();
[email protected]09356c652014-03-25 15:36:101831 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]a34f61ee2014-03-18 20:59:491832
1833 // Make the request.
1834 TestCompletionCallback callback;
1835
bnc691fda62016-08-12 00:43:161836 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a34f61ee2014-03-18 20:59:491837
tfarina42834112016-09-22 13:38:201838 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011839 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a34f61ee2014-03-18 20:59:491840
1841 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011842 EXPECT_THAT(rv, IsOk());
[email protected]a34f61ee2014-03-18 20:59:491843
1844 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161845 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]09356c652014-03-25 15:36:101846 TestLoadTimingNotReused(
1847 load_timing_info,
1848 CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]a34f61ee2014-03-18 20:59:491849
bnc691fda62016-08-12 00:43:161850 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521851 ASSERT_TRUE(response);
[email protected]a34f61ee2014-03-18 20:59:491852
wezca1070932016-05-26 20:30:521853 EXPECT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:021854 if (response->was_fetched_via_spdy) {
1855 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
1856 } else {
1857 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1858 }
[email protected]a34f61ee2014-03-18 20:59:491859
1860 std::string response_data;
bnc691fda62016-08-12 00:43:161861 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011862 EXPECT_THAT(rv, IsOk());
[email protected]09356c652014-03-25 15:36:101863 EXPECT_EQ(kHttpData, response_data);
[email protected]a34f61ee2014-03-18 20:59:491864}
1865
Biljith Jayan45a41722017-08-16 18:43:141866// Test that we do not retry indefinitely when a server sends an error like
1867// ERR_SPDY_PING_FAILED, ERR_SPDY_SERVER_REFUSED_STREAM,
1868// ERR_QUIC_HANDSHAKE_FAILED or ERR_QUIC_PROTOCOL_ERROR.
1869TEST_F(HttpNetworkTransactionTest, FiniteRetriesOnIOError) {
1870 HttpRequestInfo request;
1871 request.method = "GET";
1872 request.url = GURL("https://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101873 request.traffic_annotation =
1874 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Biljith Jayan45a41722017-08-16 18:43:141875
1876 // Check whether we give up after the third try.
1877
1878 // Construct an HTTP2 request and a "Go away" response.
Ryan Hamilton0239aac2018-05-19 00:03:131879 spdy::SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
Biljith Jayan45a41722017-08-16 18:43:141880 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
Ryan Hamilton0239aac2018-05-19 00:03:131881 spdy::SpdySerializedFrame spdy_response_go_away(
1882 spdy_util_.ConstructSpdyGoAway(0));
Ryan Sleevib8d7ea02018-05-07 20:01:011883 MockRead data_read1[] = {CreateMockRead(spdy_response_go_away)};
1884 MockWrite data_write[] = {CreateMockWrite(spdy_request, 0)};
Biljith Jayan45a41722017-08-16 18:43:141885
1886 // Three go away responses.
Ryan Sleevib8d7ea02018-05-07 20:01:011887 StaticSocketDataProvider data1(data_read1, data_write);
1888 StaticSocketDataProvider data2(data_read1, data_write);
1889 StaticSocketDataProvider data3(data_read1, data_write);
Biljith Jayan45a41722017-08-16 18:43:141890
1891 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1892 AddSSLSocketData();
1893 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1894 AddSSLSocketData();
1895 session_deps_.socket_factory->AddSocketDataProvider(&data3);
1896 AddSSLSocketData();
1897
1898 TestCompletionCallback callback;
1899 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1900 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1901
1902 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1903 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1904
1905 rv = callback.WaitForResult();
1906 EXPECT_THAT(rv, IsError(ERR_SPDY_SERVER_REFUSED_STREAM));
1907}
1908
1909TEST_F(HttpNetworkTransactionTest, RetryTwiceOnIOError) {
1910 HttpRequestInfo request;
1911 request.method = "GET";
1912 request.url = GURL("https://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101913 request.traffic_annotation =
1914 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Biljith Jayan45a41722017-08-16 18:43:141915
1916 // Check whether we try atleast thrice before giving up.
1917
1918 // Construct an HTTP2 request and a "Go away" response.
Ryan Hamilton0239aac2018-05-19 00:03:131919 spdy::SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
Biljith Jayan45a41722017-08-16 18:43:141920 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
Ryan Hamilton0239aac2018-05-19 00:03:131921 spdy::SpdySerializedFrame spdy_response_go_away(
1922 spdy_util_.ConstructSpdyGoAway(0));
Ryan Sleevib8d7ea02018-05-07 20:01:011923 MockRead data_read1[] = {CreateMockRead(spdy_response_go_away)};
1924 MockWrite data_write[] = {CreateMockWrite(spdy_request, 0)};
Biljith Jayan45a41722017-08-16 18:43:141925
1926 // Construct a non error HTTP2 response.
Ryan Hamilton0239aac2018-05-19 00:03:131927 spdy::SpdySerializedFrame spdy_response_no_error(
Biljith Jayan45a41722017-08-16 18:43:141928 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:131929 spdy::SpdySerializedFrame spdy_data(
1930 spdy_util_.ConstructSpdyDataFrame(1, true));
Biljith Jayan45a41722017-08-16 18:43:141931 MockRead data_read2[] = {CreateMockRead(spdy_response_no_error, 1),
1932 CreateMockRead(spdy_data, 2)};
1933
1934 // Two error responses.
Ryan Sleevib8d7ea02018-05-07 20:01:011935 StaticSocketDataProvider data1(data_read1, data_write);
1936 StaticSocketDataProvider data2(data_read1, data_write);
Biljith Jayan45a41722017-08-16 18:43:141937 // Followed by a success response.
Ryan Sleevib8d7ea02018-05-07 20:01:011938 SequencedSocketData data3(data_read2, data_write);
Biljith Jayan45a41722017-08-16 18:43:141939
1940 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1941 AddSSLSocketData();
1942 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1943 AddSSLSocketData();
1944 session_deps_.socket_factory->AddSocketDataProvider(&data3);
1945 AddSSLSocketData();
1946
1947 TestCompletionCallback callback;
1948 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1949 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1950
1951 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1952 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1953
1954 rv = callback.WaitForResult();
1955 EXPECT_THAT(rv, IsOk());
1956}
1957
bncd16676a2016-07-20 16:23:011958TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061959 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]202965992011-12-07 23:04:511960 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1961}
1962
bncd16676a2016-07-20 16:23:011963TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061964 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]202965992011-12-07 23:04:511965 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251966}
1967
bncd16676a2016-07-20 16:23:011968TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061969 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]202965992011-12-07 23:04:511970 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251971}
1972
[email protected]d58ceea82014-06-04 10:55:541973// Make sure that on a 408 response (Request Timeout), the request is retried,
1974// if the socket was a reused keep alive socket.
bncd16676a2016-07-20 16:23:011975TEST_F(HttpNetworkTransactionTest, KeepAlive408) {
[email protected]d58ceea82014-06-04 10:55:541976 MockRead read_failure(SYNCHRONOUS,
1977 "HTTP/1.1 408 Request Timeout\r\n"
1978 "Connection: Keep-Alive\r\n"
1979 "Content-Length: 6\r\n\r\n"
1980 "Pickle");
1981 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1982}
1983
bncd16676a2016-07-20 16:23:011984TEST_F(HttpNetworkTransactionTest, PreconnectErrorNotConnectedOnWrite) {
[email protected]a34f61ee2014-03-18 20:59:491985 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]09356c652014-03-25 15:36:101986 PreconnectErrorResendRequestTest(&write_failure, NULL, false);
[email protected]a34f61ee2014-03-18 20:59:491987}
1988
bncd16676a2016-07-20 16:23:011989TEST_F(HttpNetworkTransactionTest, PreconnectErrorReset) {
[email protected]a34f61ee2014-03-18 20:59:491990 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]09356c652014-03-25 15:36:101991 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
[email protected]a34f61ee2014-03-18 20:59:491992}
1993
bncd16676a2016-07-20 16:23:011994TEST_F(HttpNetworkTransactionTest, PreconnectErrorEOF) {
[email protected]a34f61ee2014-03-18 20:59:491995 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]09356c652014-03-25 15:36:101996 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1997}
1998
bncd16676a2016-07-20 16:23:011999TEST_F(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:102000 MockRead read_failure(ASYNC, OK); // EOF
2001 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
2002}
2003
[email protected]d58ceea82014-06-04 10:55:542004// Make sure that on a 408 response (Request Timeout), the request is retried,
2005// if the socket was a preconnected (UNUSED_IDLE) socket.
bncd16676a2016-07-20 16:23:012006TEST_F(HttpNetworkTransactionTest, RetryOnIdle408) {
[email protected]d58ceea82014-06-04 10:55:542007 MockRead read_failure(SYNCHRONOUS,
2008 "HTTP/1.1 408 Request Timeout\r\n"
2009 "Connection: Keep-Alive\r\n"
2010 "Content-Length: 6\r\n\r\n"
2011 "Pickle");
2012 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
2013 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
2014}
2015
bncd16676a2016-07-20 16:23:012016TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorNotConnectedOnWrite) {
[email protected]09356c652014-03-25 15:36:102017 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
2018 PreconnectErrorResendRequestTest(&write_failure, NULL, true);
2019}
2020
bncd16676a2016-07-20 16:23:012021TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
[email protected]09356c652014-03-25 15:36:102022 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
2023 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
2024}
2025
bncd16676a2016-07-20 16:23:012026TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
[email protected]09356c652014-03-25 15:36:102027 MockRead read_failure(SYNCHRONOUS, OK); // EOF
2028 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
2029}
2030
bncd16676a2016-07-20 16:23:012031TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:102032 MockRead read_failure(ASYNC, OK); // EOF
2033 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
[email protected]a34f61ee2014-03-18 20:59:492034}
2035
bncd16676a2016-07-20 16:23:012036TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:422037 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:252038 request.method = "GET";
bncce36dca22015-04-21 22:11:232039 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102040 request.traffic_annotation =
2041 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3d2a59b2008-09-26 19:44:252042
danakj1fd259a02016-04-16 03:17:092043 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162044 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272045
[email protected]3d2a59b2008-09-26 19:44:252046 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:062047 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:352048 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
2049 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:062050 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:252051 };
Ryan Sleevib8d7ea02018-05-07 20:01:012052 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:072053 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:252054
[email protected]49639fa2011-12-20 23:22:412055 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:252056
tfarina42834112016-09-22 13:38:202057 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012058 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3d2a59b2008-09-26 19:44:252059
2060 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:012061 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:592062
2063 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:162064 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592065 EXPECT_LT(0u, endpoint.address().size());
[email protected]3d2a59b2008-09-26 19:44:252066}
2067
2068// What do various browsers do when the server closes a non-keepalive
2069// connection without sending any response header or body?
2070//
2071// IE7: error page
2072// Safari 3.1.2 (Windows): error page
2073// Firefox 3.0.1: blank page
2074// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:422075// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
2076// Us: error page (EMPTY_RESPONSE)
bncd16676a2016-07-20 16:23:012077TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:252078 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:062079 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:352080 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
2081 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:062082 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:252083 };
Ryan Sleevib8d7ea02018-05-07 20:01:012084 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:012085 EXPECT_THAT(out.rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]3d2a59b2008-09-26 19:44:252086}
[email protected]1826a402014-01-08 15:40:482087
[email protected]7a5378b2012-11-04 03:25:172088// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
2089// tests. There was a bug causing HttpNetworkTransaction to hang in the
2090// destructor in such situations.
2091// See http://crbug.com/154712 and http://crbug.com/156609.
bncd16676a2016-07-20 16:23:012092TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:172093 HttpRequestInfo request;
2094 request.method = "GET";
bncce36dca22015-04-21 22:11:232095 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102096 request.traffic_annotation =
2097 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7a5378b2012-11-04 03:25:172098
danakj1fd259a02016-04-16 03:17:092099 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:582100 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:192101 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:172102
2103 MockRead data_reads[] = {
2104 MockRead("HTTP/1.0 200 OK\r\n"),
2105 MockRead("Connection: keep-alive\r\n"),
2106 MockRead("Content-Length: 100\r\n\r\n"),
2107 MockRead("hello"),
2108 MockRead(SYNCHRONOUS, 0),
2109 };
Ryan Sleevib8d7ea02018-05-07 20:01:012110 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:072111 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:172112
2113 TestCompletionCallback callback;
2114
tfarina42834112016-09-22 13:38:202115 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012116 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:172117
2118 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:012119 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:172120
Victor Costan9c7302b2018-08-27 16:39:442121 scoped_refptr<IOBufferWithSize> io_buf =
2122 base::MakeRefCounted<IOBufferWithSize>(100);
[email protected]90499482013-06-01 00:39:502123 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:172124 if (rv == ERR_IO_PENDING)
2125 rv = callback.WaitForResult();
2126 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:502127 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
robpercival214763f2016-07-01 23:27:012128 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:172129
2130 trans.reset();
fdoray92e35a72016-06-10 15:54:552131 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:172132 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2133}
2134
bncd16676a2016-07-20 16:23:012135TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:172136 HttpRequestInfo request;
2137 request.method = "GET";
bncce36dca22015-04-21 22:11:232138 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102139 request.traffic_annotation =
2140 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7a5378b2012-11-04 03:25:172141
danakj1fd259a02016-04-16 03:17:092142 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:582143 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:192144 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:172145
2146 MockRead data_reads[] = {
2147 MockRead("HTTP/1.0 200 OK\r\n"),
2148 MockRead("Connection: keep-alive\r\n"),
2149 MockRead("Content-Length: 100\r\n\r\n"),
2150 MockRead(SYNCHRONOUS, 0),
2151 };
Ryan Sleevib8d7ea02018-05-07 20:01:012152 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:072153 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:172154
2155 TestCompletionCallback callback;
2156
tfarina42834112016-09-22 13:38:202157 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012158 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:172159
2160 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:012161 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:172162
Victor Costan9c7302b2018-08-27 16:39:442163 scoped_refptr<IOBufferWithSize> io_buf(
2164 base::MakeRefCounted<IOBufferWithSize>(100));
[email protected]90499482013-06-01 00:39:502165 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:172166 if (rv == ERR_IO_PENDING)
2167 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:012168 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:172169
2170 trans.reset();
fdoray92e35a72016-06-10 15:54:552171 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:172172 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2173}
2174
[email protected]0b0bf032010-09-21 18:08:502175// Test that we correctly reuse a keep-alive connection after not explicitly
2176// reading the body.
bncd16676a2016-07-20 16:23:012177TEST_F(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:132178 HttpRequestInfo request;
2179 request.method = "GET";
2180 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:102181 request.traffic_annotation =
2182 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]fc31d6a42010-06-24 18:05:132183
vishal.b62985ca92015-04-17 08:45:512184 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:072185 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:092186 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272187
mmenkecc2298e2015-12-07 18:20:182188 const char* request_data =
2189 "GET / HTTP/1.1\r\n"
2190 "Host: www.foo.com\r\n"
2191 "Connection: keep-alive\r\n\r\n";
2192 MockWrite data_writes[] = {
2193 MockWrite(ASYNC, 0, request_data), MockWrite(ASYNC, 2, request_data),
2194 MockWrite(ASYNC, 4, request_data), MockWrite(ASYNC, 6, request_data),
2195 MockWrite(ASYNC, 8, request_data), MockWrite(ASYNC, 10, request_data),
2196 MockWrite(ASYNC, 12, request_data), MockWrite(ASYNC, 14, request_data),
2197 MockWrite(ASYNC, 17, request_data), MockWrite(ASYNC, 20, request_data),
2198 };
2199
[email protected]0b0bf032010-09-21 18:08:502200 // Note that because all these reads happen in the same
2201 // StaticSocketDataProvider, it shows that the same socket is being reused for
2202 // all transactions.
mmenkecc2298e2015-12-07 18:20:182203 MockRead data_reads[] = {
2204 MockRead(ASYNC, 1, "HTTP/1.1 204 No Content\r\n\r\n"),
2205 MockRead(ASYNC, 3, "HTTP/1.1 205 Reset Content\r\n\r\n"),
2206 MockRead(ASYNC, 5, "HTTP/1.1 304 Not Modified\r\n\r\n"),
2207 MockRead(ASYNC, 7,
2208 "HTTP/1.1 302 Found\r\n"
2209 "Content-Length: 0\r\n\r\n"),
2210 MockRead(ASYNC, 9,
2211 "HTTP/1.1 302 Found\r\n"
2212 "Content-Length: 5\r\n\r\n"
2213 "hello"),
2214 MockRead(ASYNC, 11,
2215 "HTTP/1.1 301 Moved Permanently\r\n"
2216 "Content-Length: 0\r\n\r\n"),
2217 MockRead(ASYNC, 13,
2218 "HTTP/1.1 301 Moved Permanently\r\n"
2219 "Content-Length: 5\r\n\r\n"
2220 "hello"),
[email protected]fc31d6a42010-06-24 18:05:132221
mmenkecc2298e2015-12-07 18:20:182222 // In the next two rounds, IsConnectedAndIdle returns false, due to
2223 // the set_busy_before_sync_reads(true) call, while the
2224 // HttpNetworkTransaction is being shut down, but the socket is still
2225 // reuseable. See http://crbug.com/544255.
2226 MockRead(ASYNC, 15,
2227 "HTTP/1.1 200 Hunky-Dory\r\n"
2228 "Content-Length: 5\r\n\r\n"),
2229 MockRead(SYNCHRONOUS, 16, "hello"),
[email protected]fc31d6a42010-06-24 18:05:132230
mmenkecc2298e2015-12-07 18:20:182231 MockRead(ASYNC, 18,
2232 "HTTP/1.1 200 Hunky-Dory\r\n"
2233 "Content-Length: 5\r\n\r\n"
2234 "he"),
2235 MockRead(SYNCHRONOUS, 19, "llo"),
2236
2237 // The body of the final request is actually read.
2238 MockRead(ASYNC, 21, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
2239 MockRead(ASYNC, 22, "hello"),
2240 };
Ryan Sleevib8d7ea02018-05-07 20:01:012241 SequencedSocketData data(data_reads, data_writes);
mmenkecc2298e2015-12-07 18:20:182242 data.set_busy_before_sync_reads(true);
2243 session_deps_.socket_factory->AddSocketDataProvider(&data);
2244
Avi Drissman4365a4782018-12-28 19:26:242245 const int kNumUnreadBodies = base::size(data_writes) - 1;
[email protected]0b0bf032010-09-21 18:08:502246 std::string response_lines[kNumUnreadBodies];
2247
mikecironef22f9812016-10-04 03:40:192248 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
mmenkecc2298e2015-12-07 18:20:182249 for (size_t i = 0; i < kNumUnreadBodies; ++i) {
[email protected]49639fa2011-12-20 23:22:412250 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:132251
Jeremy Roman0579ed62017-08-29 15:56:192252 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
bnc87dcefc2017-05-25 12:47:582253 session.get());
[email protected]fc31d6a42010-06-24 18:05:132254
tfarina42834112016-09-22 13:38:202255 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012256 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]fc31d6a42010-06-24 18:05:132257
[email protected]58e32bb2013-01-21 18:23:252258 LoadTimingInfo load_timing_info;
2259 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2260 if (i == 0) {
2261 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
2262 first_socket_log_id = load_timing_info.socket_log_id;
2263 } else {
2264 TestLoadTimingReused(load_timing_info);
2265 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
2266 }
2267
[email protected]fc31d6a42010-06-24 18:05:132268 const HttpResponseInfo* response = trans->GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182269 ASSERT_TRUE(response);
[email protected]fc31d6a42010-06-24 18:05:132270
mmenkecc2298e2015-12-07 18:20:182271 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502272 response_lines[i] = response->headers->GetStatusLine();
2273
mmenkecc2298e2015-12-07 18:20:182274 // Delete the transaction without reading the response bodies. Then spin
2275 // the message loop, so the response bodies are drained.
2276 trans.reset();
2277 base::RunLoop().RunUntilIdle();
[email protected]fc31d6a42010-06-24 18:05:132278 }
[email protected]0b0bf032010-09-21 18:08:502279
2280 const char* const kStatusLines[] = {
mmenkecc2298e2015-12-07 18:20:182281 "HTTP/1.1 204 No Content",
2282 "HTTP/1.1 205 Reset Content",
2283 "HTTP/1.1 304 Not Modified",
2284 "HTTP/1.1 302 Found",
2285 "HTTP/1.1 302 Found",
2286 "HTTP/1.1 301 Moved Permanently",
2287 "HTTP/1.1 301 Moved Permanently",
2288 "HTTP/1.1 200 Hunky-Dory",
2289 "HTTP/1.1 200 Hunky-Dory",
[email protected]0b0bf032010-09-21 18:08:502290 };
2291
Avi Drissman4365a4782018-12-28 19:26:242292 static_assert(kNumUnreadBodies == base::size(kStatusLines),
mostynb91e0da982015-01-20 19:17:272293 "forgot to update kStatusLines");
[email protected]0b0bf032010-09-21 18:08:502294
2295 for (int i = 0; i < kNumUnreadBodies; ++i)
2296 EXPECT_EQ(kStatusLines[i], response_lines[i]);
2297
[email protected]49639fa2011-12-20 23:22:412298 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:162299 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202300 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012301 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:162302 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182303 ASSERT_TRUE(response);
2304 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502305 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2306 std::string response_data;
bnc691fda62016-08-12 00:43:162307 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:012308 EXPECT_THAT(rv, IsOk());
[email protected]0b0bf032010-09-21 18:08:502309 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:132310}
2311
mmenke5f94fda2016-06-02 20:54:132312// Sockets that receive extra data after a response is complete should not be
2313// reused.
bncd16676a2016-07-20 16:23:012314TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData1) {
mmenke5f94fda2016-06-02 20:54:132315 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2316 MockWrite data_writes1[] = {
2317 MockWrite("HEAD / HTTP/1.1\r\n"
2318 "Host: www.borked.com\r\n"
2319 "Connection: keep-alive\r\n\r\n"),
2320 };
2321
2322 MockRead data_reads1[] = {
2323 MockRead("HTTP/1.1 200 OK\r\n"
2324 "Connection: keep-alive\r\n"
2325 "Content-Length: 22\r\n\r\n"
2326 "This server is borked."),
2327 };
2328
2329 MockWrite data_writes2[] = {
2330 MockWrite("GET /foo HTTP/1.1\r\n"
2331 "Host: www.borked.com\r\n"
2332 "Connection: keep-alive\r\n\r\n"),
2333 };
2334
2335 MockRead data_reads2[] = {
2336 MockRead("HTTP/1.1 200 OK\r\n"
2337 "Content-Length: 3\r\n\r\n"
2338 "foo"),
2339 };
Ryan Sleevib8d7ea02018-05-07 20:01:012340 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke5f94fda2016-06-02 20:54:132341 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:012342 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke5f94fda2016-06-02 20:54:132343 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2344
2345 TestCompletionCallback callback;
2346 HttpRequestInfo request1;
2347 request1.method = "HEAD";
2348 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e2018-02-07 07:41:102349 request1.traffic_annotation =
2350 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132351
bnc87dcefc2017-05-25 12:47:582352 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192353 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202354 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012355 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132356
2357 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2358 ASSERT_TRUE(response1);
2359 ASSERT_TRUE(response1->headers);
2360 EXPECT_EQ(200, response1->headers->response_code());
2361 EXPECT_TRUE(response1->headers->IsKeepAlive());
2362
2363 std::string response_data1;
robpercival214763f2016-07-01 23:27:012364 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132365 EXPECT_EQ("", response_data1);
2366 // Deleting the transaction attempts to release the socket back into the
2367 // socket pool.
2368 trans1.reset();
2369
2370 HttpRequestInfo request2;
2371 request2.method = "GET";
2372 request2.url = GURL("http://www.borked.com/foo");
Ramin Halavatib5e433e2018-02-07 07:41:102373 request2.traffic_annotation =
2374 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132375
bnc87dcefc2017-05-25 12:47:582376 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192377 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202378 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012379 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132380
2381 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2382 ASSERT_TRUE(response2);
2383 ASSERT_TRUE(response2->headers);
2384 EXPECT_EQ(200, response2->headers->response_code());
2385
2386 std::string response_data2;
robpercival214763f2016-07-01 23:27:012387 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132388 EXPECT_EQ("foo", response_data2);
2389}
2390
bncd16676a2016-07-20 16:23:012391TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData2) {
mmenke5f94fda2016-06-02 20:54:132392 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2393 MockWrite data_writes1[] = {
2394 MockWrite("GET / HTTP/1.1\r\n"
2395 "Host: www.borked.com\r\n"
2396 "Connection: keep-alive\r\n\r\n"),
2397 };
2398
2399 MockRead data_reads1[] = {
2400 MockRead("HTTP/1.1 200 OK\r\n"
2401 "Connection: keep-alive\r\n"
2402 "Content-Length: 22\r\n\r\n"
2403 "This server is borked."
2404 "Bonus data!"),
2405 };
2406
2407 MockWrite data_writes2[] = {
2408 MockWrite("GET /foo HTTP/1.1\r\n"
2409 "Host: www.borked.com\r\n"
2410 "Connection: keep-alive\r\n\r\n"),
2411 };
2412
2413 MockRead data_reads2[] = {
2414 MockRead("HTTP/1.1 200 OK\r\n"
2415 "Content-Length: 3\r\n\r\n"
2416 "foo"),
2417 };
Ryan Sleevib8d7ea02018-05-07 20:01:012418 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke5f94fda2016-06-02 20:54:132419 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:012420 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke5f94fda2016-06-02 20:54:132421 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2422
2423 TestCompletionCallback callback;
2424 HttpRequestInfo request1;
2425 request1.method = "GET";
2426 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e2018-02-07 07:41:102427 request1.traffic_annotation =
2428 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132429
bnc87dcefc2017-05-25 12:47:582430 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192431 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202432 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012433 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132434
2435 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2436 ASSERT_TRUE(response1);
2437 ASSERT_TRUE(response1->headers);
2438 EXPECT_EQ(200, response1->headers->response_code());
2439 EXPECT_TRUE(response1->headers->IsKeepAlive());
2440
2441 std::string response_data1;
robpercival214763f2016-07-01 23:27:012442 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132443 EXPECT_EQ("This server is borked.", response_data1);
2444 // Deleting the transaction attempts to release the socket back into the
2445 // socket pool.
2446 trans1.reset();
2447
2448 HttpRequestInfo request2;
2449 request2.method = "GET";
2450 request2.url = GURL("http://www.borked.com/foo");
Ramin Halavatib5e433e2018-02-07 07:41:102451 request2.traffic_annotation =
2452 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132453
bnc87dcefc2017-05-25 12:47:582454 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192455 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202456 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012457 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132458
2459 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2460 ASSERT_TRUE(response2);
2461 ASSERT_TRUE(response2->headers);
2462 EXPECT_EQ(200, response2->headers->response_code());
2463
2464 std::string response_data2;
robpercival214763f2016-07-01 23:27:012465 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132466 EXPECT_EQ("foo", response_data2);
2467}
2468
bncd16676a2016-07-20 16:23:012469TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData3) {
mmenke5f94fda2016-06-02 20:54:132470 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2471 MockWrite data_writes1[] = {
2472 MockWrite("GET / HTTP/1.1\r\n"
2473 "Host: www.borked.com\r\n"
2474 "Connection: keep-alive\r\n\r\n"),
2475 };
2476
2477 MockRead data_reads1[] = {
2478 MockRead("HTTP/1.1 200 OK\r\n"
2479 "Connection: keep-alive\r\n"
2480 "Transfer-Encoding: chunked\r\n\r\n"),
2481 MockRead("16\r\nThis server is borked.\r\n"),
2482 MockRead("0\r\n\r\nBonus data!"),
2483 };
2484
2485 MockWrite data_writes2[] = {
2486 MockWrite("GET /foo HTTP/1.1\r\n"
2487 "Host: www.borked.com\r\n"
2488 "Connection: keep-alive\r\n\r\n"),
2489 };
2490
2491 MockRead data_reads2[] = {
2492 MockRead("HTTP/1.1 200 OK\r\n"
2493 "Content-Length: 3\r\n\r\n"
2494 "foo"),
2495 };
Ryan Sleevib8d7ea02018-05-07 20:01:012496 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke5f94fda2016-06-02 20:54:132497 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:012498 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke5f94fda2016-06-02 20:54:132499 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2500
2501 TestCompletionCallback callback;
2502 HttpRequestInfo request1;
2503 request1.method = "GET";
2504 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e2018-02-07 07:41:102505 request1.traffic_annotation =
2506 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132507
bnc87dcefc2017-05-25 12:47:582508 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192509 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202510 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012511 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132512
2513 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2514 ASSERT_TRUE(response1);
2515 ASSERT_TRUE(response1->headers);
2516 EXPECT_EQ(200, response1->headers->response_code());
2517 EXPECT_TRUE(response1->headers->IsKeepAlive());
2518
2519 std::string response_data1;
robpercival214763f2016-07-01 23:27:012520 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132521 EXPECT_EQ("This server is borked.", response_data1);
2522 // Deleting the transaction attempts to release the socket back into the
2523 // socket pool.
2524 trans1.reset();
2525
2526 HttpRequestInfo request2;
2527 request2.method = "GET";
2528 request2.url = GURL("http://www.borked.com/foo");
Ramin Halavatib5e433e2018-02-07 07:41:102529 request2.traffic_annotation =
2530 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132531
bnc87dcefc2017-05-25 12:47:582532 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192533 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202534 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012535 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132536
2537 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2538 ASSERT_TRUE(response2);
2539 ASSERT_TRUE(response2->headers);
2540 EXPECT_EQ(200, response2->headers->response_code());
2541
2542 std::string response_data2;
robpercival214763f2016-07-01 23:27:012543 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132544 EXPECT_EQ("foo", response_data2);
2545}
2546
2547// This is a little different from the others - it tests the case that the
2548// HttpStreamParser doesn't know if there's extra data on a socket or not when
2549// the HttpNetworkTransaction is torn down, because the response body hasn't
2550// been read from yet, but the request goes through the HttpResponseBodyDrainer.
bncd16676a2016-07-20 16:23:012551TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData4) {
mmenke5f94fda2016-06-02 20:54:132552 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2553 MockWrite data_writes1[] = {
2554 MockWrite("GET / HTTP/1.1\r\n"
2555 "Host: www.borked.com\r\n"
2556 "Connection: keep-alive\r\n\r\n"),
2557 };
2558
2559 MockRead data_reads1[] = {
2560 MockRead("HTTP/1.1 200 OK\r\n"
2561 "Connection: keep-alive\r\n"
2562 "Transfer-Encoding: chunked\r\n\r\n"),
2563 MockRead("16\r\nThis server is borked.\r\n"),
2564 MockRead("0\r\n\r\nBonus data!"),
2565 };
Ryan Sleevib8d7ea02018-05-07 20:01:012566 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke5f94fda2016-06-02 20:54:132567 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2568
2569 TestCompletionCallback callback;
2570 HttpRequestInfo request1;
2571 request1.method = "GET";
2572 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e2018-02-07 07:41:102573 request1.traffic_annotation =
2574 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132575
bnc87dcefc2017-05-25 12:47:582576 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:192577 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
bnc87dcefc2017-05-25 12:47:582578 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012579 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132580
bnc87dcefc2017-05-25 12:47:582581 const HttpResponseInfo* response1 = trans->GetResponseInfo();
mmenke5f94fda2016-06-02 20:54:132582 ASSERT_TRUE(response1);
2583 ASSERT_TRUE(response1->headers);
2584 EXPECT_EQ(200, response1->headers->response_code());
2585 EXPECT_TRUE(response1->headers->IsKeepAlive());
2586
2587 // Deleting the transaction creates an HttpResponseBodyDrainer to read the
2588 // response body.
bnc87dcefc2017-05-25 12:47:582589 trans.reset();
mmenke5f94fda2016-06-02 20:54:132590
2591 // Let the HttpResponseBodyDrainer drain the socket. It should determine the
2592 // socket can't be reused, rather than returning it to the socket pool.
2593 base::RunLoop().RunUntilIdle();
2594
2595 // There should be no idle sockets in the pool.
2596 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2597}
2598
[email protected]038e9a32008-10-08 22:40:162599// Test the request-challenge-retry sequence for basic auth.
2600// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012601TEST_F(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:422602 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:162603 request.method = "GET";
bncce36dca22015-04-21 22:11:232604 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102605 request.traffic_annotation =
2606 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]038e9a32008-10-08 22:40:162607
vishal.b62985ca92015-04-17 08:45:512608 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072609 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092610 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162611 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272612
[email protected]f9ee6b52008-11-08 06:46:232613 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232614 MockWrite(
2615 "GET / HTTP/1.1\r\n"
2616 "Host: www.example.org\r\n"
2617 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:232618 };
2619
[email protected]038e9a32008-10-08 22:40:162620 MockRead data_reads1[] = {
2621 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2622 // Give a couple authenticate options (only the middle one is actually
2623 // supported).
[email protected]22927ad2009-09-21 19:56:192624 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:162625 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2626 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2627 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2628 // Large content-length -- won't matter, as connection will be reset.
2629 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062630 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:162631 };
2632
2633 // After calling trans->RestartWithAuth(), this is the request we should
2634 // be issuing -- the final header line contains the credentials.
2635 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232636 MockWrite(
2637 "GET / HTTP/1.1\r\n"
2638 "Host: www.example.org\r\n"
2639 "Connection: keep-alive\r\n"
2640 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:162641 };
2642
2643 // Lastly, the server responds with the actual content.
2644 MockRead data_reads2[] = {
2645 MockRead("HTTP/1.0 200 OK\r\n"),
2646 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2647 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062648 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:162649 };
2650
Ryan Sleevib8d7ea02018-05-07 20:01:012651 StaticSocketDataProvider data1(data_reads1, data_writes1);
2652 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:072653 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2654 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:162655
[email protected]49639fa2011-12-20 23:22:412656 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:162657
tfarina42834112016-09-22 13:38:202658 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012659 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162660
2661 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012662 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162663
[email protected]58e32bb2013-01-21 18:23:252664 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162665 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
[email protected]58e32bb2013-01-21 18:23:252666 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2667
Ryan Sleevib8d7ea02018-05-07 20:01:012668 int64_t writes_size1 = CountWriteBytes(data_writes1);
bnc691fda62016-08-12 00:43:162669 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012670 int64_t reads_size1 = CountReadBytes(data_reads1);
bnc691fda62016-08-12 00:43:162671 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192672
bnc691fda62016-08-12 00:43:162673 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522674 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042675 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:162676
[email protected]49639fa2011-12-20 23:22:412677 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:162678
bnc691fda62016-08-12 00:43:162679 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012680 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162681
2682 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012683 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162684
[email protected]58e32bb2013-01-21 18:23:252685 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162686 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
[email protected]58e32bb2013-01-21 18:23:252687 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2688 // The load timing after restart should have a new socket ID, and times after
2689 // those of the first load timing.
2690 EXPECT_LE(load_timing_info1.receive_headers_end,
2691 load_timing_info2.connect_timing.connect_start);
2692 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2693
Ryan Sleevib8d7ea02018-05-07 20:01:012694 int64_t writes_size2 = CountWriteBytes(data_writes2);
bnc691fda62016-08-12 00:43:162695 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012696 int64_t reads_size2 = CountReadBytes(data_reads2);
bnc691fda62016-08-12 00:43:162697 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192698
bnc691fda62016-08-12 00:43:162699 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522700 ASSERT_TRUE(response);
2701 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:162702 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:162703}
2704
ttuttled9dbc652015-09-29 20:00:592705// Test the request-challenge-retry sequence for basic auth.
2706// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012707TEST_F(HttpNetworkTransactionTest, BasicAuthWithAddressChange) {
ttuttled9dbc652015-09-29 20:00:592708 HttpRequestInfo request;
2709 request.method = "GET";
2710 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102711 request.traffic_annotation =
2712 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttled9dbc652015-09-29 20:00:592713
2714 TestNetLog log;
2715 MockHostResolver* resolver = new MockHostResolver();
2716 session_deps_.net_log = &log;
2717 session_deps_.host_resolver.reset(resolver);
danakj1fd259a02016-04-16 03:17:092718 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
bnc691fda62016-08-12 00:43:162719 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttled9dbc652015-09-29 20:00:592720
2721 resolver->rules()->ClearRules();
2722 resolver->rules()->AddRule("www.example.org", "127.0.0.1");
2723
2724 MockWrite data_writes1[] = {
2725 MockWrite("GET / HTTP/1.1\r\n"
2726 "Host: www.example.org\r\n"
2727 "Connection: keep-alive\r\n\r\n"),
2728 };
2729
2730 MockRead data_reads1[] = {
2731 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2732 // Give a couple authenticate options (only the middle one is actually
2733 // supported).
2734 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
2735 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2736 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2737 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2738 // Large content-length -- won't matter, as connection will be reset.
2739 MockRead("Content-Length: 10000\r\n\r\n"),
2740 MockRead(SYNCHRONOUS, ERR_FAILED),
2741 };
2742
2743 // After calling trans->RestartWithAuth(), this is the request we should
2744 // be issuing -- the final header line contains the credentials.
2745 MockWrite data_writes2[] = {
2746 MockWrite("GET / HTTP/1.1\r\n"
2747 "Host: www.example.org\r\n"
2748 "Connection: keep-alive\r\n"
2749 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2750 };
2751
2752 // Lastly, the server responds with the actual content.
2753 MockRead data_reads2[] = {
2754 MockRead("HTTP/1.0 200 OK\r\n"),
2755 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2756 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, OK),
2757 };
2758
Ryan Sleevib8d7ea02018-05-07 20:01:012759 StaticSocketDataProvider data1(data_reads1, data_writes1);
2760 StaticSocketDataProvider data2(data_reads2, data_writes2);
ttuttled9dbc652015-09-29 20:00:592761 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2762 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2763
2764 TestCompletionCallback callback1;
2765
bnc691fda62016-08-12 00:43:162766 EXPECT_EQ(OK, callback1.GetResult(trans.Start(&request, callback1.callback(),
tfarina42834112016-09-22 13:38:202767 NetLogWithSource())));
ttuttled9dbc652015-09-29 20:00:592768
2769 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162770 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
ttuttled9dbc652015-09-29 20:00:592771 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2772
Ryan Sleevib8d7ea02018-05-07 20:01:012773 int64_t writes_size1 = CountWriteBytes(data_writes1);
bnc691fda62016-08-12 00:43:162774 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012775 int64_t reads_size1 = CountReadBytes(data_reads1);
bnc691fda62016-08-12 00:43:162776 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592777
bnc691fda62016-08-12 00:43:162778 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592779 ASSERT_TRUE(response);
2780 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2781
2782 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:162783 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592784 ASSERT_FALSE(endpoint.address().empty());
2785 EXPECT_EQ("127.0.0.1:80", endpoint.ToString());
2786
2787 resolver->rules()->ClearRules();
2788 resolver->rules()->AddRule("www.example.org", "127.0.0.2");
2789
2790 TestCompletionCallback callback2;
2791
bnc691fda62016-08-12 00:43:162792 EXPECT_EQ(OK, callback2.GetResult(trans.RestartWithAuth(
ttuttled9dbc652015-09-29 20:00:592793 AuthCredentials(kFoo, kBar), callback2.callback())));
2794
2795 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162796 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
ttuttled9dbc652015-09-29 20:00:592797 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2798 // The load timing after restart should have a new socket ID, and times after
2799 // those of the first load timing.
2800 EXPECT_LE(load_timing_info1.receive_headers_end,
2801 load_timing_info2.connect_timing.connect_start);
2802 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2803
Ryan Sleevib8d7ea02018-05-07 20:01:012804 int64_t writes_size2 = CountWriteBytes(data_writes2);
bnc691fda62016-08-12 00:43:162805 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012806 int64_t reads_size2 = CountReadBytes(data_reads2);
bnc691fda62016-08-12 00:43:162807 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592808
bnc691fda62016-08-12 00:43:162809 response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592810 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:522811 EXPECT_FALSE(response->auth_challenge);
ttuttled9dbc652015-09-29 20:00:592812 EXPECT_EQ(100, response->headers->GetContentLength());
2813
bnc691fda62016-08-12 00:43:162814 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592815 ASSERT_FALSE(endpoint.address().empty());
2816 EXPECT_EQ("127.0.0.2:80", endpoint.ToString());
2817}
2818
David Benjamin83ddfb32018-03-30 01:07:522819// Test that, if the server requests auth indefinitely, HttpNetworkTransaction
2820// will eventually give up.
2821TEST_F(HttpNetworkTransactionTest, BasicAuthForever) {
2822 HttpRequestInfo request;
2823 request.method = "GET";
2824 request.url = GURL("http://www.example.org/");
2825 request.traffic_annotation =
2826 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2827
2828 TestNetLog log;
2829 session_deps_.net_log = &log;
2830 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2831 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
2832
2833 MockWrite data_writes[] = {
2834 MockWrite("GET / HTTP/1.1\r\n"
2835 "Host: www.example.org\r\n"
2836 "Connection: keep-alive\r\n\r\n"),
2837 };
2838
2839 MockRead data_reads[] = {
2840 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2841 // Give a couple authenticate options (only the middle one is actually
2842 // supported).
2843 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
2844 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2845 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2846 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2847 // Large content-length -- won't matter, as connection will be reset.
2848 MockRead("Content-Length: 10000\r\n\r\n"),
2849 MockRead(SYNCHRONOUS, ERR_FAILED),
2850 };
2851
2852 // After calling trans->RestartWithAuth(), this is the request we should
2853 // be issuing -- the final header line contains the credentials.
2854 MockWrite data_writes_restart[] = {
2855 MockWrite("GET / HTTP/1.1\r\n"
2856 "Host: www.example.org\r\n"
2857 "Connection: keep-alive\r\n"
2858 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2859 };
2860
Ryan Sleevib8d7ea02018-05-07 20:01:012861 StaticSocketDataProvider data(data_reads, data_writes);
David Benjamin83ddfb32018-03-30 01:07:522862 session_deps_.socket_factory->AddSocketDataProvider(&data);
2863
2864 TestCompletionCallback callback;
2865 int rv = callback.GetResult(
2866 trans.Start(&request, callback.callback(), NetLogWithSource()));
2867
2868 std::vector<std::unique_ptr<StaticSocketDataProvider>> data_restarts;
2869 for (int i = 0; i < 32; i++) {
2870 // Check the previous response was a 401.
2871 EXPECT_THAT(rv, IsOk());
2872 const HttpResponseInfo* response = trans.GetResponseInfo();
2873 ASSERT_TRUE(response);
2874 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2875
2876 data_restarts.push_back(std::make_unique<StaticSocketDataProvider>(
Ryan Sleevib8d7ea02018-05-07 20:01:012877 data_reads, data_writes_restart));
David Benjamin83ddfb32018-03-30 01:07:522878 session_deps_.socket_factory->AddSocketDataProvider(
2879 data_restarts.back().get());
2880 rv = callback.GetResult(trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
2881 callback.callback()));
2882 }
2883
2884 // After too many tries, the transaction should have given up.
2885 EXPECT_THAT(rv, IsError(ERR_TOO_MANY_RETRIES));
2886}
2887
bncd16676a2016-07-20 16:23:012888TEST_F(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:462889 HttpRequestInfo request;
2890 request.method = "GET";
bncce36dca22015-04-21 22:11:232891 request.url = GURL("http://www.example.org/");
ttuttle859dc7a2015-04-23 19:42:292892 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:102893 request.traffic_annotation =
2894 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]861fcd52009-08-26 02:33:462895
danakj1fd259a02016-04-16 03:17:092896 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162897 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272898
[email protected]861fcd52009-08-26 02:33:462899 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:232900 MockWrite(
2901 "GET / HTTP/1.1\r\n"
2902 "Host: www.example.org\r\n"
2903 "Connection: keep-alive\r\n\r\n"),
[email protected]861fcd52009-08-26 02:33:462904 };
2905
2906 MockRead data_reads[] = {
2907 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2908 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2909 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2910 // Large content-length -- won't matter, as connection will be reset.
2911 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062912 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:462913 };
2914
Ryan Sleevib8d7ea02018-05-07 20:01:012915 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:072916 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:412917 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:462918
tfarina42834112016-09-22 13:38:202919 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012920 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]861fcd52009-08-26 02:33:462921
2922 rv = callback.WaitForResult();
2923 EXPECT_EQ(0, rv);
2924
Ryan Sleevib8d7ea02018-05-07 20:01:012925 int64_t writes_size = CountWriteBytes(data_writes);
bnc691fda62016-08-12 00:43:162926 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012927 int64_t reads_size = CountReadBytes(data_reads);
bnc691fda62016-08-12 00:43:162928 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192929
bnc691fda62016-08-12 00:43:162930 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522931 ASSERT_TRUE(response);
2932 EXPECT_FALSE(response->auth_challenge);
[email protected]861fcd52009-08-26 02:33:462933}
2934
[email protected]2d2697f92009-02-18 21:00:322935// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2936// connection.
bncd16676a2016-07-20 16:23:012937TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
mmenkecc2298e2015-12-07 18:20:182938 // On the second pass, the body read of the auth challenge is synchronous, so
2939 // IsConnectedAndIdle returns false. The socket should still be drained and
2940 // reused. See http://crbug.com/544255.
2941 for (int i = 0; i < 2; ++i) {
2942 HttpRequestInfo request;
2943 request.method = "GET";
2944 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102945 request.traffic_annotation =
2946 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:322947
mmenkecc2298e2015-12-07 18:20:182948 TestNetLog log;
2949 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092950 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272951
mmenkecc2298e2015-12-07 18:20:182952 MockWrite data_writes[] = {
2953 MockWrite(ASYNC, 0,
2954 "GET / HTTP/1.1\r\n"
2955 "Host: www.example.org\r\n"
2956 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322957
bnc691fda62016-08-12 00:43:162958 // After calling trans.RestartWithAuth(), this is the request we should
mmenkecc2298e2015-12-07 18:20:182959 // be issuing -- the final header line contains the credentials.
2960 MockWrite(ASYNC, 6,
2961 "GET / HTTP/1.1\r\n"
2962 "Host: www.example.org\r\n"
2963 "Connection: keep-alive\r\n"
2964 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2965 };
[email protected]2d2697f92009-02-18 21:00:322966
mmenkecc2298e2015-12-07 18:20:182967 MockRead data_reads[] = {
2968 MockRead(ASYNC, 1, "HTTP/1.1 401 Unauthorized\r\n"),
2969 MockRead(ASYNC, 2, "WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2970 MockRead(ASYNC, 3, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2971 MockRead(ASYNC, 4, "Content-Length: 14\r\n\r\n"),
2972 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 5, "Unauthorized\r\n"),
[email protected]2d2697f92009-02-18 21:00:322973
mmenkecc2298e2015-12-07 18:20:182974 // Lastly, the server responds with the actual content.
2975 MockRead(ASYNC, 7, "HTTP/1.1 200 OK\r\n"),
2976 MockRead(ASYNC, 8, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2977 MockRead(ASYNC, 9, "Content-Length: 5\r\n\r\n"),
2978 MockRead(ASYNC, 10, "Hello"),
2979 };
[email protected]2d2697f92009-02-18 21:00:322980
Ryan Sleevib8d7ea02018-05-07 20:01:012981 SequencedSocketData data(data_reads, data_writes);
mmenkecc2298e2015-12-07 18:20:182982 data.set_busy_before_sync_reads(true);
2983 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]2d0a4f92011-05-05 16:38:462984
mmenkecc2298e2015-12-07 18:20:182985 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322986
bnc691fda62016-08-12 00:43:162987 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202988 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012989 ASSERT_THAT(callback1.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322990
mmenkecc2298e2015-12-07 18:20:182991 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162992 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
mmenkecc2298e2015-12-07 18:20:182993 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
[email protected]2d2697f92009-02-18 21:00:322994
bnc691fda62016-08-12 00:43:162995 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182996 ASSERT_TRUE(response);
2997 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322998
mmenkecc2298e2015-12-07 18:20:182999 TestCompletionCallback callback2;
[email protected]58e32bb2013-01-21 18:23:253000
bnc691fda62016-08-12 00:43:163001 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
3002 callback2.callback());
robpercival214763f2016-07-01 23:27:013003 ASSERT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:323004
mmenkecc2298e2015-12-07 18:20:183005 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:163006 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
mmenkecc2298e2015-12-07 18:20:183007 TestLoadTimingReused(load_timing_info2);
3008 // The load timing after restart should have the same socket ID, and times
3009 // those of the first load timing.
3010 EXPECT_LE(load_timing_info1.receive_headers_end,
3011 load_timing_info2.send_start);
3012 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]2d2697f92009-02-18 21:00:323013
bnc691fda62016-08-12 00:43:163014 response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:183015 ASSERT_TRUE(response);
3016 EXPECT_FALSE(response->auth_challenge);
3017 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:323018
mmenkecc2298e2015-12-07 18:20:183019 std::string response_data;
bnc691fda62016-08-12 00:43:163020 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]2d2697f92009-02-18 21:00:323021
Ryan Sleevib8d7ea02018-05-07 20:01:013022 int64_t writes_size = CountWriteBytes(data_writes);
bnc691fda62016-08-12 00:43:163023 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:013024 int64_t reads_size = CountReadBytes(data_reads);
bnc691fda62016-08-12 00:43:163025 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
mmenkecc2298e2015-12-07 18:20:183026 }
[email protected]2d2697f92009-02-18 21:00:323027}
3028
3029// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3030// connection and with no response body to drain.
bncd16676a2016-07-20 16:23:013031TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:423032 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:323033 request.method = "GET";
bncce36dca22015-04-21 22:11:233034 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:103035 request.traffic_annotation =
3036 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:323037
danakj1fd259a02016-04-16 03:17:093038 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273039
[email protected]2d2697f92009-02-18 21:00:323040 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:163041 MockWrite("GET / HTTP/1.1\r\n"
3042 "Host: www.example.org\r\n"
3043 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323044
bnc691fda62016-08-12 00:43:163045 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:233046 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:163047 MockWrite("GET / HTTP/1.1\r\n"
3048 "Host: www.example.org\r\n"
3049 "Connection: keep-alive\r\n"
3050 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323051 };
3052
[email protected]2d2697f92009-02-18 21:00:323053 MockRead data_reads1[] = {
3054 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
3055 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:313056 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:323057
3058 // Lastly, the server responds with the actual content.
3059 MockRead("HTTP/1.1 200 OK\r\n"),
3060 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:503061 MockRead("Content-Length: 5\r\n\r\n"),
3062 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:323063 };
3064
[email protected]2d0a4f92011-05-05 16:38:463065 // An incorrect reconnect would cause this to be read.
3066 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:063067 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:463068 };
3069
Ryan Sleevib8d7ea02018-05-07 20:01:013070 StaticSocketDataProvider data1(data_reads1, data_writes1);
3071 StaticSocketDataProvider data2(data_reads2, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:073072 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3073 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:323074
[email protected]49639fa2011-12-20 23:22:413075 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323076
bnc691fda62016-08-12 00:43:163077 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:203078 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013079 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:323080
3081 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013082 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:323083
bnc691fda62016-08-12 00:43:163084 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523085 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:043086 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:323087
[email protected]49639fa2011-12-20 23:22:413088 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323089
bnc691fda62016-08-12 00:43:163090 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013091 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:323092
3093 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013094 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:323095
bnc691fda62016-08-12 00:43:163096 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523097 ASSERT_TRUE(response);
3098 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503099 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:323100}
3101
3102// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3103// connection and with a large response body to drain.
bncd16676a2016-07-20 16:23:013104TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:423105 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:323106 request.method = "GET";
bncce36dca22015-04-21 22:11:233107 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:103108 request.traffic_annotation =
3109 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:323110
danakj1fd259a02016-04-16 03:17:093111 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273112
[email protected]2d2697f92009-02-18 21:00:323113 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:163114 MockWrite("GET / HTTP/1.1\r\n"
3115 "Host: www.example.org\r\n"
3116 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323117
bnc691fda62016-08-12 00:43:163118 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:233119 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:163120 MockWrite("GET / HTTP/1.1\r\n"
3121 "Host: www.example.org\r\n"
3122 "Connection: keep-alive\r\n"
3123 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323124 };
3125
3126 // Respond with 5 kb of response body.
3127 std::string large_body_string("Unauthorized");
3128 large_body_string.append(5 * 1024, ' ');
3129 large_body_string.append("\r\n");
3130
3131 MockRead data_reads1[] = {
3132 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
3133 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3134 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3135 // 5134 = 12 + 5 * 1024 + 2
3136 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063137 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:323138
3139 // Lastly, the server responds with the actual content.
3140 MockRead("HTTP/1.1 200 OK\r\n"),
3141 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:503142 MockRead("Content-Length: 5\r\n\r\n"),
3143 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:323144 };
3145
[email protected]2d0a4f92011-05-05 16:38:463146 // An incorrect reconnect would cause this to be read.
3147 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:063148 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:463149 };
3150
Ryan Sleevib8d7ea02018-05-07 20:01:013151 StaticSocketDataProvider data1(data_reads1, data_writes1);
3152 StaticSocketDataProvider data2(data_reads2, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:073153 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3154 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:323155
[email protected]49639fa2011-12-20 23:22:413156 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323157
bnc691fda62016-08-12 00:43:163158 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:203159 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013160 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:323161
3162 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013163 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:323164
bnc691fda62016-08-12 00:43:163165 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523166 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:043167 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:323168
[email protected]49639fa2011-12-20 23:22:413169 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323170
bnc691fda62016-08-12 00:43:163171 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013172 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:323173
3174 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013175 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:323176
bnc691fda62016-08-12 00:43:163177 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523178 ASSERT_TRUE(response);
3179 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503180 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:323181}
3182
3183// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:313184// connection, but the server gets impatient and closes the connection.
bncd16676a2016-07-20 16:23:013185TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:313186 HttpRequestInfo request;
3187 request.method = "GET";
bncce36dca22015-04-21 22:11:233188 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:103189 request.traffic_annotation =
3190 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]11203f012009-11-12 23:02:313191
danakj1fd259a02016-04-16 03:17:093192 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273193
[email protected]11203f012009-11-12 23:02:313194 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233195 MockWrite(
3196 "GET / HTTP/1.1\r\n"
3197 "Host: www.example.org\r\n"
3198 "Connection: keep-alive\r\n\r\n"),
3199 // This simulates the seemingly successful write to a closed connection
3200 // if the bug is not fixed.
3201 MockWrite(
3202 "GET / HTTP/1.1\r\n"
3203 "Host: www.example.org\r\n"
3204 "Connection: keep-alive\r\n"
3205 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:313206 };
3207
3208 MockRead data_reads1[] = {
3209 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
3210 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3211 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3212 MockRead("Content-Length: 14\r\n\r\n"),
3213 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:063214 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:313215 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:063216 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:313217 };
3218
bnc691fda62016-08-12 00:43:163219 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]11203f012009-11-12 23:02:313220 // be issuing -- the final header line contains the credentials.
3221 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:233222 MockWrite(
3223 "GET / HTTP/1.1\r\n"
3224 "Host: www.example.org\r\n"
3225 "Connection: keep-alive\r\n"
3226 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:313227 };
3228
3229 // Lastly, the server responds with the actual content.
3230 MockRead data_reads2[] = {
3231 MockRead("HTTP/1.1 200 OK\r\n"),
3232 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:503233 MockRead("Content-Length: 5\r\n\r\n"),
3234 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:313235 };
3236
Ryan Sleevib8d7ea02018-05-07 20:01:013237 StaticSocketDataProvider data1(data_reads1, data_writes1);
3238 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:073239 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3240 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:313241
[email protected]49639fa2011-12-20 23:22:413242 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:313243
bnc691fda62016-08-12 00:43:163244 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:203245 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013246 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:313247
3248 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013249 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:313250
bnc691fda62016-08-12 00:43:163251 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523252 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:043253 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:313254
[email protected]49639fa2011-12-20 23:22:413255 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:313256
bnc691fda62016-08-12 00:43:163257 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013258 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:313259
3260 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013261 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:313262
bnc691fda62016-08-12 00:43:163263 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523264 ASSERT_TRUE(response);
3265 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503266 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:313267}
3268
[email protected]394816e92010-08-03 07:38:593269// Test the request-challenge-retry sequence for basic auth, over a connection
3270// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013271TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
ttuttle34f63b52015-03-05 04:33:013272 HttpRequestInfo request;
3273 request.method = "GET";
bncce36dca22015-04-21 22:11:233274 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:013275 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293276 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103277 request.traffic_annotation =
3278 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle34f63b52015-03-05 04:33:013279
3280 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593281 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493282 ProxyResolutionService::CreateFixedFromPacResult(
3283 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513284 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:013285 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093286 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013287
3288 // Since we have proxy, should try to establish tunnel.
3289 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543290 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173291 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543292 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013293 };
3294
mmenkee71e15332015-10-07 16:39:543295 // The proxy responds to the connect with a 407, using a non-persistent
ttuttle34f63b52015-03-05 04:33:013296 // connection.
3297 MockRead data_reads1[] = {
3298 // No credentials.
3299 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
3300 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
mmenkee71e15332015-10-07 16:39:543301 };
ttuttle34f63b52015-03-05 04:33:013302
mmenkee71e15332015-10-07 16:39:543303 // Since the first connection couldn't be reused, need to establish another
3304 // once given credentials.
3305 MockWrite data_writes2[] = {
3306 // After calling trans->RestartWithAuth(), this is the request we should
3307 // be issuing -- the final header line contains the credentials.
3308 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173309 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543310 "Proxy-Connection: keep-alive\r\n"
3311 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3312
3313 MockWrite("GET / HTTP/1.1\r\n"
3314 "Host: www.example.org\r\n"
3315 "Connection: keep-alive\r\n\r\n"),
3316 };
3317
3318 MockRead data_reads2[] = {
ttuttle34f63b52015-03-05 04:33:013319 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3320
3321 MockRead("HTTP/1.1 200 OK\r\n"),
3322 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3323 MockRead("Content-Length: 5\r\n\r\n"),
3324 MockRead(SYNCHRONOUS, "hello"),
3325 };
3326
Ryan Sleevib8d7ea02018-05-07 20:01:013327 StaticSocketDataProvider data1(data_reads1, data_writes1);
ttuttle34f63b52015-03-05 04:33:013328 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:013329 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenkee71e15332015-10-07 16:39:543330 session_deps_.socket_factory->AddSocketDataProvider(&data2);
ttuttle34f63b52015-03-05 04:33:013331 SSLSocketDataProvider ssl(ASYNC, OK);
3332 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3333
3334 TestCompletionCallback callback1;
3335
bnc87dcefc2017-05-25 12:47:583336 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193337 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013338
3339 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013340 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:013341
3342 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013343 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463344 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:013345 log.GetEntries(&entries);
3346 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003347 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3348 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013349 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003350 entries, pos,
3351 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3352 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013353
3354 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523355 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013356 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523357 ASSERT_TRUE(response->headers);
ttuttle34f63b52015-03-05 04:33:013358 EXPECT_EQ(407, response->headers->response_code());
3359 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3360 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3361
3362 LoadTimingInfo load_timing_info;
3363 // CONNECT requests and responses are handled at the connect job level, so
3364 // the transaction does not yet have a connection.
3365 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3366
3367 TestCompletionCallback callback2;
3368
3369 rv =
3370 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013371 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:013372
3373 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013374 EXPECT_THAT(rv, IsOk());
ttuttle34f63b52015-03-05 04:33:013375
3376 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523377 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013378
3379 EXPECT_TRUE(response->headers->IsKeepAlive());
3380 EXPECT_EQ(200, response->headers->response_code());
3381 EXPECT_EQ(5, response->headers->GetContentLength());
3382 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3383
3384 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523385 EXPECT_FALSE(response->auth_challenge);
ttuttle34f63b52015-03-05 04:33:013386
3387 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3388 TestLoadTimingNotReusedWithPac(load_timing_info,
3389 CONNECT_TIMING_HAS_SSL_TIMES);
3390
3391 trans.reset();
3392 session->CloseAllConnections();
3393}
3394
3395// Test the request-challenge-retry sequence for basic auth, over a connection
3396// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013397TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) {
[email protected]394816e92010-08-03 07:38:593398 HttpRequestInfo request;
3399 request.method = "GET";
bncce36dca22015-04-21 22:11:233400 request.url = GURL("https://www.example.org/");
[email protected]394816e92010-08-03 07:38:593401 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293402 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103403 request.traffic_annotation =
3404 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]394816e92010-08-03 07:38:593405
[email protected]cb9bf6ca2011-01-28 13:15:273406 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593407 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493408 ProxyResolutionService::CreateFixedFromPacResult(
3409 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513410 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073411 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093412 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273413
[email protected]394816e92010-08-03 07:38:593414 // Since we have proxy, should try to establish tunnel.
3415 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543416 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173417 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543418 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenkee0b5c882015-08-26 20:29:113419 };
3420
mmenkee71e15332015-10-07 16:39:543421 // The proxy responds to the connect with a 407, using a non-persistent
mmenke0fd148d2015-09-30 23:00:083422 // connection.
3423 MockRead data_reads1[] = {
mmenkee71e15332015-10-07 16:39:543424 // No credentials.
3425 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3426 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3427 MockRead("Proxy-Connection: close\r\n\r\n"),
3428 };
mmenkee0b5c882015-08-26 20:29:113429
mmenkee71e15332015-10-07 16:39:543430 MockWrite data_writes2[] = {
3431 // After calling trans->RestartWithAuth(), this is the request we should
3432 // be issuing -- the final header line contains the credentials.
3433 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173434 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543435 "Proxy-Connection: keep-alive\r\n"
3436 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
mmenke0fd148d2015-09-30 23:00:083437
mmenkee71e15332015-10-07 16:39:543438 MockWrite("GET / HTTP/1.1\r\n"
3439 "Host: www.example.org\r\n"
3440 "Connection: keep-alive\r\n\r\n"),
3441 };
3442
3443 MockRead data_reads2[] = {
3444 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3445
3446 MockRead("HTTP/1.1 200 OK\r\n"),
3447 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3448 MockRead("Content-Length: 5\r\n\r\n"),
3449 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:593450 };
3451
Ryan Sleevib8d7ea02018-05-07 20:01:013452 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:073453 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:013454 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenkee71e15332015-10-07 16:39:543455 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8ddf8322012-02-23 18:08:063456 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073457 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:593458
[email protected]49639fa2011-12-20 23:22:413459 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:593460
bnc87dcefc2017-05-25 12:47:583461 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193462 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:503463
[email protected]49639fa2011-12-20 23:22:413464 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013465 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593466
3467 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013468 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463469 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403470 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:593471 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003472 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3473 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593474 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403475 entries, pos,
mikecirone8b85c432016-09-08 19:11:003476 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3477 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593478
3479 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523480 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013481 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523482 ASSERT_TRUE(response->headers);
[email protected]394816e92010-08-03 07:38:593483 EXPECT_EQ(407, response->headers->response_code());
3484 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043485 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:593486
[email protected]029c83b62013-01-24 05:28:203487 LoadTimingInfo load_timing_info;
3488 // CONNECT requests and responses are handled at the connect job level, so
3489 // the transaction does not yet have a connection.
3490 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3491
[email protected]49639fa2011-12-20 23:22:413492 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:593493
[email protected]49639fa2011-12-20 23:22:413494 rv = trans->RestartWithAuth(
3495 AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013496 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593497
3498 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013499 EXPECT_THAT(rv, IsOk());
[email protected]394816e92010-08-03 07:38:593500
3501 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523502 ASSERT_TRUE(response);
[email protected]394816e92010-08-03 07:38:593503
3504 EXPECT_TRUE(response->headers->IsKeepAlive());
3505 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:503506 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:593507 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3508
3509 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523510 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503511
[email protected]029c83b62013-01-24 05:28:203512 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3513 TestLoadTimingNotReusedWithPac(load_timing_info,
3514 CONNECT_TIMING_HAS_SSL_TIMES);
3515
[email protected]0b0bf032010-09-21 18:08:503516 trans.reset();
[email protected]102e27c2011-02-23 01:01:313517 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:593518}
3519
[email protected]11203f012009-11-12 23:02:313520// Test the request-challenge-retry sequence for basic auth, over a keep-alive
ttuttle34f63b52015-03-05 04:33:013521// proxy connection with HTTP/1.0 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013522TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
mmenked39192ee2015-12-09 00:57:233523 // On the second pass, the body read of the auth challenge is synchronous, so
3524 // IsConnectedAndIdle returns false. The socket should still be drained and
3525 // reused. See http://crbug.com/544255.
3526 for (int i = 0; i < 2; ++i) {
3527 HttpRequestInfo request;
3528 request.method = "GET";
3529 request.url = GURL("https://www.example.org/");
3530 // Ensure that proxy authentication is attempted even
3531 // when the no authentication data flag is set.
3532 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103533 request.traffic_annotation =
3534 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle34f63b52015-03-05 04:33:013535
mmenked39192ee2015-12-09 00:57:233536 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593537 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493538 ProxyResolutionService::CreateFixed("myproxy:70",
3539 TRAFFIC_ANNOTATION_FOR_TESTS);
mmenked39192ee2015-12-09 00:57:233540 BoundTestNetLog log;
3541 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093542 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013543
bnc691fda62016-08-12 00:43:163544 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013545
mmenked39192ee2015-12-09 00:57:233546 // Since we have proxy, should try to establish tunnel.
3547 MockWrite data_writes1[] = {
3548 MockWrite(ASYNC, 0,
3549 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3550 "Host: www.example.org:443\r\n"
3551 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013552
bnc691fda62016-08-12 00:43:163553 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233554 // be issuing -- the final header line contains the credentials.
3555 MockWrite(ASYNC, 3,
3556 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3557 "Host: www.example.org:443\r\n"
3558 "Proxy-Connection: keep-alive\r\n"
3559 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3560 };
ttuttle34f63b52015-03-05 04:33:013561
mmenked39192ee2015-12-09 00:57:233562 // The proxy responds to the connect with a 407, using a persistent
3563 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3564 MockRead data_reads1[] = {
3565 // No credentials.
3566 MockRead(ASYNC, 1,
3567 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3568 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3569 "Proxy-Connection: keep-alive\r\n"
3570 "Content-Length: 10\r\n\r\n"),
3571 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
ttuttle34f63b52015-03-05 04:33:013572
mmenked39192ee2015-12-09 00:57:233573 // Wrong credentials (wrong password).
3574 MockRead(ASYNC, 4,
3575 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3576 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3577 "Proxy-Connection: keep-alive\r\n"
3578 "Content-Length: 10\r\n\r\n"),
3579 // No response body because the test stops reading here.
3580 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3581 };
ttuttle34f63b52015-03-05 04:33:013582
Ryan Sleevib8d7ea02018-05-07 20:01:013583 SequencedSocketData data1(data_reads1, data_writes1);
mmenked39192ee2015-12-09 00:57:233584 data1.set_busy_before_sync_reads(true);
3585 session_deps_.socket_factory->AddSocketDataProvider(&data1);
ttuttle34f63b52015-03-05 04:33:013586
mmenked39192ee2015-12-09 00:57:233587 TestCompletionCallback callback1;
ttuttle34f63b52015-03-05 04:33:013588
bnc691fda62016-08-12 00:43:163589 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013590 EXPECT_THAT(callback1.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013591
mmenked39192ee2015-12-09 00:57:233592 TestNetLogEntry::List entries;
3593 log.GetEntries(&entries);
3594 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003595 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3596 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233597 ExpectLogContainsSomewhere(
3598 entries, pos,
mikecirone8b85c432016-09-08 19:11:003599 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3600 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013601
bnc691fda62016-08-12 00:43:163602 const HttpResponseInfo* 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 TestCompletionCallback callback2;
ttuttle34f63b52015-03-05 04:33:013612
mmenked39192ee2015-12-09 00:57:233613 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163614 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3615 callback2.callback());
robpercival214763f2016-07-01 23:27:013616 EXPECT_THAT(callback2.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013617
bnc691fda62016-08-12 00:43:163618 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233619 ASSERT_TRUE(response);
3620 ASSERT_TRUE(response->headers);
3621 EXPECT_TRUE(response->headers->IsKeepAlive());
3622 EXPECT_EQ(407, response->headers->response_code());
3623 EXPECT_EQ(10, response->headers->GetContentLength());
3624 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3625 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013626
mmenked39192ee2015-12-09 00:57:233627 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3628 // out of scope.
3629 session->CloseAllConnections();
3630 }
ttuttle34f63b52015-03-05 04:33:013631}
3632
3633// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3634// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013635TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
mmenked39192ee2015-12-09 00:57:233636 // On the second pass, the body read of the auth challenge is synchronous, so
3637 // IsConnectedAndIdle returns false. The socket should still be drained and
3638 // reused. See http://crbug.com/544255.
3639 for (int i = 0; i < 2; ++i) {
3640 HttpRequestInfo request;
3641 request.method = "GET";
3642 request.url = GURL("https://www.example.org/");
3643 // Ensure that proxy authentication is attempted even
3644 // when the no authentication data flag is set.
3645 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103646 request.traffic_annotation =
3647 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenked39192ee2015-12-09 00:57:233648
3649 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593650 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493651 ProxyResolutionService::CreateFixed("myproxy:70",
3652 TRAFFIC_ANNOTATION_FOR_TESTS);
mmenked39192ee2015-12-09 00:57:233653 BoundTestNetLog log;
3654 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093655 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenked39192ee2015-12-09 00:57:233656
bnc691fda62016-08-12 00:43:163657 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenked39192ee2015-12-09 00:57:233658
3659 // Since we have proxy, should try to establish tunnel.
3660 MockWrite data_writes1[] = {
3661 MockWrite(ASYNC, 0,
3662 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3663 "Host: www.example.org:443\r\n"
3664 "Proxy-Connection: keep-alive\r\n\r\n"),
3665
bnc691fda62016-08-12 00:43:163666 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233667 // be issuing -- the final header line contains the credentials.
3668 MockWrite(ASYNC, 3,
3669 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3670 "Host: www.example.org:443\r\n"
3671 "Proxy-Connection: keep-alive\r\n"
3672 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3673 };
3674
3675 // The proxy responds to the connect with a 407, using a persistent
3676 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3677 MockRead data_reads1[] = {
3678 // No credentials.
3679 MockRead(ASYNC, 1,
3680 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3681 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3682 "Content-Length: 10\r\n\r\n"),
3683 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
3684
3685 // Wrong credentials (wrong password).
3686 MockRead(ASYNC, 4,
3687 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3688 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3689 "Content-Length: 10\r\n\r\n"),
3690 // No response body because the test stops reading here.
3691 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3692 };
3693
Ryan Sleevib8d7ea02018-05-07 20:01:013694 SequencedSocketData data1(data_reads1, data_writes1);
mmenked39192ee2015-12-09 00:57:233695 data1.set_busy_before_sync_reads(true);
3696 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3697
3698 TestCompletionCallback callback1;
3699
bnc691fda62016-08-12 00:43:163700 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013701 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233702
3703 TestNetLogEntry::List entries;
3704 log.GetEntries(&entries);
3705 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003706 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3707 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233708 ExpectLogContainsSomewhere(
3709 entries, pos,
mikecirone8b85c432016-09-08 19:11:003710 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3711 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233712
bnc691fda62016-08-12 00:43:163713 const HttpResponseInfo* 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 TestCompletionCallback callback2;
3723
3724 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163725 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3726 callback2.callback());
robpercival214763f2016-07-01 23:27:013727 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233728
bnc691fda62016-08-12 00:43:163729 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233730 ASSERT_TRUE(response);
3731 ASSERT_TRUE(response->headers);
3732 EXPECT_TRUE(response->headers->IsKeepAlive());
3733 EXPECT_EQ(407, response->headers->response_code());
3734 EXPECT_EQ(10, response->headers->GetContentLength());
3735 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3736 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3737
3738 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3739 // out of scope.
3740 session->CloseAllConnections();
3741 }
3742}
3743
3744// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3745// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel, in
3746// the case the server sends extra data on the original socket, so it can't be
3747// reused.
bncd16676a2016-07-20 16:23:013748TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveExtraData) {
[email protected]cb9bf6ca2011-01-28 13:15:273749 HttpRequestInfo request;
3750 request.method = "GET";
bncce36dca22015-04-21 22:11:233751 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273752 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293753 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103754 request.traffic_annotation =
3755 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:273756
[email protected]2d2697f92009-02-18 21:00:323757 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593758 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493759 ProxyResolutionService::CreateFixedFromPacResult(
3760 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513761 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073762 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093763 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:323764
[email protected]2d2697f92009-02-18 21:00:323765 // Since we have proxy, should try to establish tunnel.
3766 MockWrite data_writes1[] = {
mmenked39192ee2015-12-09 00:57:233767 MockWrite(ASYNC, 0,
3768 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173769 "Host: www.example.org:443\r\n"
3770 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233771 };
[email protected]2d2697f92009-02-18 21:00:323772
mmenked39192ee2015-12-09 00:57:233773 // The proxy responds to the connect with a 407, using a persistent, but sends
3774 // extra data, so the socket cannot be reused.
3775 MockRead data_reads1[] = {
3776 // No credentials.
3777 MockRead(ASYNC, 1,
3778 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3779 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3780 "Content-Length: 10\r\n\r\n"),
3781 MockRead(SYNCHRONOUS, 2, "0123456789"),
3782 MockRead(SYNCHRONOUS, 3, "I'm broken!"),
3783 };
3784
3785 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:233786 // After calling trans->RestartWithAuth(), this is the request we should
3787 // be issuing -- the final header line contains the credentials.
mmenked39192ee2015-12-09 00:57:233788 MockWrite(ASYNC, 0,
3789 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173790 "Host: www.example.org:443\r\n"
3791 "Proxy-Connection: keep-alive\r\n"
mmenked39192ee2015-12-09 00:57:233792 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3793
3794 MockWrite(ASYNC, 2,
3795 "GET / HTTP/1.1\r\n"
3796 "Host: www.example.org\r\n"
3797 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323798 };
3799
mmenked39192ee2015-12-09 00:57:233800 MockRead data_reads2[] = {
3801 MockRead(ASYNC, 1, "HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323802
mmenked39192ee2015-12-09 00:57:233803 MockRead(ASYNC, 3,
3804 "HTTP/1.1 200 OK\r\n"
3805 "Content-Type: text/html; charset=iso-8859-1\r\n"
3806 "Content-Length: 5\r\n\r\n"),
3807 // No response body because the test stops reading here.
3808 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 4),
[email protected]2d2697f92009-02-18 21:00:323809 };
3810
Ryan Sleevib8d7ea02018-05-07 20:01:013811 SequencedSocketData data1(data_reads1, data_writes1);
mmenked39192ee2015-12-09 00:57:233812 data1.set_busy_before_sync_reads(true);
[email protected]bb88e1d32013-05-03 23:11:073813 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:013814 SequencedSocketData data2(data_reads2, data_writes2);
mmenked39192ee2015-12-09 00:57:233815 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3816 SSLSocketDataProvider ssl(ASYNC, OK);
3817 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d2697f92009-02-18 21:00:323818
[email protected]49639fa2011-12-20 23:22:413819 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323820
bnc87dcefc2017-05-25 12:47:583821 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193822 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d2697f92009-02-18 21:00:323823
mmenked39192ee2015-12-09 00:57:233824 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013825 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233826
mmenke43758e62015-05-04 21:09:463827 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403828 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:393829 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003830 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3831 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:393832 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403833 entries, pos,
mikecirone8b85c432016-09-08 19:11:003834 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3835 NetLogEventPhase::NONE);
[email protected]2d2697f92009-02-18 21:00:323836
[email protected]1c773ea12009-04-28 19:58:423837 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243838 ASSERT_TRUE(response);
3839 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:323840 EXPECT_TRUE(response->headers->IsKeepAlive());
3841 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423842 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043843 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:323844
mmenked39192ee2015-12-09 00:57:233845 LoadTimingInfo load_timing_info;
3846 // CONNECT requests and responses are handled at the connect job level, so
3847 // the transaction does not yet have a connection.
3848 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3849
[email protected]49639fa2011-12-20 23:22:413850 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323851
mmenked39192ee2015-12-09 00:57:233852 rv =
3853 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013854 EXPECT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:323855
[email protected]2d2697f92009-02-18 21:00:323856 EXPECT_TRUE(response->headers->IsKeepAlive());
mmenked39192ee2015-12-09 00:57:233857 EXPECT_EQ(200, response->headers->response_code());
3858 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:423859 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]e772db3f2010-07-12 18:11:133860
mmenked39192ee2015-12-09 00:57:233861 // The password prompt info should not be set.
3862 EXPECT_FALSE(response->auth_challenge);
3863
3864 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3865 TestLoadTimingNotReusedWithPac(load_timing_info,
3866 CONNECT_TIMING_HAS_SSL_TIMES);
3867
3868 trans.reset();
[email protected]102e27c2011-02-23 01:01:313869 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:323870}
3871
mmenkee71e15332015-10-07 16:39:543872// Test the case a proxy closes a socket while the challenge body is being
3873// drained.
bncd16676a2016-07-20 16:23:013874TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHangupDuringBody) {
mmenkee71e15332015-10-07 16:39:543875 HttpRequestInfo request;
3876 request.method = "GET";
3877 request.url = GURL("https://www.example.org/");
3878 // Ensure that proxy authentication is attempted even
3879 // when the no authentication data flag is set.
3880 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103881 request.traffic_annotation =
3882 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenkee71e15332015-10-07 16:39:543883
3884 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:493885 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
3886 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:093887 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenkee71e15332015-10-07 16:39:543888
bnc691fda62016-08-12 00:43:163889 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkee71e15332015-10-07 16:39:543890
3891 // Since we have proxy, should try to establish tunnel.
3892 MockWrite data_writes1[] = {
3893 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173894 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543895 "Proxy-Connection: keep-alive\r\n\r\n"),
3896 };
3897
3898 // The proxy responds to the connect with a 407, using a persistent
3899 // connection.
3900 MockRead data_reads1[] = {
3901 // No credentials.
3902 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3903 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3904 MockRead("Content-Length: 10\r\n\r\n"), MockRead("spam!"),
3905 // Server hands up in the middle of the body.
3906 MockRead(ASYNC, ERR_CONNECTION_CLOSED),
3907 };
3908
3909 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:163910 // After calling trans.RestartWithAuth(), this is the request we should
mmenkee71e15332015-10-07 16:39:543911 // be issuing -- the final header line contains the credentials.
3912 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173913 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543914 "Proxy-Connection: keep-alive\r\n"
3915 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3916
3917 MockWrite("GET / HTTP/1.1\r\n"
3918 "Host: www.example.org\r\n"
3919 "Connection: keep-alive\r\n\r\n"),
3920 };
3921
3922 MockRead data_reads2[] = {
3923 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3924
3925 MockRead("HTTP/1.1 200 OK\r\n"),
3926 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3927 MockRead("Content-Length: 5\r\n\r\n"),
3928 MockRead(SYNCHRONOUS, "hello"),
3929 };
3930
Ryan Sleevib8d7ea02018-05-07 20:01:013931 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenkee71e15332015-10-07 16:39:543932 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:013933 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenkee71e15332015-10-07 16:39:543934 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3935 SSLSocketDataProvider ssl(ASYNC, OK);
3936 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3937
3938 TestCompletionCallback callback;
3939
tfarina42834112016-09-22 13:38:203940 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013941 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543942
bnc691fda62016-08-12 00:43:163943 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543944 ASSERT_TRUE(response);
3945 ASSERT_TRUE(response->headers);
3946 EXPECT_TRUE(response->headers->IsKeepAlive());
3947 EXPECT_EQ(407, response->headers->response_code());
3948 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3949
bnc691fda62016-08-12 00:43:163950 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
robpercival214763f2016-07-01 23:27:013951 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543952
bnc691fda62016-08-12 00:43:163953 response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543954 ASSERT_TRUE(response);
3955 ASSERT_TRUE(response->headers);
3956 EXPECT_TRUE(response->headers->IsKeepAlive());
3957 EXPECT_EQ(200, response->headers->response_code());
3958 std::string body;
bnc691fda62016-08-12 00:43:163959 EXPECT_THAT(ReadTransaction(&trans, &body), IsOk());
mmenkee71e15332015-10-07 16:39:543960 EXPECT_EQ("hello", body);
3961}
3962
[email protected]a8e9b162009-03-12 00:06:443963// Test that we don't read the response body when we fail to establish a tunnel,
3964// even if the user cancels the proxy's auth attempt.
bncd16676a2016-07-20 16:23:013965TEST_F(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:273966 HttpRequestInfo request;
3967 request.method = "GET";
bncce36dca22015-04-21 22:11:233968 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:103969 request.traffic_annotation =
3970 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:273971
[email protected]a8e9b162009-03-12 00:06:443972 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:493973 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
3974 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]a8e9b162009-03-12 00:06:443975
danakj1fd259a02016-04-16 03:17:093976 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:443977
bnc691fda62016-08-12 00:43:163978 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a8e9b162009-03-12 00:06:443979
[email protected]a8e9b162009-03-12 00:06:443980 // Since we have proxy, should try to establish tunnel.
3981 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173982 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3983 "Host: www.example.org:443\r\n"
3984 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:443985 };
3986
3987 // The proxy responds to the connect with a 407.
3988 MockRead data_reads[] = {
ttuttle7933c112015-01-06 00:55:243989 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3990 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3991 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233992 MockRead("0123456789"),
ttuttle7933c112015-01-06 00:55:243993 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]a8e9b162009-03-12 00:06:443994 };
3995
Ryan Sleevib8d7ea02018-05-07 20:01:013996 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:073997 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:443998
[email protected]49639fa2011-12-20 23:22:413999 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:444000
tfarina42834112016-09-22 13:38:204001 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014002 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a8e9b162009-03-12 00:06:444003
4004 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:014005 EXPECT_THAT(rv, IsOk());
[email protected]a8e9b162009-03-12 00:06:444006
bnc691fda62016-08-12 00:43:164007 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:244008 ASSERT_TRUE(response);
4009 ASSERT_TRUE(response->headers);
[email protected]a8e9b162009-03-12 00:06:444010 EXPECT_TRUE(response->headers->IsKeepAlive());
4011 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:424012 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:444013
4014 std::string response_data;
bnc691fda62016-08-12 00:43:164015 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:014016 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]e60e47a2010-07-14 03:37:184017
4018 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:314019 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:444020}
4021
ttuttle7933c112015-01-06 00:55:244022// Test that we don't pass extraneous headers from the proxy's response to the
4023// caller when the proxy responds to CONNECT with 407.
bncd16676a2016-07-20 16:23:014024TEST_F(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
ttuttle7933c112015-01-06 00:55:244025 HttpRequestInfo request;
4026 request.method = "GET";
bncce36dca22015-04-21 22:11:234027 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104028 request.traffic_annotation =
4029 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle7933c112015-01-06 00:55:244030
4031 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:494032 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
4033 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle7933c112015-01-06 00:55:244034
danakj1fd259a02016-04-16 03:17:094035 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle7933c112015-01-06 00:55:244036
bnc691fda62016-08-12 00:43:164037 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle7933c112015-01-06 00:55:244038
4039 // Since we have proxy, should try to establish tunnel.
4040 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:174041 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4042 "Host: www.example.org:443\r\n"
4043 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle7933c112015-01-06 00:55:244044 };
4045
4046 // The proxy responds to the connect with a 407.
4047 MockRead data_reads[] = {
4048 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4049 MockRead("X-Foo: bar\r\n"),
4050 MockRead("Set-Cookie: foo=bar\r\n"),
4051 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4052 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:234053 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
ttuttle7933c112015-01-06 00:55:244054 };
4055
Ryan Sleevib8d7ea02018-05-07 20:01:014056 StaticSocketDataProvider data(data_reads, data_writes);
ttuttle7933c112015-01-06 00:55:244057 session_deps_.socket_factory->AddSocketDataProvider(&data);
4058
4059 TestCompletionCallback callback;
4060
tfarina42834112016-09-22 13:38:204061 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014062 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle7933c112015-01-06 00:55:244063
4064 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:014065 EXPECT_THAT(rv, IsOk());
ttuttle7933c112015-01-06 00:55:244066
bnc691fda62016-08-12 00:43:164067 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:244068 ASSERT_TRUE(response);
4069 ASSERT_TRUE(response->headers);
4070 EXPECT_TRUE(response->headers->IsKeepAlive());
4071 EXPECT_EQ(407, response->headers->response_code());
4072 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4073 EXPECT_FALSE(response->headers->HasHeader("X-Foo"));
4074 EXPECT_FALSE(response->headers->HasHeader("Set-Cookie"));
4075
4076 std::string response_data;
bnc691fda62016-08-12 00:43:164077 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:014078 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
ttuttle7933c112015-01-06 00:55:244079
4080 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
4081 session->CloseAllConnections();
4082}
4083
[email protected]8fdbcd22010-05-05 02:54:524084// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
4085// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
bncd16676a2016-07-20 16:23:014086TEST_F(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:524087 HttpRequestInfo request;
4088 request.method = "GET";
bncce36dca22015-04-21 22:11:234089 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104090 request.traffic_annotation =
4091 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8fdbcd22010-05-05 02:54:524092
[email protected]cb9bf6ca2011-01-28 13:15:274093 // We are using a DIRECT connection (i.e. no proxy) for this session.
danakj1fd259a02016-04-16 03:17:094094 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:164095 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:274096
[email protected]8fdbcd22010-05-05 02:54:524097 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:234098 MockWrite(
4099 "GET / HTTP/1.1\r\n"
4100 "Host: www.example.org\r\n"
4101 "Connection: keep-alive\r\n\r\n"),
[email protected]8fdbcd22010-05-05 02:54:524102 };
4103
4104 MockRead data_reads1[] = {
4105 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
4106 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4107 // Large content-length -- won't matter, as connection will be reset.
4108 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064109 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:524110 };
4111
Ryan Sleevib8d7ea02018-05-07 20:01:014112 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:074113 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:524114
[email protected]49639fa2011-12-20 23:22:414115 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:524116
tfarina42834112016-09-22 13:38:204117 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014118 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8fdbcd22010-05-05 02:54:524119
4120 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:014121 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
[email protected]8fdbcd22010-05-05 02:54:524122}
4123
[email protected]7a67a8152010-11-05 18:31:104124// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
4125// through a non-authenticating proxy. The request should fail with
4126// ERR_UNEXPECTED_PROXY_AUTH.
4127// Note that it is impossible to detect if an HTTP server returns a 407 through
4128// a non-authenticating proxy - there is nothing to indicate whether the
4129// response came from the proxy or the server, so it is treated as if the proxy
4130// issued the challenge.
bncd16676a2016-07-20 16:23:014131TEST_F(HttpNetworkTransactionTest, HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:274132 HttpRequestInfo request;
4133 request.method = "GET";
bncce36dca22015-04-21 22:11:234134 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104135 request.traffic_annotation =
4136 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:274137
Ramin Halavatica8d5252018-03-12 05:33:494138 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
4139 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:514140 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074141 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094142 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:104143
[email protected]7a67a8152010-11-05 18:31:104144 // Since we have proxy, should try to establish tunnel.
4145 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174146 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4147 "Host: www.example.org:443\r\n"
4148 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:104149
rsleevidb16bb02015-11-12 23:47:174150 MockWrite("GET / HTTP/1.1\r\n"
4151 "Host: www.example.org\r\n"
4152 "Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:104153 };
4154
4155 MockRead data_reads1[] = {
4156 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4157
4158 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
4159 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4160 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:064161 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:104162 };
4163
Ryan Sleevib8d7ea02018-05-07 20:01:014164 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:074165 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:064166 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074167 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:104168
[email protected]49639fa2011-12-20 23:22:414169 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:104170
bnc691fda62016-08-12 00:43:164171 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]7a67a8152010-11-05 18:31:104172
bnc691fda62016-08-12 00:43:164173 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014174 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a67a8152010-11-05 18:31:104175
4176 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014177 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
mmenke43758e62015-05-04 21:09:464178 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:404179 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:104180 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:004181 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
4182 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:104183 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:404184 entries, pos,
mikecirone8b85c432016-09-08 19:11:004185 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
4186 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:104187}
[email protected]2df19bb2010-08-25 20:13:464188
mmenke2a1781d2015-10-07 19:25:334189// Test a proxy auth scheme that allows default credentials and a proxy server
4190// that uses non-persistent connections.
bncd16676a2016-07-20 16:23:014191TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334192 AuthAllowsDefaultCredentialsTunnelConnectionClose) {
4193 HttpRequestInfo request;
4194 request.method = "GET";
4195 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104196 request.traffic_annotation =
4197 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334198
4199 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594200 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494201 ProxyResolutionService::CreateFixedFromPacResult(
4202 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334203
Jeremy Roman0579ed62017-08-29 15:56:194204 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334205 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194206 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334207 mock_handler->set_allows_default_credentials(true);
4208 auth_handler_factory->AddMockHandler(mock_handler.release(),
4209 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484210 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334211
4212 // Add NetLog just so can verify load timing information gets a NetLog ID.
4213 NetLog net_log;
4214 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094215 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334216
4217 // Since we have proxy, should try to establish tunnel.
4218 MockWrite data_writes1[] = {
4219 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174220 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334221 "Proxy-Connection: keep-alive\r\n\r\n"),
4222 };
4223
4224 // The proxy responds to the connect with a 407, using a non-persistent
4225 // connection.
4226 MockRead data_reads1[] = {
4227 // No credentials.
4228 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4229 MockRead("Proxy-Authenticate: Mock\r\n"),
4230 MockRead("Proxy-Connection: close\r\n\r\n"),
4231 };
4232
4233 // Since the first connection couldn't be reused, need to establish another
4234 // once given credentials.
4235 MockWrite data_writes2[] = {
4236 // After calling trans->RestartWithAuth(), this is the request we should
4237 // be issuing -- the final header line contains the credentials.
4238 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174239 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334240 "Proxy-Connection: keep-alive\r\n"
4241 "Proxy-Authorization: auth_token\r\n\r\n"),
4242
4243 MockWrite("GET / HTTP/1.1\r\n"
4244 "Host: www.example.org\r\n"
4245 "Connection: keep-alive\r\n\r\n"),
4246 };
4247
4248 MockRead data_reads2[] = {
4249 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
4250
4251 MockRead("HTTP/1.1 200 OK\r\n"),
4252 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4253 MockRead("Content-Length: 5\r\n\r\n"),
4254 MockRead(SYNCHRONOUS, "hello"),
4255 };
4256
Ryan Sleevib8d7ea02018-05-07 20:01:014257 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke2a1781d2015-10-07 19:25:334258 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:014259 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke2a1781d2015-10-07 19:25:334260 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4261 SSLSocketDataProvider ssl(ASYNC, OK);
4262 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4263
bnc87dcefc2017-05-25 12:47:584264 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194265 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334266
4267 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204268 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014269 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334270
4271 const HttpResponseInfo* response = trans->GetResponseInfo();
4272 ASSERT_TRUE(response);
4273 ASSERT_TRUE(response->headers);
4274 EXPECT_FALSE(response->headers->IsKeepAlive());
4275 EXPECT_EQ(407, response->headers->response_code());
4276 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4277 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
wezca1070932016-05-26 20:30:524278 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:334279
4280 LoadTimingInfo load_timing_info;
4281 // CONNECT requests and responses are handled at the connect job level, so
4282 // the transaction does not yet have a connection.
4283 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4284
4285 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014286 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334287 response = trans->GetResponseInfo();
4288 ASSERT_TRUE(response);
4289 ASSERT_TRUE(response->headers);
4290 EXPECT_TRUE(response->headers->IsKeepAlive());
4291 EXPECT_EQ(200, response->headers->response_code());
4292 EXPECT_EQ(5, response->headers->GetContentLength());
4293 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4294
4295 // The password prompt info should not be set.
4296 EXPECT_FALSE(response->auth_challenge);
4297
4298 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4299 TestLoadTimingNotReusedWithPac(load_timing_info,
4300 CONNECT_TIMING_HAS_SSL_TIMES);
4301
4302 trans.reset();
4303 session->CloseAllConnections();
4304}
4305
4306// Test a proxy auth scheme that allows default credentials and a proxy server
4307// that hangs up when credentials are initially sent.
bncd16676a2016-07-20 16:23:014308TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334309 AuthAllowsDefaultCredentialsTunnelServerClosesConnection) {
4310 HttpRequestInfo request;
4311 request.method = "GET";
4312 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104313 request.traffic_annotation =
4314 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334315
4316 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594317 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494318 ProxyResolutionService::CreateFixedFromPacResult(
4319 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334320
Jeremy Roman0579ed62017-08-29 15:56:194321 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334322 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194323 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334324 mock_handler->set_allows_default_credentials(true);
4325 auth_handler_factory->AddMockHandler(mock_handler.release(),
4326 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484327 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334328
4329 // Add NetLog just so can verify load timing information gets a NetLog ID.
4330 NetLog net_log;
4331 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094332 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334333
4334 // Should try to establish tunnel.
4335 MockWrite data_writes1[] = {
4336 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174337 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334338 "Proxy-Connection: keep-alive\r\n\r\n"),
4339
4340 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174341 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334342 "Proxy-Connection: keep-alive\r\n"
4343 "Proxy-Authorization: auth_token\r\n\r\n"),
4344 };
4345
4346 // The proxy responds to the connect with a 407, using a non-persistent
4347 // connection.
4348 MockRead data_reads1[] = {
4349 // No credentials.
4350 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4351 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4352 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4353 };
4354
4355 // Since the first connection was closed, need to establish another once given
4356 // credentials.
4357 MockWrite data_writes2[] = {
4358 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174359 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334360 "Proxy-Connection: keep-alive\r\n"
4361 "Proxy-Authorization: auth_token\r\n\r\n"),
4362
4363 MockWrite("GET / HTTP/1.1\r\n"
4364 "Host: www.example.org\r\n"
4365 "Connection: keep-alive\r\n\r\n"),
4366 };
4367
4368 MockRead data_reads2[] = {
4369 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
4370
4371 MockRead("HTTP/1.1 200 OK\r\n"),
4372 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4373 MockRead("Content-Length: 5\r\n\r\n"),
4374 MockRead(SYNCHRONOUS, "hello"),
4375 };
4376
Ryan Sleevib8d7ea02018-05-07 20:01:014377 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke2a1781d2015-10-07 19:25:334378 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:014379 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke2a1781d2015-10-07 19:25:334380 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4381 SSLSocketDataProvider ssl(ASYNC, OK);
4382 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4383
bnc87dcefc2017-05-25 12:47:584384 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194385 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334386
4387 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204388 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014389 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334390
4391 const HttpResponseInfo* response = trans->GetResponseInfo();
4392 ASSERT_TRUE(response);
4393 ASSERT_TRUE(response->headers);
4394 EXPECT_TRUE(response->headers->IsKeepAlive());
4395 EXPECT_EQ(407, response->headers->response_code());
4396 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4397 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4398 EXPECT_FALSE(response->auth_challenge);
4399
4400 LoadTimingInfo load_timing_info;
4401 // CONNECT requests and responses are handled at the connect job level, so
4402 // the transaction does not yet have a connection.
4403 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4404
4405 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014406 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334407
4408 response = trans->GetResponseInfo();
4409 ASSERT_TRUE(response);
4410 ASSERT_TRUE(response->headers);
4411 EXPECT_TRUE(response->headers->IsKeepAlive());
4412 EXPECT_EQ(200, response->headers->response_code());
4413 EXPECT_EQ(5, response->headers->GetContentLength());
4414 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4415
4416 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524417 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:334418
4419 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4420 TestLoadTimingNotReusedWithPac(load_timing_info,
4421 CONNECT_TIMING_HAS_SSL_TIMES);
4422
4423 trans.reset();
4424 session->CloseAllConnections();
4425}
4426
4427// Test a proxy auth scheme that allows default credentials and a proxy server
4428// that hangs up when credentials are initially sent, and hangs up again when
4429// they are retried.
bncd16676a2016-07-20 16:23:014430TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334431 AuthAllowsDefaultCredentialsTunnelServerClosesConnectionTwice) {
4432 HttpRequestInfo request;
4433 request.method = "GET";
4434 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104435 request.traffic_annotation =
4436 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334437
4438 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594439 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494440 ProxyResolutionService::CreateFixedFromPacResult(
4441 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334442
Jeremy Roman0579ed62017-08-29 15:56:194443 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334444 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194445 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334446 mock_handler->set_allows_default_credentials(true);
4447 auth_handler_factory->AddMockHandler(mock_handler.release(),
4448 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484449 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334450
4451 // Add NetLog just so can verify load timing information gets a NetLog ID.
4452 NetLog net_log;
4453 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094454 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334455
4456 // Should try to establish tunnel.
4457 MockWrite data_writes1[] = {
4458 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174459 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334460 "Proxy-Connection: keep-alive\r\n\r\n"),
4461
4462 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174463 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334464 "Proxy-Connection: keep-alive\r\n"
4465 "Proxy-Authorization: auth_token\r\n\r\n"),
4466 };
4467
4468 // The proxy responds to the connect with a 407, and then hangs up after the
4469 // second request is sent.
4470 MockRead data_reads1[] = {
4471 // No credentials.
4472 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4473 MockRead("Content-Length: 0\r\n"),
4474 MockRead("Proxy-Connection: keep-alive\r\n"),
4475 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4476 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4477 };
4478
4479 // HttpNetworkTransaction sees a reused connection that was closed with
4480 // ERR_CONNECTION_CLOSED, realized it might have been a race, so retries the
4481 // request.
4482 MockWrite data_writes2[] = {
4483 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174484 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334485 "Proxy-Connection: keep-alive\r\n\r\n"),
4486 };
4487
4488 // The proxy, having had more than enough of us, just hangs up.
4489 MockRead data_reads2[] = {
4490 // No credentials.
4491 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4492 };
4493
Ryan Sleevib8d7ea02018-05-07 20:01:014494 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke2a1781d2015-10-07 19:25:334495 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:014496 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke2a1781d2015-10-07 19:25:334497 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4498
bnc87dcefc2017-05-25 12:47:584499 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194500 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334501
4502 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204503 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014504 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334505
4506 const HttpResponseInfo* response = trans->GetResponseInfo();
4507 ASSERT_TRUE(response);
4508 ASSERT_TRUE(response->headers);
4509 EXPECT_TRUE(response->headers->IsKeepAlive());
4510 EXPECT_EQ(407, response->headers->response_code());
4511 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4512 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4513 EXPECT_FALSE(response->auth_challenge);
4514
4515 LoadTimingInfo load_timing_info;
4516 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4517
4518 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014519 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_EMPTY_RESPONSE));
mmenke2a1781d2015-10-07 19:25:334520
4521 trans.reset();
4522 session->CloseAllConnections();
4523}
4524
Asanka Herathbc3f8f62018-11-16 23:08:304525// This test exercises an odd edge case where the proxy closes the connection
4526// after the authentication handshake is complete. Presumably this technique is
4527// used in lieu of returning a 403 or 5xx status code when the authentication
4528// succeeds, but the user is not authorized to connect to the destination
4529// server. There's no standard for what a proxy should do to indicate a blocked
4530// site.
4531TEST_F(HttpNetworkTransactionTest,
4532 AuthAllowsDefaultCredentialsTunnelConnectionClosesBeforeBody) {
4533 HttpRequestInfo request;
4534 request.method = "GET";
4535 request.url = GURL("https://www.example.org/");
4536 request.traffic_annotation =
4537 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4538
4539 // Configure against proxy server "myproxy:70".
4540 session_deps_.proxy_resolution_service =
4541 ProxyResolutionService::CreateFixedFromPacResult(
4542 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
4543
Steven Valdez0ef94d02018-11-19 23:28:134544 // When TLS 1.3 is enabled, spurious connections are made as part of the SSL
4545 // version interference probes.
4546 // TODO(crbug.com/906668): Correctly handle version interference probes to
4547 // test TLS 1.3.
4548 SSLConfig config;
4549 config.version_max = SSL_PROTOCOL_VERSION_TLS1_2;
4550 session_deps_.ssl_config_service =
4551 std::make_unique<TestSSLConfigService>(config);
4552
Asanka Herathbc3f8f62018-11-16 23:08:304553 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
4554 auth_handler_factory->set_do_init_from_challenge(true);
4555
4556 // Create two mock AuthHandlers. This is because the transaction gets retried
4557 // after the first ERR_CONNECTION_CLOSED since it's ambiguous whether there
4558 // was a real network error.
4559 //
4560 // The handlers support both default and explicit credentials. The retry
4561 // mentioned above should be able to reuse the default identity. Thus there
4562 // should never be a need to prompt for explicit credentials.
4563 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
4564 mock_handler->set_allows_default_credentials(true);
4565 mock_handler->set_allows_explicit_credentials(true);
4566 mock_handler->set_connection_based(true);
4567 auth_handler_factory->AddMockHandler(mock_handler.release(),
4568 HttpAuth::AUTH_PROXY);
4569 mock_handler = std::make_unique<HttpAuthHandlerMock>();
4570 mock_handler->set_allows_default_credentials(true);
4571 mock_handler->set_allows_explicit_credentials(true);
4572 mock_handler->set_connection_based(true);
4573 auth_handler_factory->AddMockHandler(mock_handler.release(),
4574 HttpAuth::AUTH_PROXY);
4575 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
4576
4577 NetLog net_log;
4578 session_deps_.net_log = &net_log;
4579 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4580
4581 // Data for both sockets.
4582 //
4583 // Writes are for the tunnel establishment attempts and the
4584 // authentication handshake.
4585 MockWrite data_writes1[] = {
4586 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4587 "Host: www.example.org:443\r\n"
4588 "Proxy-Connection: keep-alive\r\n\r\n"),
4589
4590 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4591 "Host: www.example.org:443\r\n"
4592 "Proxy-Connection: keep-alive\r\n"
4593 "Proxy-Authorization: auth_token\r\n\r\n"),
4594
4595 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4596 "Host: www.example.org:443\r\n"
4597 "Proxy-Connection: keep-alive\r\n"
4598 "Proxy-Authorization: auth_token\r\n\r\n"),
4599 };
4600
4601 // The server side of the authentication handshake. Note that the response to
4602 // the final CONNECT request is ERR_CONNECTION_CLOSED.
4603 MockRead data_reads1[] = {
4604 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4605 MockRead("Content-Length: 0\r\n"),
4606 MockRead("Proxy-Connection: keep-alive\r\n"),
4607 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4608
4609 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4610 MockRead("Content-Length: 0\r\n"),
4611 MockRead("Proxy-Connection: keep-alive\r\n"),
4612 MockRead("Proxy-Authenticate: Mock foo\r\n\r\n"),
4613
4614 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4615 };
4616
4617 StaticSocketDataProvider data1(data_reads1, data_writes1);
4618 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4619
4620 // The second socket is for the reconnection attempt. Data is identical to the
4621 // first attempt.
4622 StaticSocketDataProvider data2(data_reads1, data_writes1);
4623 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4624
4625 auto trans =
4626 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
4627
4628 TestCompletionCallback callback;
4629 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4630
4631 // Two rounds per handshake. After one retry, the error is propagated up the
4632 // stack.
4633 for (int i = 0; i < 4; ++i) {
4634 EXPECT_THAT(callback.GetResult(rv), IsOk());
4635
4636 const HttpResponseInfo* response = trans->GetResponseInfo();
4637 ASSERT_TRUE(response);
4638 ASSERT_TRUE(response->headers);
4639 EXPECT_EQ(407, response->headers->response_code());
4640 ASSERT_TRUE(trans->IsReadyToRestartForAuth());
4641
4642 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4643 }
4644
4645 // One shall be the number thou shalt retry, and the number of the retrying
4646 // shall be one. Two shalt thou not retry, neither retry thou zero, excepting
4647 // that thou then proceed to one. Three is right out. Once the number one,
4648 // being the first number, be reached, then lobbest thou thy
4649 // ERR_CONNECTION_CLOSED towards they network transaction, who shall snuff it.
4650 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.GetResult(rv));
4651
4652 trans.reset();
4653 session->CloseAllConnections();
4654}
4655
mmenke2a1781d2015-10-07 19:25:334656// Test a proxy auth scheme that allows default credentials and a proxy server
4657// that hangs up when credentials are initially sent, and sends a challenge
4658// again they are retried.
bncd16676a2016-07-20 16:23:014659TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334660 AuthAllowsDefaultCredentialsTunnelServerChallengesTwice) {
4661 HttpRequestInfo request;
4662 request.method = "GET";
4663 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104664 request.traffic_annotation =
4665 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334666
4667 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594668 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494669 ProxyResolutionService::CreateFixedFromPacResult(
4670 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334671
Jeremy Roman0579ed62017-08-29 15:56:194672 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334673 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194674 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334675 mock_handler->set_allows_default_credentials(true);
4676 auth_handler_factory->AddMockHandler(mock_handler.release(),
4677 HttpAuth::AUTH_PROXY);
4678 // Add another handler for the second challenge. It supports default
4679 // credentials, but they shouldn't be used, since they were already tried.
Jeremy Roman0579ed62017-08-29 15:56:194680 mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334681 mock_handler->set_allows_default_credentials(true);
4682 auth_handler_factory->AddMockHandler(mock_handler.release(),
4683 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484684 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334685
4686 // Add NetLog just so can verify load timing information gets a NetLog ID.
4687 NetLog net_log;
4688 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094689 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334690
4691 // Should try to establish tunnel.
4692 MockWrite data_writes1[] = {
4693 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174694 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334695 "Proxy-Connection: keep-alive\r\n\r\n"),
4696 };
4697
4698 // The proxy responds to the connect with a 407, using a non-persistent
4699 // connection.
4700 MockRead data_reads1[] = {
4701 // No credentials.
4702 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4703 MockRead("Proxy-Authenticate: Mock\r\n"),
4704 MockRead("Proxy-Connection: close\r\n\r\n"),
4705 };
4706
4707 // Since the first connection was closed, need to establish another once given
4708 // credentials.
4709 MockWrite data_writes2[] = {
4710 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174711 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334712 "Proxy-Connection: keep-alive\r\n"
4713 "Proxy-Authorization: auth_token\r\n\r\n"),
4714 };
4715
4716 MockRead data_reads2[] = {
4717 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4718 MockRead("Proxy-Authenticate: Mock\r\n"),
4719 MockRead("Proxy-Connection: close\r\n\r\n"),
4720 };
4721
Ryan Sleevib8d7ea02018-05-07 20:01:014722 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke2a1781d2015-10-07 19:25:334723 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:014724 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke2a1781d2015-10-07 19:25:334725 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4726 SSLSocketDataProvider ssl(ASYNC, OK);
4727 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4728
bnc87dcefc2017-05-25 12:47:584729 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194730 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334731
4732 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204733 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014734 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334735
4736 const HttpResponseInfo* response = trans->GetResponseInfo();
4737 ASSERT_TRUE(response);
4738 ASSERT_TRUE(response->headers);
4739 EXPECT_EQ(407, response->headers->response_code());
4740 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4741 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4742 EXPECT_FALSE(response->auth_challenge);
4743
4744 LoadTimingInfo load_timing_info;
4745 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4746
4747 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014748 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334749 response = trans->GetResponseInfo();
4750 ASSERT_TRUE(response);
4751 ASSERT_TRUE(response->headers);
4752 EXPECT_EQ(407, response->headers->response_code());
4753 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4754 EXPECT_TRUE(response->auth_challenge);
4755
4756 trans.reset();
4757 session->CloseAllConnections();
4758}
4759
asankae2257db2016-10-11 22:03:164760// A more nuanced test than GenerateAuthToken test which asserts that
4761// ERR_INVALID_AUTH_CREDENTIALS does not cause the auth scheme to be
4762// unnecessarily invalidated, and that if the server co-operates, the
4763// authentication handshake can continue with the same scheme but with a
4764// different identity.
4765TEST_F(HttpNetworkTransactionTest, NonPermanentGenerateAuthTokenError) {
4766 HttpRequestInfo request;
4767 request.method = "GET";
4768 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104769 request.traffic_annotation =
4770 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
asankae2257db2016-10-11 22:03:164771
Jeremy Roman0579ed62017-08-29 15:56:194772 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
asankae2257db2016-10-11 22:03:164773 auth_handler_factory->set_do_init_from_challenge(true);
4774
4775 // First handler. Uses default credentials, but barfs at generate auth token.
Jeremy Roman0579ed62017-08-29 15:56:194776 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164777 mock_handler->set_allows_default_credentials(true);
4778 mock_handler->set_allows_explicit_credentials(true);
4779 mock_handler->set_connection_based(true);
4780 mock_handler->SetGenerateExpectation(true, ERR_INVALID_AUTH_CREDENTIALS);
4781 auth_handler_factory->AddMockHandler(mock_handler.release(),
4782 HttpAuth::AUTH_SERVER);
4783
4784 // Add another handler for the second challenge. It supports default
4785 // credentials, but they shouldn't be used, since they were already tried.
Jeremy Roman0579ed62017-08-29 15:56:194786 mock_handler = std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164787 mock_handler->set_allows_default_credentials(true);
4788 mock_handler->set_allows_explicit_credentials(true);
4789 mock_handler->set_connection_based(true);
4790 auth_handler_factory->AddMockHandler(mock_handler.release(),
4791 HttpAuth::AUTH_SERVER);
4792 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
4793
4794 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4795
4796 MockWrite data_writes1[] = {
4797 MockWrite("GET / HTTP/1.1\r\n"
4798 "Host: www.example.org\r\n"
4799 "Connection: keep-alive\r\n\r\n"),
4800 };
4801
4802 MockRead data_reads1[] = {
4803 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4804 "WWW-Authenticate: Mock\r\n"
4805 "Connection: keep-alive\r\n\r\n"),
4806 };
4807
4808 // Identical to data_writes1[]. The AuthHandler encounters a
4809 // ERR_INVALID_AUTH_CREDENTIALS during the GenerateAuthToken stage, so the
4810 // transaction procceds without an authorization header.
4811 MockWrite data_writes2[] = {
4812 MockWrite("GET / HTTP/1.1\r\n"
4813 "Host: www.example.org\r\n"
4814 "Connection: keep-alive\r\n\r\n"),
4815 };
4816
4817 MockRead data_reads2[] = {
4818 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4819 "WWW-Authenticate: Mock\r\n"
4820 "Connection: keep-alive\r\n\r\n"),
4821 };
4822
4823 MockWrite data_writes3[] = {
4824 MockWrite("GET / HTTP/1.1\r\n"
4825 "Host: www.example.org\r\n"
4826 "Connection: keep-alive\r\n"
4827 "Authorization: auth_token\r\n\r\n"),
4828 };
4829
4830 MockRead data_reads3[] = {
4831 MockRead("HTTP/1.1 200 OK\r\n"
4832 "Content-Length: 5\r\n"
4833 "Content-Type: text/plain\r\n"
4834 "Connection: keep-alive\r\n\r\n"
4835 "Hello"),
4836 };
4837
Ryan Sleevib8d7ea02018-05-07 20:01:014838 StaticSocketDataProvider data1(data_reads1, data_writes1);
asankae2257db2016-10-11 22:03:164839 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4840
Ryan Sleevib8d7ea02018-05-07 20:01:014841 StaticSocketDataProvider data2(data_reads2, data_writes2);
asankae2257db2016-10-11 22:03:164842 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4843
Ryan Sleevib8d7ea02018-05-07 20:01:014844 StaticSocketDataProvider data3(data_reads3, data_writes3);
asankae2257db2016-10-11 22:03:164845 session_deps_.socket_factory->AddSocketDataProvider(&data3);
4846
bnc87dcefc2017-05-25 12:47:584847 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194848 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
asankae2257db2016-10-11 22:03:164849
4850 TestCompletionCallback callback;
4851 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4852 EXPECT_THAT(callback.GetResult(rv), IsOk());
4853
4854 const HttpResponseInfo* response = trans->GetResponseInfo();
4855 ASSERT_TRUE(response);
4856 ASSERT_TRUE(response->headers);
4857 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4858
4859 // The following three tests assert that an authentication challenge was
4860 // received and that the stack is ready to respond to the challenge using
4861 // ambient credentials.
4862 EXPECT_EQ(401, response->headers->response_code());
4863 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4864 EXPECT_FALSE(response->auth_challenge);
4865
4866 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4867 EXPECT_THAT(callback.GetResult(rv), IsOk());
4868 response = trans->GetResponseInfo();
4869 ASSERT_TRUE(response);
4870 ASSERT_TRUE(response->headers);
4871
4872 // The following three tests assert that an authentication challenge was
4873 // received and that the stack needs explicit credentials before it is ready
4874 // to respond to the challenge.
4875 EXPECT_EQ(401, response->headers->response_code());
4876 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4877 EXPECT_TRUE(response->auth_challenge);
4878
4879 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4880 EXPECT_THAT(callback.GetResult(rv), IsOk());
4881 response = trans->GetResponseInfo();
4882 ASSERT_TRUE(response);
4883 ASSERT_TRUE(response->headers);
4884 EXPECT_EQ(200, response->headers->response_code());
4885
4886 trans.reset();
4887 session->CloseAllConnections();
4888}
4889
Matt Menked1eb6d42018-01-17 04:54:064890// Proxy resolver that returns a proxy with the same host and port for different
4891// schemes, based on the path of the URL being requests.
4892class SameProxyWithDifferentSchemesProxyResolver : public ProxyResolver {
4893 public:
4894 SameProxyWithDifferentSchemesProxyResolver() {}
4895 ~SameProxyWithDifferentSchemesProxyResolver() override {}
4896
4897 static std::string ProxyHostPortPairAsString() { return "proxy.test:10000"; }
4898
4899 static HostPortPair ProxyHostPortPair() {
4900 return HostPortPair::FromString(ProxyHostPortPairAsString());
4901 }
4902
4903 // ProxyResolver implementation.
4904 int GetProxyForURL(const GURL& url,
4905 ProxyInfo* results,
Bence Békycc5b88a2018-05-25 20:24:174906 CompletionOnceCallback callback,
Matt Menked1eb6d42018-01-17 04:54:064907 std::unique_ptr<Request>* request,
4908 const NetLogWithSource& /*net_log*/) override {
4909 *results = ProxyInfo();
Ramin Halavati921731ea2018-03-16 08:24:574910 results->set_traffic_annotation(
4911 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
Matt Menked1eb6d42018-01-17 04:54:064912 if (url.path() == "/socks4") {
4913 results->UsePacString("SOCKS " + ProxyHostPortPairAsString());
4914 return OK;
4915 }
4916 if (url.path() == "/socks5") {
4917 results->UsePacString("SOCKS5 " + ProxyHostPortPairAsString());
4918 return OK;
4919 }
4920 if (url.path() == "/http") {
4921 results->UsePacString("PROXY " + ProxyHostPortPairAsString());
4922 return OK;
4923 }
4924 if (url.path() == "/https") {
4925 results->UsePacString("HTTPS " + ProxyHostPortPairAsString());
4926 return OK;
4927 }
Matt Menkee8648fa2019-01-17 16:47:074928 if (url.path() == "/https_trusted") {
4929 results->UseProxyServer(ProxyServer(ProxyServer::SCHEME_HTTPS,
4930 ProxyHostPortPair(),
4931 true /* is_trusted_proxy */));
4932 return OK;
4933 }
Matt Menked1eb6d42018-01-17 04:54:064934 NOTREACHED();
4935 return ERR_NOT_IMPLEMENTED;
4936 }
4937
4938 private:
4939 DISALLOW_COPY_AND_ASSIGN(SameProxyWithDifferentSchemesProxyResolver);
4940};
4941
4942class SameProxyWithDifferentSchemesProxyResolverFactory
4943 : public ProxyResolverFactory {
4944 public:
4945 SameProxyWithDifferentSchemesProxyResolverFactory()
4946 : ProxyResolverFactory(false) {}
4947
Lily Houghton99597862018-03-07 16:40:424948 int CreateProxyResolver(const scoped_refptr<PacFileData>& pac_script,
4949 std::unique_ptr<ProxyResolver>* resolver,
Bence Békycc5b88a2018-05-25 20:24:174950 CompletionOnceCallback callback,
Lily Houghton99597862018-03-07 16:40:424951 std::unique_ptr<Request>* request) override {
Matt Menked1eb6d42018-01-17 04:54:064952 *resolver = std::make_unique<SameProxyWithDifferentSchemesProxyResolver>();
4953 return OK;
4954 }
4955
4956 private:
4957 DISALLOW_COPY_AND_ASSIGN(SameProxyWithDifferentSchemesProxyResolverFactory);
4958};
4959
4960// Check that when different proxy schemes are all applied to a proxy at the
Matt Menkee8648fa2019-01-17 16:47:074961// same address, the connections are not grouped together. i.e., a request to
Matt Menked1eb6d42018-01-17 04:54:064962// foo.com using proxy.com as an HTTPS proxy won't use the same socket as a
4963// request to foo.com using proxy.com as an HTTP proxy.
4964TEST_F(HttpNetworkTransactionTest, SameDestinationForDifferentProxyTypes) {
Ramin Halavatica8d5252018-03-12 05:33:494965 session_deps_.proxy_resolution_service =
4966 std::make_unique<ProxyResolutionService>(
4967 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
4968 ProxyConfig::CreateAutoDetect(), TRAFFIC_ANNOTATION_FOR_TESTS)),
4969 std::make_unique<SameProxyWithDifferentSchemesProxyResolverFactory>(),
4970 nullptr);
Matt Menked1eb6d42018-01-17 04:54:064971
4972 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4973
4974 MockWrite socks_writes[] = {
4975 MockWrite(SYNCHRONOUS, kSOCKS4OkRequestLocalHostPort80,
4976 kSOCKS4OkRequestLocalHostPort80Length),
4977 MockWrite(SYNCHRONOUS,
4978 "GET /socks4 HTTP/1.1\r\n"
4979 "Host: test\r\n"
4980 "Connection: keep-alive\r\n\r\n"),
4981 };
4982 MockRead socks_reads[] = {
4983 MockRead(SYNCHRONOUS, kSOCKS4OkReply, kSOCKS4OkReplyLength),
4984 MockRead("HTTP/1.0 200 OK\r\n"
4985 "Connection: keep-alive\r\n"
4986 "Content-Length: 15\r\n\r\n"
4987 "SOCKS4 Response"),
4988 };
Ryan Sleevib8d7ea02018-05-07 20:01:014989 StaticSocketDataProvider socks_data(socks_reads, socks_writes);
Matt Menked1eb6d42018-01-17 04:54:064990 session_deps_.socket_factory->AddSocketDataProvider(&socks_data);
4991
4992 const char kSOCKS5Request[] = {
4993 0x05, // Version
4994 0x01, // Command (CONNECT)
4995 0x00, // Reserved
4996 0x03, // Address type (DOMAINNAME)
4997 0x04, // Length of domain (4)
4998 't', 'e', 's', 't', // Domain string
4999 0x00, 0x50, // 16-bit port (80)
5000 };
5001 MockWrite socks5_writes[] = {
5002 MockWrite(ASYNC, kSOCKS5GreetRequest, kSOCKS5GreetRequestLength),
Avi Drissman4365a4782018-12-28 19:26:245003 MockWrite(ASYNC, kSOCKS5Request, base::size(kSOCKS5Request)),
Matt Menked1eb6d42018-01-17 04:54:065004 MockWrite(SYNCHRONOUS,
5005 "GET /socks5 HTTP/1.1\r\n"
5006 "Host: test\r\n"
5007 "Connection: keep-alive\r\n\r\n"),
5008 };
5009 MockRead socks5_reads[] = {
5010 MockRead(ASYNC, kSOCKS5GreetResponse, kSOCKS5GreetResponseLength),
5011 MockRead(ASYNC, kSOCKS5OkResponse, kSOCKS5OkResponseLength),
5012 MockRead("HTTP/1.0 200 OK\r\n"
5013 "Connection: keep-alive\r\n"
5014 "Content-Length: 15\r\n\r\n"
5015 "SOCKS5 Response"),
5016 };
Ryan Sleevib8d7ea02018-05-07 20:01:015017 StaticSocketDataProvider socks5_data(socks5_reads, socks5_writes);
Matt Menked1eb6d42018-01-17 04:54:065018 session_deps_.socket_factory->AddSocketDataProvider(&socks5_data);
5019
5020 MockWrite http_writes[] = {
5021 MockWrite(SYNCHRONOUS,
5022 "GET http://test/http HTTP/1.1\r\n"
5023 "Host: test\r\n"
5024 "Proxy-Connection: keep-alive\r\n\r\n"),
5025 };
5026 MockRead http_reads[] = {
5027 MockRead("HTTP/1.1 200 OK\r\n"
5028 "Proxy-Connection: keep-alive\r\n"
5029 "Content-Length: 13\r\n\r\n"
5030 "HTTP Response"),
5031 };
Ryan Sleevib8d7ea02018-05-07 20:01:015032 StaticSocketDataProvider http_data(http_reads, http_writes);
Matt Menked1eb6d42018-01-17 04:54:065033 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
5034
5035 MockWrite https_writes[] = {
5036 MockWrite(SYNCHRONOUS,
5037 "GET http://test/https HTTP/1.1\r\n"
5038 "Host: test\r\n"
5039 "Proxy-Connection: keep-alive\r\n\r\n"),
5040 };
5041 MockRead https_reads[] = {
5042 MockRead("HTTP/1.1 200 OK\r\n"
5043 "Proxy-Connection: keep-alive\r\n"
5044 "Content-Length: 14\r\n\r\n"
5045 "HTTPS Response"),
5046 };
Ryan Sleevib8d7ea02018-05-07 20:01:015047 StaticSocketDataProvider https_data(https_reads, https_writes);
Matt Menked1eb6d42018-01-17 04:54:065048 session_deps_.socket_factory->AddSocketDataProvider(&https_data);
5049 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
5050 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5051
Matt Menkee8648fa2019-01-17 16:47:075052 MockWrite https_trusted_writes[] = {
5053 MockWrite(SYNCHRONOUS,
5054 "GET http://test/https_trusted HTTP/1.1\r\n"
5055 "Host: test\r\n"
5056 "Proxy-Connection: keep-alive\r\n\r\n"),
5057 };
5058 MockRead https_trusted_reads[] = {
5059 MockRead("HTTP/1.1 200 OK\r\n"
5060 "Proxy-Connection: keep-alive\r\n"
5061 "Content-Length: 22\r\n\r\n"
5062 "HTTPS Trusted Response"),
5063 };
5064 StaticSocketDataProvider trusted_https_data(https_trusted_reads,
5065 https_trusted_writes);
5066 session_deps_.socket_factory->AddSocketDataProvider(&trusted_https_data);
5067 SSLSocketDataProvider ssl2(SYNCHRONOUS, OK);
5068 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
5069
Matt Menked1eb6d42018-01-17 04:54:065070 struct TestCase {
5071 GURL url;
5072 std::string expected_response;
Matt Menkee8648fa2019-01-17 16:47:075073 // How many idle sockets there should be in the SOCKS 4/5 proxy socket pools
Matt Menked1eb6d42018-01-17 04:54:065074 // after the test.
Matt Menkee8648fa2019-01-17 16:47:075075 int expected_idle_socks4_sockets;
5076 int expected_idle_socks5_sockets;
5077 // How many idle sockets there should be in the HTTP/HTTPS proxy socket
5078 // pools after the test.
Matt Menked1eb6d42018-01-17 04:54:065079 int expected_idle_http_sockets;
Matt Menkee8648fa2019-01-17 16:47:075080 int expected_idle_https_sockets;
5081 // How many idle sockets there should be in the HTTPS proxy socket pool with
5082 // the ProxyServer's |is_trusted_proxy| bit set after the test.
5083 int expected_idle_trusted_https_sockets;
Matt Menked1eb6d42018-01-17 04:54:065084 } const kTestCases[] = {
Matt Menkee8648fa2019-01-17 16:47:075085 {GURL("http://test/socks4"), "SOCKS4 Response", 1, 0, 0, 0, 0},
5086 {GURL("http://test/socks5"), "SOCKS5 Response", 1, 1, 0, 0, 0},
5087 {GURL("http://test/http"), "HTTP Response", 1, 1, 1, 0, 0},
5088 {GURL("http://test/https"), "HTTPS Response", 1, 1, 1, 1, 0},
5089 {GURL("http://test/https_trusted"), "HTTPS Trusted Response", 1, 1, 1, 1,
5090 1},
Matt Menked1eb6d42018-01-17 04:54:065091 };
5092
5093 for (const auto& test_case : kTestCases) {
5094 HttpRequestInfo request;
5095 request.method = "GET";
5096 request.url = test_case.url;
Ramin Halavatib5e433e2018-02-07 07:41:105097 request.traffic_annotation =
5098 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Matt Menked1eb6d42018-01-17 04:54:065099 std::unique_ptr<HttpNetworkTransaction> trans =
5100 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
5101 session.get());
5102 TestCompletionCallback callback;
5103 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
5104 EXPECT_THAT(callback.GetResult(rv), IsOk());
5105
5106 const HttpResponseInfo* response = trans->GetResponseInfo();
5107 ASSERT_TRUE(response);
5108 ASSERT_TRUE(response->headers);
5109 EXPECT_EQ(200, response->headers->response_code());
5110 std::string response_data;
5111 EXPECT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
5112 EXPECT_EQ(test_case.expected_response, response_data);
5113
5114 // Return the socket to the socket pool, so can make sure it's not used for
5115 // the next requests.
5116 trans.reset();
5117 base::RunLoop().RunUntilIdle();
5118
5119 // Check the number of idle sockets in the pool, to make sure that used
5120 // sockets are indeed being returned to the socket pool. If each request
5121 // doesn't return an idle socket to the pool, the test would incorrectly
5122 // pass.
Matt Menkee8648fa2019-01-17 16:47:075123 EXPECT_EQ(test_case.expected_idle_socks4_sockets,
5124 session
5125 ->GetSocketPoolForSOCKSProxy(
5126 HttpNetworkSession::NORMAL_SOCKET_POOL,
5127 ProxyServer(ProxyServer::SCHEME_SOCKS4,
5128 SameProxyWithDifferentSchemesProxyResolver::
5129 ProxyHostPortPair()))
5130 ->IdleSocketCount());
5131 EXPECT_EQ(test_case.expected_idle_socks5_sockets,
5132 session
5133 ->GetSocketPoolForSOCKSProxy(
5134 HttpNetworkSession::NORMAL_SOCKET_POOL,
5135 ProxyServer(ProxyServer::SCHEME_SOCKS5,
5136 SameProxyWithDifferentSchemesProxyResolver::
5137 ProxyHostPortPair()))
5138 ->IdleSocketCount());
5139 EXPECT_EQ(test_case.expected_idle_http_sockets,
5140 session
5141 ->GetSocketPoolForHTTPLikeProxy(
5142 HttpNetworkSession::NORMAL_SOCKET_POOL,
5143 ProxyServer(ProxyServer::SCHEME_HTTP,
5144 SameProxyWithDifferentSchemesProxyResolver::
5145 ProxyHostPortPair()))
5146 ->IdleSocketCount());
5147 EXPECT_EQ(test_case.expected_idle_https_sockets,
5148 session
5149 ->GetSocketPoolForHTTPLikeProxy(
5150 HttpNetworkSession::NORMAL_SOCKET_POOL,
5151 ProxyServer(ProxyServer::SCHEME_HTTPS,
5152 SameProxyWithDifferentSchemesProxyResolver::
5153 ProxyHostPortPair()))
5154 ->IdleSocketCount());
5155 EXPECT_EQ(test_case.expected_idle_trusted_https_sockets,
5156 session
5157 ->GetSocketPoolForHTTPLikeProxy(
5158 HttpNetworkSession::NORMAL_SOCKET_POOL,
5159 ProxyServer(ProxyServer::SCHEME_HTTPS,
5160 SameProxyWithDifferentSchemesProxyResolver::
5161 ProxyHostPortPair(),
5162 true /* is_trusted_proxy */))
5163 ->IdleSocketCount());
Matt Menked1eb6d42018-01-17 04:54:065164 }
5165}
5166
[email protected]029c83b62013-01-24 05:28:205167// Test the load timing for HTTPS requests with an HTTP proxy.
bncd16676a2016-07-20 16:23:015168TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:205169 HttpRequestInfo request1;
5170 request1.method = "GET";
bncce36dca22015-04-21 22:11:235171 request1.url = GURL("https://www.example.org/1");
Ramin Halavatib5e433e2018-02-07 07:41:105172 request1.traffic_annotation =
5173 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:205174
5175 HttpRequestInfo request2;
5176 request2.method = "GET";
bncce36dca22015-04-21 22:11:235177 request2.url = GURL("https://www.example.org/2");
Ramin Halavatib5e433e2018-02-07 07:41:105178 request2.traffic_annotation =
5179 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:205180
5181 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495182 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5183 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515184 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075185 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095186 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:205187
5188 // Since we have proxy, should try to establish tunnel.
5189 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:175190 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5191 "Host: www.example.org:443\r\n"
5192 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205193
rsleevidb16bb02015-11-12 23:47:175194 MockWrite("GET /1 HTTP/1.1\r\n"
5195 "Host: www.example.org\r\n"
5196 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205197
rsleevidb16bb02015-11-12 23:47:175198 MockWrite("GET /2 HTTP/1.1\r\n"
5199 "Host: www.example.org\r\n"
5200 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205201 };
5202
5203 // The proxy responds to the connect with a 407, using a persistent
5204 // connection.
5205 MockRead data_reads1[] = {
5206 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
5207
5208 MockRead("HTTP/1.1 200 OK\r\n"),
5209 MockRead("Content-Length: 1\r\n\r\n"),
5210 MockRead(SYNCHRONOUS, "1"),
5211
5212 MockRead("HTTP/1.1 200 OK\r\n"),
5213 MockRead("Content-Length: 2\r\n\r\n"),
5214 MockRead(SYNCHRONOUS, "22"),
5215 };
5216
Ryan Sleevib8d7ea02018-05-07 20:01:015217 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:075218 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:205219 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075220 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:205221
5222 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:585223 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:195224 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:205225
5226 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015227 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:205228
5229 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015230 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:205231
5232 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:525233 ASSERT_TRUE(response1);
tbansal2ecbbc72016-10-06 17:15:475234 EXPECT_TRUE(response1->proxy_server.is_http());
wezca1070932016-05-26 20:30:525235 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:205236 EXPECT_EQ(1, response1->headers->GetContentLength());
5237
5238 LoadTimingInfo load_timing_info1;
5239 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
5240 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
5241
5242 trans1.reset();
5243
5244 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:585245 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:195246 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:205247
5248 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015249 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:205250
5251 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015252 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:205253
5254 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:525255 ASSERT_TRUE(response2);
tbansal2ecbbc72016-10-06 17:15:475256 EXPECT_TRUE(response2->proxy_server.is_http());
wezca1070932016-05-26 20:30:525257 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:205258 EXPECT_EQ(2, response2->headers->GetContentLength());
5259
5260 LoadTimingInfo load_timing_info2;
5261 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5262 TestLoadTimingReused(load_timing_info2);
5263
5264 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
5265
5266 trans2.reset();
5267 session->CloseAllConnections();
5268}
5269
5270// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
bncd16676a2016-07-20 16:23:015271TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:205272 HttpRequestInfo request1;
5273 request1.method = "GET";
bncce36dca22015-04-21 22:11:235274 request1.url = GURL("https://www.example.org/1");
Ramin Halavatib5e433e2018-02-07 07:41:105275 request1.traffic_annotation =
5276 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:205277
5278 HttpRequestInfo request2;
5279 request2.method = "GET";
bncce36dca22015-04-21 22:11:235280 request2.url = GURL("https://www.example.org/2");
Ramin Halavatib5e433e2018-02-07 07:41:105281 request2.traffic_annotation =
5282 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:205283
5284 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595285 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:495286 ProxyResolutionService::CreateFixedFromPacResult(
5287 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515288 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075289 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095290 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:205291
5292 // Since we have proxy, should try to establish tunnel.
5293 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:175294 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5295 "Host: www.example.org:443\r\n"
5296 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205297
rsleevidb16bb02015-11-12 23:47:175298 MockWrite("GET /1 HTTP/1.1\r\n"
5299 "Host: www.example.org\r\n"
5300 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205301
rsleevidb16bb02015-11-12 23:47:175302 MockWrite("GET /2 HTTP/1.1\r\n"
5303 "Host: www.example.org\r\n"
5304 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205305 };
5306
5307 // The proxy responds to the connect with a 407, using a persistent
5308 // connection.
5309 MockRead data_reads1[] = {
5310 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
5311
5312 MockRead("HTTP/1.1 200 OK\r\n"),
5313 MockRead("Content-Length: 1\r\n\r\n"),
5314 MockRead(SYNCHRONOUS, "1"),
5315
5316 MockRead("HTTP/1.1 200 OK\r\n"),
5317 MockRead("Content-Length: 2\r\n\r\n"),
5318 MockRead(SYNCHRONOUS, "22"),
5319 };
5320
Ryan Sleevib8d7ea02018-05-07 20:01:015321 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:075322 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:205323 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075324 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:205325
5326 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:585327 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:195328 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:205329
5330 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015331 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:205332
5333 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015334 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:205335
5336 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:525337 ASSERT_TRUE(response1);
5338 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:205339 EXPECT_EQ(1, response1->headers->GetContentLength());
5340
5341 LoadTimingInfo load_timing_info1;
5342 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
5343 TestLoadTimingNotReusedWithPac(load_timing_info1,
5344 CONNECT_TIMING_HAS_SSL_TIMES);
5345
5346 trans1.reset();
5347
5348 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:585349 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:195350 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:205351
5352 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015353 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:205354
5355 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015356 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:205357
5358 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:525359 ASSERT_TRUE(response2);
5360 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:205361 EXPECT_EQ(2, response2->headers->GetContentLength());
5362
5363 LoadTimingInfo load_timing_info2;
5364 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5365 TestLoadTimingReusedWithPac(load_timing_info2);
5366
5367 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
5368
5369 trans2.reset();
5370 session->CloseAllConnections();
5371}
5372
[email protected]2df19bb2010-08-25 20:13:465373// Test a simple get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015374TEST_F(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:275375 HttpRequestInfo request;
5376 request.method = "GET";
bncce36dca22015-04-21 22:11:235377 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105378 request.traffic_annotation =
5379 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275380
[email protected]2df19bb2010-08-25 20:13:465381 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495382 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5383 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515384 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075385 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095386 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:465387
[email protected]2df19bb2010-08-25 20:13:465388 // Since we have proxy, should use full url
5389 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235390 MockWrite(
5391 "GET http://www.example.org/ HTTP/1.1\r\n"
5392 "Host: www.example.org\r\n"
5393 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465394 };
5395
5396 MockRead data_reads1[] = {
5397 MockRead("HTTP/1.1 200 OK\r\n"),
5398 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5399 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065400 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:465401 };
5402
Ryan Sleevib8d7ea02018-05-07 20:01:015403 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:075404 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:065405 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075406 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:465407
[email protected]49639fa2011-12-20 23:22:415408 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:465409
bnc691fda62016-08-12 00:43:165410 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505411
bnc691fda62016-08-12 00:43:165412 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015413 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465414
5415 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015416 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465417
[email protected]58e32bb2013-01-21 18:23:255418 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165419 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255420 TestLoadTimingNotReused(load_timing_info,
5421 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5422
bnc691fda62016-08-12 00:43:165423 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525424 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:465425
tbansal2ecbbc72016-10-06 17:15:475426 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:465427 EXPECT_TRUE(response->headers->IsKeepAlive());
5428 EXPECT_EQ(200, response->headers->response_code());
5429 EXPECT_EQ(100, response->headers->GetContentLength());
5430 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5431
5432 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525433 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:465434}
5435
[email protected]7642b5ae2010-09-01 20:55:175436// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015437TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:275438 HttpRequestInfo request;
5439 request.method = "GET";
bncce36dca22015-04-21 22:11:235440 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105441 request.traffic_annotation =
5442 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275443
[email protected]7642b5ae2010-09-01 20:55:175444 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495445 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5446 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515447 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075448 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095449 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:175450
bncce36dca22015-04-21 22:11:235451 // fetch http://www.example.org/ via SPDY
Ryan Hamilton0239aac2018-05-19 00:03:135452 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:455453 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415454 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]7642b5ae2010-09-01 20:55:175455
Ryan Hamilton0239aac2018-05-19 00:03:135456 spdy::SpdySerializedFrame resp(
5457 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
5458 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:175459 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415460 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]7642b5ae2010-09-01 20:55:175461 };
5462
Ryan Sleevib8d7ea02018-05-07 20:01:015463 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075464 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:175465
[email protected]8ddf8322012-02-23 18:08:065466 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365467 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075468 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:175469
[email protected]49639fa2011-12-20 23:22:415470 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:175471
bnc691fda62016-08-12 00:43:165472 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505473
bnc691fda62016-08-12 00:43:165474 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015475 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7642b5ae2010-09-01 20:55:175476
5477 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015478 EXPECT_THAT(rv, IsOk());
[email protected]7642b5ae2010-09-01 20:55:175479
[email protected]58e32bb2013-01-21 18:23:255480 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165481 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255482 TestLoadTimingNotReused(load_timing_info,
5483 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5484
bnc691fda62016-08-12 00:43:165485 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525486 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:475487 EXPECT_TRUE(response->proxy_server.is_https());
wezca1070932016-05-26 20:30:525488 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025489 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]7642b5ae2010-09-01 20:55:175490
5491 std::string response_data;
bnc691fda62016-08-12 00:43:165492 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235493 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:175494}
5495
[email protected]1c173852014-06-19 12:51:505496// Verifies that a session which races and wins against the owning transaction
5497// (completing prior to host resolution), doesn't fail the transaction.
5498// Regression test for crbug.com/334413.
bncd16676a2016-07-20 16:23:015499TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
[email protected]1c173852014-06-19 12:51:505500 HttpRequestInfo request;
5501 request.method = "GET";
bncce36dca22015-04-21 22:11:235502 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105503 request.traffic_annotation =
5504 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c173852014-06-19 12:51:505505
5506 // Configure SPDY proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495507 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5508 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515509 BoundTestNetLog log;
[email protected]1c173852014-06-19 12:51:505510 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095511 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1c173852014-06-19 12:51:505512
bncce36dca22015-04-21 22:11:235513 // Fetch http://www.example.org/ through the SPDY proxy.
Ryan Hamilton0239aac2018-05-19 00:03:135514 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:455515 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415516 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]1c173852014-06-19 12:51:505517
Ryan Hamilton0239aac2018-05-19 00:03:135518 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
5519 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]1c173852014-06-19 12:51:505520 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415521 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]1c173852014-06-19 12:51:505522 };
5523
Ryan Sleevib8d7ea02018-05-07 20:01:015524 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]1c173852014-06-19 12:51:505525 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
5526
5527 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365528 ssl.next_proto = kProtoHTTP2;
[email protected]1c173852014-06-19 12:51:505529 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5530
5531 TestCompletionCallback callback1;
5532
bnc691fda62016-08-12 00:43:165533 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1c173852014-06-19 12:51:505534
5535 // Stall the hostname resolution begun by the transaction.
[email protected]1c173852014-06-19 12:51:505536 session_deps_.host_resolver->set_ondemand_mode(true);
5537
bnc691fda62016-08-12 00:43:165538 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015539 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c173852014-06-19 12:51:505540
5541 // Race a session to the proxy, which completes first.
5542 session_deps_.host_resolver->set_ondemand_mode(false);
Paul Jensena457017a2018-01-19 23:52:045543 SpdySessionKey key(HostPortPair("proxy", 70), ProxyServer::Direct(),
Matt Menke2436b2f2018-12-11 18:07:115544 PRIVACY_MODE_DISABLED,
5545 SpdySessionKey::IsProxySession::kTrue, SocketTag());
[email protected]1c173852014-06-19 12:51:505546 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:525547 CreateSpdySession(session.get(), key, log.bound());
[email protected]1c173852014-06-19 12:51:505548
5549 // Unstall the resolution begun by the transaction.
5550 session_deps_.host_resolver->set_ondemand_mode(true);
5551 session_deps_.host_resolver->ResolveAllPending();
5552
5553 EXPECT_FALSE(callback1.have_result());
5554 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015555 EXPECT_THAT(rv, IsOk());
[email protected]1c173852014-06-19 12:51:505556
bnc691fda62016-08-12 00:43:165557 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525558 ASSERT_TRUE(response);
5559 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025560 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]1c173852014-06-19 12:51:505561
5562 std::string response_data;
bnc691fda62016-08-12 00:43:165563 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]1c173852014-06-19 12:51:505564 EXPECT_EQ(kUploadData, response_data);
5565}
5566
[email protected]dc7bd1c52010-11-12 00:01:135567// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015568TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:275569 HttpRequestInfo request;
5570 request.method = "GET";
bncce36dca22015-04-21 22:11:235571 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105572 request.traffic_annotation =
5573 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275574
[email protected]79cb5c12011-09-12 13:12:045575 // Configure against https proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495576 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5577 "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515578 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075579 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095580 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:135581
[email protected]dc7bd1c52010-11-12 00:01:135582 // The first request will be a bare GET, the second request will be a
5583 // GET with a Proxy-Authorization header.
bncb26024382016-06-29 02:39:455584 spdy_util_.set_default_url(request.url);
Ryan Hamilton0239aac2018-05-19 00:03:135585 spdy::SpdySerializedFrame req_get(
Bence Béky27ad0a12018-02-08 00:35:485586 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:385587 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]dc7bd1c52010-11-12 00:01:135588 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:465589 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:135590 };
Ryan Hamilton0239aac2018-05-19 00:03:135591 spdy::SpdySerializedFrame req_get_authorization(spdy_util_.ConstructSpdyGet(
Avi Drissman4365a4782018-12-28 19:26:245592 kExtraAuthorizationHeaders, base::size(kExtraAuthorizationHeaders) / 2, 3,
Bence Béky27ad0a12018-02-08 00:35:485593 LOWEST));
[email protected]dc7bd1c52010-11-12 00:01:135594 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415595 CreateMockWrite(req_get, 0), CreateMockWrite(req_get_authorization, 3),
[email protected]dc7bd1c52010-11-12 00:01:135596 };
5597
5598 // The first response is a 407 proxy authentication challenge, and the second
5599 // response will be a 200 response since the second request includes a valid
5600 // Authorization header.
5601 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:465602 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:135603 };
Ryan Hamilton0239aac2018-05-19 00:03:135604 spdy::SpdySerializedFrame resp_authentication(
5605 spdy_util_.ConstructSpdyReplyError(
5606 "407", kExtraAuthenticationHeaders,
Avi Drissman4365a4782018-12-28 19:26:245607 base::size(kExtraAuthenticationHeaders) / 2, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135608 spdy::SpdySerializedFrame body_authentication(
bncdf80d44fd2016-07-15 20:27:415609 spdy_util_.ConstructSpdyDataFrame(1, true));
Ryan Hamilton0239aac2018-05-19 00:03:135610 spdy::SpdySerializedFrame resp_data(
5611 spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
5612 spdy::SpdySerializedFrame body_data(
5613 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:135614 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415615 CreateMockRead(resp_authentication, 1),
bnceb9aa7112017-01-05 01:03:465616 CreateMockRead(body_authentication, 2, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415617 CreateMockRead(resp_data, 4),
5618 CreateMockRead(body_data, 5),
rch8e6c6c42015-05-01 14:05:135619 MockRead(ASYNC, 0, 6),
[email protected]dc7bd1c52010-11-12 00:01:135620 };
5621
Ryan Sleevib8d7ea02018-05-07 20:01:015622 SequencedSocketData data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075623 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:135624
[email protected]8ddf8322012-02-23 18:08:065625 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365626 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075627 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:135628
[email protected]49639fa2011-12-20 23:22:415629 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:135630
bnc691fda62016-08-12 00:43:165631 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]dc7bd1c52010-11-12 00:01:135632
bnc691fda62016-08-12 00:43:165633 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015634 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:135635
5636 rv = callback1.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 = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:135640
wezca1070932016-05-26 20:30:525641 ASSERT_TRUE(response);
5642 ASSERT_TRUE(response->headers);
[email protected]dc7bd1c52010-11-12 00:01:135643 EXPECT_EQ(407, response->headers->response_code());
5644 EXPECT_TRUE(response->was_fetched_via_spdy);
asanka098c0092016-06-16 20:18:435645 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:135646
[email protected]49639fa2011-12-20 23:22:415647 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:135648
bnc691fda62016-08-12 00:43:165649 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015650 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:135651
5652 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015653 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:135654
bnc691fda62016-08-12 00:43:165655 const HttpResponseInfo* const response_restart = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:135656
wezca1070932016-05-26 20:30:525657 ASSERT_TRUE(response_restart);
5658 ASSERT_TRUE(response_restart->headers);
[email protected]dc7bd1c52010-11-12 00:01:135659 EXPECT_EQ(200, response_restart->headers->response_code());
5660 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525661 EXPECT_FALSE(response_restart->auth_challenge);
[email protected]dc7bd1c52010-11-12 00:01:135662}
5663
[email protected]d9da5fe2010-10-13 22:37:165664// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
bncd16676a2016-07-20 16:23:015665TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:275666 HttpRequestInfo request;
5667 request.method = "GET";
bncce36dca22015-04-21 22:11:235668 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105669 request.traffic_annotation =
5670 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275671
[email protected]d9da5fe2010-10-13 22:37:165672 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495673 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5674 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515675 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075676 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095677 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165678
bnc691fda62016-08-12 00:43:165679 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165680
bncce36dca22015-04-21 22:11:235681 // CONNECT to www.example.org:443 via SPDY
Ryan Hamilton0239aac2018-05-19 00:03:135682 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235683 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
5684 // fetch https://www.example.org/ via HTTP
[email protected]d9da5fe2010-10-13 22:37:165685
bncce36dca22015-04-21 22:11:235686 const char get[] =
5687 "GET / HTTP/1.1\r\n"
5688 "Host: www.example.org\r\n"
5689 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:135690 spdy::SpdySerializedFrame wrapped_get(
Bence Békyd74f4382018-02-20 18:26:195691 spdy_util_.ConstructSpdyDataFrame(1, get, false));
Ryan Hamilton0239aac2018-05-19 00:03:135692 spdy::SpdySerializedFrame conn_resp(
5693 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:165694 const char resp[] = "HTTP/1.1 200 OK\r\n"
5695 "Content-Length: 10\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:135696 spdy::SpdySerializedFrame wrapped_get_resp(
Bence Békyd74f4382018-02-20 18:26:195697 spdy_util_.ConstructSpdyDataFrame(1, resp, false));
Ryan Hamilton0239aac2018-05-19 00:03:135698 spdy::SpdySerializedFrame wrapped_body(
Bence Békyd74f4382018-02-20 18:26:195699 spdy_util_.ConstructSpdyDataFrame(1, "1234567890", false));
Ryan Hamilton0239aac2018-05-19 00:03:135700 spdy::SpdySerializedFrame window_update(
bncdf80d44fd2016-07-15 20:27:415701 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
[email protected]8d2f7012012-02-16 00:08:045702
5703 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415704 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
5705 CreateMockWrite(window_update, 6),
[email protected]8d2f7012012-02-16 00:08:045706 };
5707
[email protected]d9da5fe2010-10-13 22:37:165708 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415709 CreateMockRead(conn_resp, 1, ASYNC),
5710 CreateMockRead(wrapped_get_resp, 3, ASYNC),
5711 CreateMockRead(wrapped_body, 4, ASYNC),
5712 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:135713 MockRead(ASYNC, 0, 7),
[email protected]d9da5fe2010-10-13 22:37:165714 };
5715
Ryan Sleevib8d7ea02018-05-07 20:01:015716 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075717 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165718
[email protected]8ddf8322012-02-23 18:08:065719 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365720 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075721 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065722 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075723 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165724
[email protected]49639fa2011-12-20 23:22:415725 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165726
bnc691fda62016-08-12 00:43:165727 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015728 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165729
5730 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015731 ASSERT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:165732
[email protected]58e32bb2013-01-21 18:23:255733 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165734 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255735 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5736
bnc691fda62016-08-12 00:43:165737 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525738 ASSERT_TRUE(response);
5739 ASSERT_TRUE(response->headers);
[email protected]d9da5fe2010-10-13 22:37:165740 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5741
5742 std::string response_data;
bnc691fda62016-08-12 00:43:165743 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]d9da5fe2010-10-13 22:37:165744 EXPECT_EQ("1234567890", response_data);
5745}
5746
5747// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
bncd16676a2016-07-20 16:23:015748TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
5749 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:385750
[email protected]cb9bf6ca2011-01-28 13:15:275751 HttpRequestInfo request;
5752 request.method = "GET";
bncce36dca22015-04-21 22:11:235753 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105754 request.traffic_annotation =
5755 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275756
[email protected]d9da5fe2010-10-13 22:37:165757 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495758 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5759 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515760 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075761 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095762 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165763
bnc691fda62016-08-12 00:43:165764 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165765
bncce36dca22015-04-21 22:11:235766 // CONNECT to www.example.org:443 via SPDY
Ryan Hamilton0239aac2018-05-19 00:03:135767 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235768 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
5769 // fetch https://www.example.org/ via SPDY
5770 const char kMyUrl[] = "https://www.example.org/";
Ryan Hamilton0239aac2018-05-19 00:03:135771 spdy::SpdySerializedFrame get(
bnc38dcd392016-02-09 23:19:495772 spdy_util_wrapped.ConstructSpdyGet(kMyUrl, 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:135773 spdy::SpdySerializedFrame wrapped_get(
5774 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
5775 spdy::SpdySerializedFrame conn_resp(
5776 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
5777 spdy::SpdySerializedFrame get_resp(
bnc42331402016-07-25 13:36:155778 spdy_util_wrapped.ConstructSpdyGetReply(NULL, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135779 spdy::SpdySerializedFrame wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:025780 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135781 spdy::SpdySerializedFrame body(
5782 spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
5783 spdy::SpdySerializedFrame wrapped_body(
[email protected]23e482282013-06-14 16:08:025784 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135785 spdy::SpdySerializedFrame window_update_get_resp(
bncdf80d44fd2016-07-15 20:27:415786 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
Ryan Hamilton0239aac2018-05-19 00:03:135787 spdy::SpdySerializedFrame window_update_body(
bncdf80d44fd2016-07-15 20:27:415788 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
[email protected]8d2f7012012-02-16 00:08:045789
5790 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415791 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
5792 CreateMockWrite(window_update_get_resp, 6),
5793 CreateMockWrite(window_update_body, 7),
[email protected]8d2f7012012-02-16 00:08:045794 };
5795
[email protected]d9da5fe2010-10-13 22:37:165796 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415797 CreateMockRead(conn_resp, 1, ASYNC),
rch32320842015-05-16 15:57:095798 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:415799 CreateMockRead(wrapped_get_resp, 4, ASYNC),
5800 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:135801 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:165802 };
5803
Ryan Sleevib8d7ea02018-05-07 20:01:015804 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075805 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165806
[email protected]8ddf8322012-02-23 18:08:065807 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365808 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075809 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065810 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365811 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075812 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165813
[email protected]49639fa2011-12-20 23:22:415814 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165815
bnc691fda62016-08-12 00:43:165816 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015817 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165818
rch32320842015-05-16 15:57:095819 // Allow the SpdyProxyClientSocket's write callback to complete.
fdoray92e35a72016-06-10 15:54:555820 base::RunLoop().RunUntilIdle();
rch32320842015-05-16 15:57:095821 // Now allow the read of the response to complete.
mmenkee24011922015-12-17 22:12:595822 spdy_data.Resume();
[email protected]d9da5fe2010-10-13 22:37:165823 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015824 EXPECT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:165825
[email protected]58e32bb2013-01-21 18:23:255826 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165827 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255828 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5829
bnc691fda62016-08-12 00:43:165830 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525831 ASSERT_TRUE(response);
5832 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025833 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d9da5fe2010-10-13 22:37:165834
5835 std::string response_data;
bnc691fda62016-08-12 00:43:165836 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235837 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:165838}
5839
5840// Test a SPDY CONNECT failure through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015841TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:275842 HttpRequestInfo request;
5843 request.method = "GET";
bncce36dca22015-04-21 22:11:235844 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105845 request.traffic_annotation =
5846 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275847
[email protected]d9da5fe2010-10-13 22:37:165848 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495849 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5850 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515851 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075852 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095853 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165854
bnc691fda62016-08-12 00:43:165855 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165856
bncce36dca22015-04-21 22:11:235857 // CONNECT to www.example.org:443 via SPDY
Ryan Hamilton0239aac2018-05-19 00:03:135858 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235859 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:135860 spdy::SpdySerializedFrame get(
5861 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:165862
5863 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415864 CreateMockWrite(connect, 0), CreateMockWrite(get, 2),
[email protected]d9da5fe2010-10-13 22:37:165865 };
5866
Ryan Hamilton0239aac2018-05-19 00:03:135867 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(1));
5868 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:165869 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415870 CreateMockRead(resp, 1, ASYNC), MockRead(ASYNC, 0, 3),
[email protected]d9da5fe2010-10-13 22:37:165871 };
5872
Ryan Sleevib8d7ea02018-05-07 20:01:015873 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075874 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165875
[email protected]8ddf8322012-02-23 18:08:065876 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365877 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075878 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065879 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365880 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075881 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165882
[email protected]49639fa2011-12-20 23:22:415883 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165884
bnc691fda62016-08-12 00:43:165885 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015886 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165887
5888 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015889 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]d9da5fe2010-10-13 22:37:165890
ttuttle960fcbf2016-04-19 13:26:325891 // TODO(juliatuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:165892}
5893
Matt Menkecb2cd0982018-12-19 17:54:045894// Test the case where a proxied H2 session doesn't exist when an auth challenge
5895// is observed, but does exist by the time auth credentials are provided.
5896// Proxy-Connection: Close is used so that there's a second DNS lookup, which is
5897// what causes the existing H2 session to be noticed and reused.
5898TEST_F(HttpNetworkTransactionTest, ProxiedH2SessionAppearsDuringAuth) {
5899 ProxyConfig proxy_config;
5900 proxy_config.set_auto_detect(true);
5901 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
5902
5903 CapturingProxyResolver capturing_proxy_resolver;
5904 capturing_proxy_resolver.set_proxy_server(
5905 ProxyServer(ProxyServer::SCHEME_HTTP, HostPortPair("myproxy", 70)));
5906 session_deps_.proxy_resolution_service =
5907 std::make_unique<ProxyResolutionService>(
5908 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
5909 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
5910 std::make_unique<CapturingProxyResolverFactory>(
5911 &capturing_proxy_resolver),
5912 nullptr);
5913
5914 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
5915
5916 const char kMyUrl[] = "https://www.example.org/";
5917 spdy::SpdySerializedFrame get(spdy_util_.ConstructSpdyGet(kMyUrl, 1, LOWEST));
5918 spdy::SpdySerializedFrame get_resp(
5919 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
5920 spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
5921
5922 spdy_util_.UpdateWithStreamDestruction(1);
5923 spdy::SpdySerializedFrame get2(
5924 spdy_util_.ConstructSpdyGet(kMyUrl, 3, LOWEST));
5925 spdy::SpdySerializedFrame get_resp2(
5926 spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
5927 spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
5928
5929 MockWrite auth_challenge_writes[] = {
5930 MockWrite(ASYNC, 0,
5931 "CONNECT www.example.org:443 HTTP/1.1\r\n"
5932 "Host: www.example.org:443\r\n"
5933 "Proxy-Connection: keep-alive\r\n\r\n"),
5934 };
5935
5936 MockRead auth_challenge_reads[] = {
5937 MockRead(ASYNC, 1,
5938 "HTTP/1.1 407 Authentication Required\r\n"
5939 "Content-Length: 0\r\n"
5940 "Proxy-Connection: close\r\n"
5941 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
5942 };
5943
5944 MockWrite spdy_writes[] = {
5945 MockWrite(ASYNC, 0,
5946 "CONNECT www.example.org:443 HTTP/1.1\r\n"
5947 "Host: www.example.org:443\r\n"
5948 "Proxy-Connection: keep-alive\r\n"
5949 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5950 CreateMockWrite(get, 2),
5951 CreateMockWrite(get2, 5),
5952 };
5953
5954 MockRead spdy_reads[] = {
5955 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\n\r\n"),
5956 CreateMockRead(get_resp, 3, ASYNC),
5957 CreateMockRead(body, 4, ASYNC),
5958 CreateMockRead(get_resp2, 6, ASYNC),
5959 CreateMockRead(body2, 7, ASYNC),
5960
5961 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 8),
5962 };
5963
5964 SequencedSocketData auth_challenge1(auth_challenge_reads,
5965 auth_challenge_writes);
5966 session_deps_.socket_factory->AddSocketDataProvider(&auth_challenge1);
5967
5968 SequencedSocketData auth_challenge2(auth_challenge_reads,
5969 auth_challenge_writes);
5970 session_deps_.socket_factory->AddSocketDataProvider(&auth_challenge2);
5971
5972 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
5973 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
5974
5975 SSLSocketDataProvider ssl(ASYNC, OK);
5976 ssl.next_proto = kProtoHTTP2;
5977 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5978
5979 TestCompletionCallback callback;
5980 std::string response_data;
5981
5982 // Run first request until an auth challenge is observed.
5983 HttpRequestInfo request1;
5984 request1.method = "GET";
5985 request1.url = GURL(kMyUrl);
5986 request1.traffic_annotation =
5987 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5988 HttpNetworkTransaction trans1(LOWEST, session.get());
5989 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
5990 EXPECT_THAT(callback.GetResult(rv), IsOk());
5991 const HttpResponseInfo* response = trans1.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 // Run second request until an auth challenge is observed.
5999 HttpRequestInfo request2;
6000 request2.method = "GET";
6001 request2.url = GURL(kMyUrl);
6002 request2.traffic_annotation =
6003 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6004 HttpNetworkTransaction trans2(LOWEST, session.get());
6005 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
6006 EXPECT_THAT(callback.GetResult(rv), IsOk());
6007 response = trans2.GetResponseInfo();
6008 ASSERT_TRUE(response);
6009 ASSERT_TRUE(response->headers);
6010 EXPECT_EQ(407, response->headers->response_code());
6011 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6012 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
6013
6014 // Now provide credentials for the first request, and wait for it to complete.
6015 rv = trans1.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
6016 rv = callback.GetResult(rv);
6017 EXPECT_THAT(rv, IsOk());
6018 response = trans1.GetResponseInfo();
6019 ASSERT_TRUE(response);
6020 ASSERT_TRUE(response->headers);
6021 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
6022 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
6023 EXPECT_EQ(kUploadData, response_data);
6024
6025 // Now provide credentials for the second request. It should notice the
6026 // existing session, and reuse it.
6027 rv = trans2.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
6028 EXPECT_THAT(callback.GetResult(rv), IsOk());
6029 response = trans2.GetResponseInfo();
6030 ASSERT_TRUE(response);
6031 ASSERT_TRUE(response->headers);
6032 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
6033 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
6034 EXPECT_EQ(kUploadData, response_data);
6035}
6036
[email protected]f6c63db52013-02-02 00:35:226037// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
6038// HTTPS Proxy to different servers.
bncd16676a2016-07-20 16:23:016039TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:226040 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
6041 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496042 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6043 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:516044 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076045 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:096046 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:506047 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:226048
6049 HttpRequestInfo request1;
6050 request1.method = "GET";
bncce36dca22015-04-21 22:11:236051 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:226052 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:106053 request1.traffic_annotation =
6054 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226055
6056 HttpRequestInfo request2;
6057 request2.method = "GET";
bncce36dca22015-04-21 22:11:236058 request2.url = GURL("https://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:226059 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:106060 request2.traffic_annotation =
6061 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226062
bncce36dca22015-04-21 22:11:236063 // CONNECT to www.example.org:443 via SPDY.
Ryan Hamilton0239aac2018-05-19 00:03:136064 spdy::SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:236065 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:136066 spdy::SpdySerializedFrame conn_resp1(
6067 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:226068
bncce36dca22015-04-21 22:11:236069 // Fetch https://www.example.org/ via HTTP.
6070 const char get1[] =
6071 "GET / HTTP/1.1\r\n"
6072 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:226073 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136074 spdy::SpdySerializedFrame wrapped_get1(
Bence Békyd74f4382018-02-20 18:26:196075 spdy_util_.ConstructSpdyDataFrame(1, get1, false));
[email protected]f6c63db52013-02-02 00:35:226076 const char resp1[] = "HTTP/1.1 200 OK\r\n"
6077 "Content-Length: 1\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136078 spdy::SpdySerializedFrame wrapped_get_resp1(
Bence Békyd74f4382018-02-20 18:26:196079 spdy_util_.ConstructSpdyDataFrame(1, resp1, false));
Ryan Hamilton0239aac2018-05-19 00:03:136080 spdy::SpdySerializedFrame wrapped_body1(
Bence Békyd74f4382018-02-20 18:26:196081 spdy_util_.ConstructSpdyDataFrame(1, "1", false));
Ryan Hamilton0239aac2018-05-19 00:03:136082 spdy::SpdySerializedFrame window_update(
bncdf80d44fd2016-07-15 20:27:416083 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:226084
bncce36dca22015-04-21 22:11:236085 // CONNECT to mail.example.org:443 via SPDY.
Ryan Hamilton0239aac2018-05-19 00:03:136086 spdy::SpdyHeaderBlock connect2_block;
6087 connect2_block[spdy::kHttp2MethodHeader] = "CONNECT";
6088 connect2_block[spdy::kHttp2AuthorityHeader] = "mail.example.org:443";
6089 spdy::SpdySerializedFrame connect2(spdy_util_.ConstructSpdyHeaders(
bnc42331402016-07-25 13:36:156090 3, std::move(connect2_block), LOWEST, false));
[email protected]601e03f12014-04-06 16:26:396091
Ryan Hamilton0239aac2018-05-19 00:03:136092 spdy::SpdySerializedFrame conn_resp2(
6093 spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:226094
bncce36dca22015-04-21 22:11:236095 // Fetch https://mail.example.org/ via HTTP.
6096 const char get2[] =
6097 "GET / HTTP/1.1\r\n"
6098 "Host: mail.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:226099 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136100 spdy::SpdySerializedFrame wrapped_get2(
Bence Békyd74f4382018-02-20 18:26:196101 spdy_util_.ConstructSpdyDataFrame(3, get2, false));
[email protected]f6c63db52013-02-02 00:35:226102 const char resp2[] = "HTTP/1.1 200 OK\r\n"
6103 "Content-Length: 2\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136104 spdy::SpdySerializedFrame wrapped_get_resp2(
Bence Békyd74f4382018-02-20 18:26:196105 spdy_util_.ConstructSpdyDataFrame(3, resp2, false));
Ryan Hamilton0239aac2018-05-19 00:03:136106 spdy::SpdySerializedFrame wrapped_body2(
Bence Békyd74f4382018-02-20 18:26:196107 spdy_util_.ConstructSpdyDataFrame(3, "22", false));
[email protected]f6c63db52013-02-02 00:35:226108
6109 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:416110 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
6111 CreateMockWrite(connect2, 5), CreateMockWrite(wrapped_get2, 7),
[email protected]f6c63db52013-02-02 00:35:226112 };
6113
6114 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:416115 CreateMockRead(conn_resp1, 1, ASYNC),
6116 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
6117 CreateMockRead(wrapped_body1, 4, ASYNC),
6118 CreateMockRead(conn_resp2, 6, ASYNC),
6119 CreateMockRead(wrapped_get_resp2, 8, ASYNC),
6120 CreateMockRead(wrapped_body2, 9, ASYNC),
6121 MockRead(ASYNC, 0, 10),
[email protected]f6c63db52013-02-02 00:35:226122 };
6123
Ryan Sleevib8d7ea02018-05-07 20:01:016124 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
mmenke11eb5152015-06-09 14:50:506125 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:226126
6127 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:366128 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:506129 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:226130 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:506131 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:226132 SSLSocketDataProvider ssl3(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:506133 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:226134
6135 TestCompletionCallback callback;
6136
bnc691fda62016-08-12 00:43:166137 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206138 int rv = trans.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016139 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:226140
6141 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:166142 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]f6c63db52013-02-02 00:35:226143 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
6144
bnc691fda62016-08-12 00:43:166145 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526146 ASSERT_TRUE(response);
6147 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:226148 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6149
6150 std::string response_data;
Victor Costan9c7302b2018-08-27 16:39:446151 scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(256);
bnc691fda62016-08-12 00:43:166152 rv = trans.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:506153 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:226154
bnc691fda62016-08-12 00:43:166155 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206156 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016157 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:226158
6159 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:166160 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:226161 // Even though the SPDY connection is reused, a new tunnelled connection has
6162 // to be created, so the socket's load timing looks like a fresh connection.
6163 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
6164
6165 // The requests should have different IDs, since they each are using their own
6166 // separate stream.
6167 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
6168
bnc691fda62016-08-12 00:43:166169 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:506170 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:226171}
6172
6173// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
6174// HTTPS Proxy to the same server.
bncd16676a2016-07-20 16:23:016175TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:226176 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
6177 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496178 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6179 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:516180 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076181 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:096182 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:506183 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:226184
6185 HttpRequestInfo request1;
6186 request1.method = "GET";
bncce36dca22015-04-21 22:11:236187 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:226188 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:106189 request1.traffic_annotation =
6190 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226191
6192 HttpRequestInfo request2;
6193 request2.method = "GET";
bncce36dca22015-04-21 22:11:236194 request2.url = GURL("https://www.example.org/2");
[email protected]f6c63db52013-02-02 00:35:226195 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:106196 request2.traffic_annotation =
6197 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226198
bncce36dca22015-04-21 22:11:236199 // CONNECT to www.example.org:443 via SPDY.
Ryan Hamilton0239aac2018-05-19 00:03:136200 spdy::SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:236201 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:136202 spdy::SpdySerializedFrame conn_resp1(
6203 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:226204
bncce36dca22015-04-21 22:11:236205 // Fetch https://www.example.org/ via HTTP.
6206 const char get1[] =
6207 "GET / 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_get1(
Bence Békyd74f4382018-02-20 18:26:196211 spdy_util_.ConstructSpdyDataFrame(1, get1, false));
[email protected]f6c63db52013-02-02 00:35:226212 const char resp1[] = "HTTP/1.1 200 OK\r\n"
6213 "Content-Length: 1\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136214 spdy::SpdySerializedFrame wrapped_get_resp1(
Bence Békyd74f4382018-02-20 18:26:196215 spdy_util_.ConstructSpdyDataFrame(1, resp1, false));
Ryan Hamilton0239aac2018-05-19 00:03:136216 spdy::SpdySerializedFrame wrapped_body1(
Bence Békyd74f4382018-02-20 18:26:196217 spdy_util_.ConstructSpdyDataFrame(1, "1", false));
Ryan Hamilton0239aac2018-05-19 00:03:136218 spdy::SpdySerializedFrame window_update(
bncdf80d44fd2016-07-15 20:27:416219 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:226220
bncce36dca22015-04-21 22:11:236221 // Fetch https://www.example.org/2 via HTTP.
6222 const char get2[] =
6223 "GET /2 HTTP/1.1\r\n"
6224 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:226225 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136226 spdy::SpdySerializedFrame wrapped_get2(
Bence Békyd74f4382018-02-20 18:26:196227 spdy_util_.ConstructSpdyDataFrame(1, get2, false));
[email protected]f6c63db52013-02-02 00:35:226228 const char resp2[] = "HTTP/1.1 200 OK\r\n"
6229 "Content-Length: 2\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136230 spdy::SpdySerializedFrame wrapped_get_resp2(
Bence Békyd74f4382018-02-20 18:26:196231 spdy_util_.ConstructSpdyDataFrame(1, resp2, false));
Ryan Hamilton0239aac2018-05-19 00:03:136232 spdy::SpdySerializedFrame wrapped_body2(
Bence Békyd74f4382018-02-20 18:26:196233 spdy_util_.ConstructSpdyDataFrame(1, "22", false));
[email protected]f6c63db52013-02-02 00:35:226234
6235 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:416236 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
6237 CreateMockWrite(wrapped_get2, 5),
[email protected]f6c63db52013-02-02 00:35:226238 };
6239
6240 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:416241 CreateMockRead(conn_resp1, 1, ASYNC),
6242 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
bnceb9aa7112017-01-05 01:03:466243 CreateMockRead(wrapped_body1, 4, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:416244 CreateMockRead(wrapped_get_resp2, 6, ASYNC),
bnceb9aa7112017-01-05 01:03:466245 CreateMockRead(wrapped_body2, 7, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:416246 MockRead(ASYNC, 0, 8),
[email protected]f6c63db52013-02-02 00:35:226247 };
6248
Ryan Sleevib8d7ea02018-05-07 20:01:016249 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
mmenke11eb5152015-06-09 14:50:506250 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:226251
6252 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:366253 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:506254 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:226255 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:506256 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:226257
6258 TestCompletionCallback callback;
6259
bnc87dcefc2017-05-25 12:47:586260 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:196261 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206262 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016263 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:226264
6265 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016266 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:226267
6268 LoadTimingInfo load_timing_info;
6269 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6270 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
6271
6272 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526273 ASSERT_TRUE(response);
6274 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:226275 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6276
6277 std::string response_data;
Victor Costan9c7302b2018-08-27 16:39:446278 scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(256);
[email protected]90499482013-06-01 00:39:506279 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:226280 trans.reset();
6281
bnc87dcefc2017-05-25 12:47:586282 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:196283 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206284 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016285 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:226286
[email protected]f6c63db52013-02-02 00:35:226287 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016288 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:226289
6290 LoadTimingInfo load_timing_info2;
6291 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
6292 TestLoadTimingReused(load_timing_info2);
6293
6294 // The requests should have the same ID.
6295 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
6296
[email protected]90499482013-06-01 00:39:506297 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:226298}
6299
6300// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
6301// Proxy to different servers.
bncd16676a2016-07-20 16:23:016302TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) {
[email protected]f6c63db52013-02-02 00:35:226303 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496304 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6305 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:516306 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076307 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:096308 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:506309 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:226310
6311 HttpRequestInfo request1;
6312 request1.method = "GET";
bncce36dca22015-04-21 22:11:236313 request1.url = GURL("http://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:226314 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:106315 request1.traffic_annotation =
6316 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226317
6318 HttpRequestInfo request2;
6319 request2.method = "GET";
bncce36dca22015-04-21 22:11:236320 request2.url = GURL("http://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:226321 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:106322 request2.traffic_annotation =
6323 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226324
bncce36dca22015-04-21 22:11:236325 // http://www.example.org/
Ryan Hamilton0239aac2018-05-19 00:03:136326 spdy::SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:236327 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
Ryan Hamilton0239aac2018-05-19 00:03:136328 spdy::SpdySerializedFrame get1(
bnc42331402016-07-25 13:36:156329 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
Ryan Hamilton0239aac2018-05-19 00:03:136330 spdy::SpdySerializedFrame get_resp1(
6331 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
6332 spdy::SpdySerializedFrame body1(
6333 spdy_util_.ConstructSpdyDataFrame(1, "1", true));
rdsmithebb50aa2015-11-12 03:44:386334 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]f6c63db52013-02-02 00:35:226335
bncce36dca22015-04-21 22:11:236336 // http://mail.example.org/
Ryan Hamilton0239aac2018-05-19 00:03:136337 spdy::SpdyHeaderBlock headers2(
bncce36dca22015-04-21 22:11:236338 spdy_util_.ConstructGetHeaderBlockForProxy("http://mail.example.org/"));
Ryan Hamilton0239aac2018-05-19 00:03:136339 spdy::SpdySerializedFrame get2(
bnc42331402016-07-25 13:36:156340 spdy_util_.ConstructSpdyHeaders(3, std::move(headers2), LOWEST, true));
Ryan Hamilton0239aac2018-05-19 00:03:136341 spdy::SpdySerializedFrame get_resp2(
6342 spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
6343 spdy::SpdySerializedFrame body2(
6344 spdy_util_.ConstructSpdyDataFrame(3, "22", true));
[email protected]f6c63db52013-02-02 00:35:226345
6346 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:416347 CreateMockWrite(get1, 0), CreateMockWrite(get2, 3),
[email protected]f6c63db52013-02-02 00:35:226348 };
6349
6350 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:416351 CreateMockRead(get_resp1, 1, ASYNC),
6352 CreateMockRead(body1, 2, ASYNC),
6353 CreateMockRead(get_resp2, 4, ASYNC),
6354 CreateMockRead(body2, 5, ASYNC),
6355 MockRead(ASYNC, 0, 6),
[email protected]f6c63db52013-02-02 00:35:226356 };
6357
Ryan Sleevib8d7ea02018-05-07 20:01:016358 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
mmenke11eb5152015-06-09 14:50:506359 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:226360
6361 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:366362 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:506363 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:226364
6365 TestCompletionCallback callback;
6366
bnc87dcefc2017-05-25 12:47:586367 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:196368 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206369 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016370 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:226371
6372 LoadTimingInfo load_timing_info;
6373 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6374 TestLoadTimingNotReused(load_timing_info,
6375 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6376
6377 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526378 ASSERT_TRUE(response);
6379 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:026380 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]f6c63db52013-02-02 00:35:226381
6382 std::string response_data;
Victor Costan9c7302b2018-08-27 16:39:446383 scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(256);
mmenke11eb5152015-06-09 14:50:506384 rv = trans->Read(buf.get(), 256, callback.callback());
6385 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:226386 // Delete the first request, so the second one can reuse the socket.
6387 trans.reset();
6388
bnc691fda62016-08-12 00:43:166389 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206390 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016391 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:226392
6393 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:166394 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:226395 TestLoadTimingReused(load_timing_info2);
6396
6397 // The requests should have the same ID.
6398 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
6399
bnc691fda62016-08-12 00:43:166400 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:506401 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:226402}
6403
Matt Menke2436b2f2018-12-11 18:07:116404// Test that an HTTP/2 CONNECT through an HTTPS Proxy to a HTTP/2 server and a
6405// direct (non-proxied) request to the proxy server are not pooled, as that
6406// would break socket pool isolation.
6407TEST_F(HttpNetworkTransactionTest, SpdyProxyIsolation1) {
6408 ProxyConfig proxy_config;
6409 proxy_config.set_auto_detect(true);
6410 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
6411
6412 CapturingProxyResolver capturing_proxy_resolver;
6413 session_deps_.proxy_resolution_service =
6414 std::make_unique<ProxyResolutionService>(
6415 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
6416 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
6417 std::make_unique<CapturingProxyResolverFactory>(
6418 &capturing_proxy_resolver),
6419 nullptr);
6420
6421 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6422
6423 SpdyTestUtil spdy_util1;
6424 // CONNECT to www.example.org:443 via HTTP/2.
6425 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
6426 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
6427 // fetch https://www.example.org/ via HTTP/2.
6428 const char kMyUrl[] = "https://www.example.org/";
6429 spdy::SpdySerializedFrame get(spdy_util1.ConstructSpdyGet(kMyUrl, 1, LOWEST));
6430 spdy::SpdySerializedFrame wrapped_get(
6431 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
6432 spdy::SpdySerializedFrame conn_resp(
6433 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
6434 spdy::SpdySerializedFrame get_resp(
6435 spdy_util1.ConstructSpdyGetReply(NULL, 0, 1));
6436 spdy::SpdySerializedFrame wrapped_get_resp(
6437 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
6438 spdy::SpdySerializedFrame body(spdy_util1.ConstructSpdyDataFrame(1, true));
6439 spdy::SpdySerializedFrame wrapped_body(
6440 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
6441 spdy::SpdySerializedFrame window_update_get_resp(
6442 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
6443 spdy::SpdySerializedFrame window_update_body(
6444 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
6445
6446 MockWrite spdy_writes1[] = {
6447 CreateMockWrite(connect, 0),
6448 CreateMockWrite(wrapped_get, 2),
6449 CreateMockWrite(window_update_get_resp, 6),
6450 CreateMockWrite(window_update_body, 7),
6451 };
6452
6453 MockRead spdy_reads1[] = {
6454 CreateMockRead(conn_resp, 1, ASYNC),
6455 MockRead(ASYNC, ERR_IO_PENDING, 3),
6456 CreateMockRead(wrapped_get_resp, 4, ASYNC),
6457 CreateMockRead(wrapped_body, 5, ASYNC),
6458 MockRead(ASYNC, 0, 8),
6459 };
6460
6461 SequencedSocketData spdy_data1(spdy_reads1, spdy_writes1);
6462 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data1);
6463
6464 // Fetch https://proxy:70/ via HTTP/2. Needs a new SpdyTestUtil, since it uses
6465 // a new pipe.
6466 SpdyTestUtil spdy_util2;
6467 spdy::SpdySerializedFrame req(
6468 spdy_util2.ConstructSpdyGet("https://proxy:70/", 1, LOWEST));
6469 MockWrite spdy_writes2[] = {CreateMockWrite(req, 0)};
6470
6471 spdy::SpdySerializedFrame resp(
6472 spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
6473 spdy::SpdySerializedFrame data(spdy_util2.ConstructSpdyDataFrame(1, true));
6474 MockRead spdy_reads2[] = {
6475 CreateMockRead(resp, 1),
6476 CreateMockRead(data, 2),
6477 MockRead(ASYNC, 0, 3),
6478 };
6479 SequencedSocketData spdy_data2(spdy_reads2, spdy_writes2);
6480 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data2);
6481
6482 SSLSocketDataProvider ssl(ASYNC, OK);
6483 ssl.next_proto = kProtoHTTP2;
6484 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6485 SSLSocketDataProvider ssl2(ASYNC, OK);
6486 ssl2.next_proto = kProtoHTTP2;
6487 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6488 SSLSocketDataProvider ssl3(ASYNC, OK);
6489 ssl3.next_proto = kProtoHTTP2;
6490 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
6491
6492 TestCompletionCallback callback;
6493 std::string response_data;
6494
6495 // Make a request using proxy:70 as a HTTP/2 proxy.
6496 capturing_proxy_resolver.set_proxy_server(
6497 ProxyServer(ProxyServer::SCHEME_HTTPS, HostPortPair("proxy", 70)));
6498 HttpRequestInfo request1;
6499 request1.method = "GET";
6500 request1.url = GURL("https://www.example.org/");
6501 request1.traffic_annotation =
6502 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6503
6504 HttpNetworkTransaction trans1(LOWEST, session.get());
6505 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
6506 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6507
6508 // Allow the SpdyProxyClientSocket's write callback to complete.
6509 base::RunLoop().RunUntilIdle();
6510 // Now allow the read of the response to complete.
6511 spdy_data1.Resume();
6512 rv = callback.WaitForResult();
6513 EXPECT_THAT(rv, IsOk());
6514
6515 const HttpResponseInfo* response = trans1.GetResponseInfo();
6516 ASSERT_TRUE(response);
6517 ASSERT_TRUE(response->headers);
6518 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
6519
6520 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
6521 EXPECT_EQ(kUploadData, response_data);
6522 RunUntilIdle();
6523
6524 // Make a direct HTTP/2 request to proxy:70.
6525 capturing_proxy_resolver.set_proxy_server(ProxyServer::Direct());
6526 HttpRequestInfo request2;
6527 request2.method = "GET";
6528 request2.url = GURL("https://proxy:70/");
6529 request2.traffic_annotation =
6530 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6531 HttpNetworkTransaction trans2(LOWEST, session.get());
6532 EXPECT_THAT(callback.GetResult(trans2.Start(&request2, callback.callback(),
6533 NetLogWithSource())),
6534 IsOk());
6535 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
6536}
6537
6538// Same as above, but reverse request order, since the code to check for an
6539// existing session is different for tunnels and direct connections.
6540TEST_F(HttpNetworkTransactionTest, SpdyProxyIsolation2) {
6541 // Configure against https proxy server "myproxy:80".
6542 ProxyConfig proxy_config;
6543 proxy_config.set_auto_detect(true);
6544 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
6545
6546 CapturingProxyResolver capturing_proxy_resolver;
6547 session_deps_.proxy_resolution_service =
6548 std::make_unique<ProxyResolutionService>(
6549 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
6550 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
6551 std::make_unique<CapturingProxyResolverFactory>(
6552 &capturing_proxy_resolver),
6553 nullptr);
6554
6555 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6556 // Fetch https://proxy:70/ via HTTP/2.
6557 SpdyTestUtil spdy_util1;
6558 spdy::SpdySerializedFrame req(
6559 spdy_util1.ConstructSpdyGet("https://proxy:70/", 1, LOWEST));
6560 MockWrite spdy_writes1[] = {CreateMockWrite(req, 0)};
6561
6562 spdy::SpdySerializedFrame resp(
6563 spdy_util1.ConstructSpdyGetReply(nullptr, 0, 1));
6564 spdy::SpdySerializedFrame data(spdy_util1.ConstructSpdyDataFrame(1, true));
6565 MockRead spdy_reads1[] = {
6566 CreateMockRead(resp, 1),
6567 CreateMockRead(data, 2),
6568 MockRead(ASYNC, 0, 3),
6569 };
6570 SequencedSocketData spdy_data1(spdy_reads1, spdy_writes1);
6571 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data1);
6572
6573 SpdyTestUtil spdy_util2;
6574 // CONNECT to www.example.org:443 via HTTP/2.
6575 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
6576 nullptr, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
6577 // fetch https://www.example.org/ via HTTP/2.
6578 const char kMyUrl[] = "https://www.example.org/";
6579 spdy::SpdySerializedFrame get(spdy_util2.ConstructSpdyGet(kMyUrl, 1, LOWEST));
6580 spdy::SpdySerializedFrame wrapped_get(
6581 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
6582 spdy::SpdySerializedFrame conn_resp(
6583 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
6584 spdy::SpdySerializedFrame get_resp(
6585 spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
6586 spdy::SpdySerializedFrame wrapped_get_resp(
6587 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
6588 spdy::SpdySerializedFrame body(spdy_util2.ConstructSpdyDataFrame(1, true));
6589 spdy::SpdySerializedFrame wrapped_body(
6590 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
6591 spdy::SpdySerializedFrame window_update_get_resp(
6592 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
6593 spdy::SpdySerializedFrame window_update_body(
6594 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
6595
6596 MockWrite spdy_writes2[] = {
6597 CreateMockWrite(connect, 0),
6598 CreateMockWrite(wrapped_get, 2),
6599 CreateMockWrite(window_update_get_resp, 6),
6600 CreateMockWrite(window_update_body, 7),
6601 };
6602
6603 MockRead spdy_reads2[] = {
6604 CreateMockRead(conn_resp, 1, ASYNC),
6605 MockRead(ASYNC, ERR_IO_PENDING, 3),
6606 CreateMockRead(wrapped_get_resp, 4, ASYNC),
6607 CreateMockRead(wrapped_body, 5, ASYNC),
6608 MockRead(ASYNC, 0, 8),
6609 };
6610
6611 SequencedSocketData spdy_data2(spdy_reads2, spdy_writes2);
6612 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data2);
6613
6614 SSLSocketDataProvider ssl(ASYNC, OK);
6615 ssl.next_proto = kProtoHTTP2;
6616 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6617 SSLSocketDataProvider ssl2(ASYNC, OK);
6618 ssl2.next_proto = kProtoHTTP2;
6619 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6620 SSLSocketDataProvider ssl3(ASYNC, OK);
6621 ssl3.next_proto = kProtoHTTP2;
6622 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
6623
6624 TestCompletionCallback callback;
6625 std::string response_data;
6626
6627 // Make a direct HTTP/2 request to proxy:70.
6628 capturing_proxy_resolver.set_proxy_server(ProxyServer::Direct());
6629 HttpRequestInfo request1;
6630 request1.method = "GET";
6631 request1.url = GURL("https://proxy:70/");
6632 request1.traffic_annotation =
6633 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6634 HttpNetworkTransaction trans1(LOWEST, session.get());
6635 EXPECT_THAT(callback.GetResult(trans1.Start(&request1, callback.callback(),
6636 NetLogWithSource())),
6637 IsOk());
6638 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
6639 RunUntilIdle();
6640
6641 // Make a request using proxy:70 as a HTTP/2 proxy.
6642 capturing_proxy_resolver.set_proxy_server(
6643 ProxyServer(ProxyServer::SCHEME_HTTPS, HostPortPair("proxy", 70)));
6644 HttpRequestInfo request2;
6645 request2.method = "GET";
6646 request2.url = GURL("https://www.example.org/");
6647 request2.traffic_annotation =
6648 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6649
6650 HttpNetworkTransaction trans2(LOWEST, session.get());
6651 int rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
6652 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6653
6654 // Allow the SpdyProxyClientSocket's write callback to complete.
6655 base::RunLoop().RunUntilIdle();
6656 // Now allow the read of the response to complete.
6657 spdy_data2.Resume();
6658 rv = callback.WaitForResult();
6659 EXPECT_THAT(rv, IsOk());
6660
6661 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
6662 ASSERT_TRUE(response2);
6663 ASSERT_TRUE(response2->headers);
6664 EXPECT_EQ("HTTP/1.1 200", response2->headers->GetStatusLine());
6665
6666 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
6667 EXPECT_EQ(kUploadData, response_data);
6668}
6669
[email protected]2df19bb2010-08-25 20:13:466670// Test the challenge-response-retry sequence through an HTTPS Proxy
bncd16676a2016-07-20 16:23:016671TEST_F(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:466672 HttpRequestInfo request;
6673 request.method = "GET";
bncce36dca22015-04-21 22:11:236674 request.url = GURL("http://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:466675 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:296676 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:106677 request.traffic_annotation =
6678 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:466679
[email protected]79cb5c12011-09-12 13:12:046680 // Configure against https proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496681 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6682 "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:516683 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076684 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:096685 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276686
[email protected]2df19bb2010-08-25 20:13:466687 // Since we have proxy, should use full url
6688 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:166689 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
6690 "Host: www.example.org\r\n"
6691 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:466692
bnc691fda62016-08-12 00:43:166693 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:236694 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:166695 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
6696 "Host: www.example.org\r\n"
6697 "Proxy-Connection: keep-alive\r\n"
6698 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:466699 };
6700
6701 // The proxy responds to the GET with a 407, using a persistent
6702 // connection.
6703 MockRead data_reads1[] = {
6704 // No credentials.
6705 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
6706 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6707 MockRead("Proxy-Connection: keep-alive\r\n"),
6708 MockRead("Content-Length: 0\r\n\r\n"),
6709
6710 MockRead("HTTP/1.1 200 OK\r\n"),
6711 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6712 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066713 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:466714 };
6715
Ryan Sleevib8d7ea02018-05-07 20:01:016716 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:076717 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:066718 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076719 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:466720
[email protected]49639fa2011-12-20 23:22:416721 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:466722
bnc691fda62016-08-12 00:43:166723 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506724
bnc691fda62016-08-12 00:43:166725 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:016726 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:466727
6728 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016729 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:466730
[email protected]58e32bb2013-01-21 18:23:256731 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:166732 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:256733 TestLoadTimingNotReused(load_timing_info,
6734 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6735
bnc691fda62016-08-12 00:43:166736 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526737 ASSERT_TRUE(response);
6738 ASSERT_TRUE(response->headers);
[email protected]2df19bb2010-08-25 20:13:466739 EXPECT_EQ(407, response->headers->response_code());
6740 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
asanka098c0092016-06-16 20:18:436741 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:466742
[email protected]49639fa2011-12-20 23:22:416743 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:466744
bnc691fda62016-08-12 00:43:166745 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:016746 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:466747
6748 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016749 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:466750
[email protected]58e32bb2013-01-21 18:23:256751 load_timing_info = LoadTimingInfo();
bnc691fda62016-08-12 00:43:166752 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:256753 // Retrying with HTTP AUTH is considered to be reusing a socket.
6754 TestLoadTimingReused(load_timing_info);
6755
bnc691fda62016-08-12 00:43:166756 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526757 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:466758
6759 EXPECT_TRUE(response->headers->IsKeepAlive());
6760 EXPECT_EQ(200, response->headers->response_code());
6761 EXPECT_EQ(100, response->headers->GetContentLength());
6762 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6763
6764 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:526765 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:466766}
6767
[email protected]23e482282013-06-14 16:08:026768void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:086769 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:426770 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:086771 request.method = "GET";
bncce36dca22015-04-21 22:11:236772 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:106773 request.traffic_annotation =
6774 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]c744cf22009-02-27 07:28:086775
[email protected]cb9bf6ca2011-01-28 13:15:276776 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496777 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6778 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:096779 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276780
[email protected]c744cf22009-02-27 07:28:086781 // Since we have proxy, should try to establish tunnel.
6782 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:176783 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
6784 "Host: www.example.org:443\r\n"
6785 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:086786 };
6787
6788 MockRead data_reads[] = {
mmenked39192ee2015-12-09 00:57:236789 status, MockRead("Content-Length: 10\r\n\r\n"),
6790 // No response body because the test stops reading here.
6791 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]c744cf22009-02-27 07:28:086792 };
6793
Ryan Sleevib8d7ea02018-05-07 20:01:016794 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:076795 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:086796
[email protected]49639fa2011-12-20 23:22:416797 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:086798
bnc691fda62016-08-12 00:43:166799 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506800
tfarina42834112016-09-22 13:38:206801 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016802 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]c744cf22009-02-27 07:28:086803
6804 rv = callback.WaitForResult();
6805 EXPECT_EQ(expected_status, rv);
6806}
6807
[email protected]23e482282013-06-14 16:08:026808void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:236809 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:086810 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:426811 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:086812}
6813
bncd16676a2016-07-20 16:23:016814TEST_F(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:086815 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
6816}
6817
bncd16676a2016-07-20 16:23:016818TEST_F(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:086819 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
6820}
6821
bncd16676a2016-07-20 16:23:016822TEST_F(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:086823 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
6824}
6825
bncd16676a2016-07-20 16:23:016826TEST_F(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:086827 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
6828}
6829
bncd16676a2016-07-20 16:23:016830TEST_F(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:086831 ConnectStatusHelper(
6832 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
6833}
6834
bncd16676a2016-07-20 16:23:016835TEST_F(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:086836 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
6837}
6838
bncd16676a2016-07-20 16:23:016839TEST_F(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:086840 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
6841}
6842
bncd16676a2016-07-20 16:23:016843TEST_F(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:086844 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
6845}
6846
bncd16676a2016-07-20 16:23:016847TEST_F(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:086848 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
6849}
6850
bncd16676a2016-07-20 16:23:016851TEST_F(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:086852 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
6853}
6854
bncd16676a2016-07-20 16:23:016855TEST_F(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:086856 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
6857}
6858
bncd16676a2016-07-20 16:23:016859TEST_F(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:086860 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
6861}
6862
bncd16676a2016-07-20 16:23:016863TEST_F(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:086864 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
6865}
6866
bncd16676a2016-07-20 16:23:016867TEST_F(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:086868 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
6869}
6870
bncd16676a2016-07-20 16:23:016871TEST_F(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:086872 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
6873}
6874
bncd16676a2016-07-20 16:23:016875TEST_F(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:086876 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
6877}
6878
bncd16676a2016-07-20 16:23:016879TEST_F(HttpNetworkTransactionTest, ConnectStatus308) {
[email protected]0a17aab32014-04-24 03:32:376880 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
6881}
6882
bncd16676a2016-07-20 16:23:016883TEST_F(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:086884 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
6885}
6886
bncd16676a2016-07-20 16:23:016887TEST_F(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:086888 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
6889}
6890
bncd16676a2016-07-20 16:23:016891TEST_F(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:086892 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
6893}
6894
bncd16676a2016-07-20 16:23:016895TEST_F(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:086896 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
6897}
6898
bncd16676a2016-07-20 16:23:016899TEST_F(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:086900 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
6901}
6902
bncd16676a2016-07-20 16:23:016903TEST_F(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:086904 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
6905}
6906
bncd16676a2016-07-20 16:23:016907TEST_F(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:086908 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
6909}
6910
bncd16676a2016-07-20 16:23:016911TEST_F(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:086912 ConnectStatusHelperWithExpectedStatus(
6913 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:546914 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:086915}
6916
bncd16676a2016-07-20 16:23:016917TEST_F(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:086918 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
6919}
6920
bncd16676a2016-07-20 16:23:016921TEST_F(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:086922 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
6923}
6924
bncd16676a2016-07-20 16:23:016925TEST_F(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:086926 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
6927}
6928
bncd16676a2016-07-20 16:23:016929TEST_F(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:086930 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
6931}
6932
bncd16676a2016-07-20 16:23:016933TEST_F(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:086934 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
6935}
6936
bncd16676a2016-07-20 16:23:016937TEST_F(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:086938 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
6939}
6940
bncd16676a2016-07-20 16:23:016941TEST_F(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:086942 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
6943}
6944
bncd16676a2016-07-20 16:23:016945TEST_F(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:086946 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
6947}
6948
bncd16676a2016-07-20 16:23:016949TEST_F(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:086950 ConnectStatusHelper(
6951 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
6952}
6953
bncd16676a2016-07-20 16:23:016954TEST_F(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:086955 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
6956}
6957
bncd16676a2016-07-20 16:23:016958TEST_F(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:086959 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
6960}
6961
bncd16676a2016-07-20 16:23:016962TEST_F(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:086963 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
6964}
6965
bncd16676a2016-07-20 16:23:016966TEST_F(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:086967 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
6968}
6969
bncd16676a2016-07-20 16:23:016970TEST_F(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:086971 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
6972}
6973
bncd16676a2016-07-20 16:23:016974TEST_F(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:086975 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
6976}
6977
bncd16676a2016-07-20 16:23:016978TEST_F(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:086979 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
6980}
6981
[email protected]038e9a32008-10-08 22:40:166982// Test the flow when both the proxy server AND origin server require
6983// authentication. Again, this uses basic auth for both since that is
6984// the simplest to mock.
bncd16676a2016-07-20 16:23:016985TEST_F(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:276986 HttpRequestInfo request;
6987 request.method = "GET";
bncce36dca22015-04-21 22:11:236988 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:106989 request.traffic_annotation =
6990 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:276991
[email protected]038e9a32008-10-08 22:40:166992 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496993 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6994 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:096995 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:076996
bnc691fda62016-08-12 00:43:166997 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]038e9a32008-10-08 22:40:166998
[email protected]f9ee6b52008-11-08 06:46:236999 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237000 MockWrite(
7001 "GET http://www.example.org/ HTTP/1.1\r\n"
7002 "Host: www.example.org\r\n"
7003 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237004 };
7005
[email protected]038e9a32008-10-08 22:40:167006 MockRead data_reads1[] = {
7007 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
7008 // Give a couple authenticate options (only the middle one is actually
7009 // supported).
[email protected]22927ad2009-09-21 19:56:197010 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:167011 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7012 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
7013 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7014 // Large content-length -- won't matter, as connection will be reset.
7015 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067016 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:167017 };
7018
bnc691fda62016-08-12 00:43:167019 // After calling trans.RestartWithAuth() the first time, this is the
[email protected]038e9a32008-10-08 22:40:167020 // request we should be issuing -- the final header line contains the
7021 // proxy's credentials.
7022 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237023 MockWrite(
7024 "GET http://www.example.org/ HTTP/1.1\r\n"
7025 "Host: www.example.org\r\n"
7026 "Proxy-Connection: keep-alive\r\n"
7027 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:167028 };
7029
7030 // Now the proxy server lets the request pass through to origin server.
7031 // The origin server responds with a 401.
7032 MockRead data_reads2[] = {
7033 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7034 // Note: We are using the same realm-name as the proxy server. This is
7035 // completely valid, as realms are unique across hosts.
7036 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7037 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7038 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067039 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:167040 };
7041
bnc691fda62016-08-12 00:43:167042 // After calling trans.RestartWithAuth() the second time, we should send
[email protected]038e9a32008-10-08 22:40:167043 // the credentials for both the proxy and origin server.
7044 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237045 MockWrite(
7046 "GET http://www.example.org/ HTTP/1.1\r\n"
7047 "Host: www.example.org\r\n"
7048 "Proxy-Connection: keep-alive\r\n"
7049 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
7050 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:167051 };
7052
7053 // Lastly we get the desired content.
7054 MockRead data_reads3[] = {
7055 MockRead("HTTP/1.0 200 OK\r\n"),
7056 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7057 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067058 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:167059 };
7060
Ryan Sleevib8d7ea02018-05-07 20:01:017061 StaticSocketDataProvider data1(data_reads1, data_writes1);
7062 StaticSocketDataProvider data2(data_reads2, data_writes2);
7063 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]bb88e1d32013-05-03 23:11:077064 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7065 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7066 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:167067
[email protected]49639fa2011-12-20 23:22:417068 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:167069
tfarina42834112016-09-22 13:38:207070 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017071 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:167072
7073 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017074 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:167075
bnc691fda62016-08-12 00:43:167076 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527077 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047078 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:167079
[email protected]49639fa2011-12-20 23:22:417080 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:167081
bnc691fda62016-08-12 00:43:167082 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:017083 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:167084
7085 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017086 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:167087
bnc691fda62016-08-12 00:43:167088 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527089 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047090 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:167091
[email protected]49639fa2011-12-20 23:22:417092 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:167093
bnc691fda62016-08-12 00:43:167094 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
7095 callback3.callback());
robpercival214763f2016-07-01 23:27:017096 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:167097
7098 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017099 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:167100
bnc691fda62016-08-12 00:43:167101 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527102 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:167103 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:167104}
[email protected]4ddaf2502008-10-23 18:26:197105
[email protected]ea9dc9a2009-09-05 00:43:327106// For the NTLM implementation using SSPI, we skip the NTLM tests since we
7107// can't hook into its internals to cause it to generate predictable NTLM
7108// authorization headers.
7109#if defined(NTLM_PORTABLE)
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377110// The NTLM authentication unit tests are based on known test data from the
7111// [MS-NLMP] Specification [1]. These tests are primarily of the authentication
7112// flow rather than the implementation of the NTLM protocol. See net/ntlm
7113// for the implementation and testing of the protocol.
7114//
7115// [1] https://msdn.microsoft.com/en-us/library/cc236621.aspx
[email protected]385a4672009-03-11 22:21:297116
7117// Enter the correct password and authenticate successfully.
Zentaro Kavanagh1890a3d2018-01-29 19:52:557118TEST_F(HttpNetworkTransactionTest, NTLMAuthV2) {
[email protected]1c773ea12009-04-28 19:58:427119 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:247120 request.method = "GET";
Zentaro Kavanagh1890a3d2018-01-29 19:52:557121 request.url = GURL("https://server/kids/login.aspx");
Ramin Halavatib5e433e2018-02-07 07:41:107122 request.traffic_annotation =
7123 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2217aa22013-10-11 03:03:547124
7125 // Ensure load is not disrupted by flags which suppress behaviour specific
7126 // to other auth schemes.
7127 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:247128
Zentaro Kavanagh6ccee512017-09-28 18:34:097129 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
7130 MockGetMSTime, MockGenerateRandom, MockGetHostName);
danakj1fd259a02016-04-16 03:17:097131 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277132
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377133 // Generate the NTLM messages based on known test data.
7134 std::string negotiate_msg;
7135 std::string challenge_msg;
7136 std::string authenticate_msg;
7137 base::Base64Encode(
7138 base::StringPiece(
7139 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
Avi Drissman4365a4782018-12-28 19:26:247140 base::size(ntlm::test::kExpectedNegotiateMsg)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377141 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:557142 base::Base64Encode(
7143 base::StringPiece(
7144 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
Avi Drissman4365a4782018-12-28 19:26:247145 base::size(ntlm::test::kChallengeMsgFromSpecV2)),
Zentaro Kavanagh1890a3d2018-01-29 19:52:557146 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377147 base::Base64Encode(
7148 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:097149 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557150 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
Avi Drissman4365a4782018-12-28 19:26:247151 base::size(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557152 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377153 &authenticate_msg);
7154
[email protected]3f918782009-02-28 01:29:247155 MockWrite data_writes1[] = {
Zentaro Kavanagh1890a3d2018-01-29 19:52:557156 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
7157 "Host: server\r\n"
7158 "Connection: keep-alive\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:247159 };
7160
7161 MockRead data_reads1[] = {
7162 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:047163 // Negotiate and NTLM are often requested together. However, we only want
7164 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
7165 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:247166 MockRead("WWW-Authenticate: NTLM\r\n"),
7167 MockRead("Connection: close\r\n"),
7168 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:367169 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:247170 // Missing content -- won't matter, as connection will be reset.
[email protected]3f918782009-02-28 01:29:247171 };
7172
7173 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:167174 // After restarting with a null identity, this is the
7175 // request we should be issuing -- the final header line contains a Type
7176 // 1 message.
7177 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557178 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167179 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377180 "Authorization: NTLM "),
7181 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:247182
bnc691fda62016-08-12 00:43:167183 // After calling trans.RestartWithAuth(), we should send a Type 3 message
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377184 // (using correct credentials). The second request continues on the
7185 // same connection.
bnc691fda62016-08-12 00:43:167186 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557187 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167188 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377189 "Authorization: NTLM "),
7190 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:247191 };
7192
7193 MockRead data_reads2[] = {
Bence Béky1e4ef192017-09-18 19:58:027194 // The origin server responds with a Type 2 message.
7195 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377196 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
7197 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky1e4ef192017-09-18 19:58:027198 MockRead("Content-Type: text/html\r\n\r\n"),
7199 MockRead("You are not authorized to view this page\r\n"),
[email protected]3f918782009-02-28 01:29:247200
Bence Béky1e4ef192017-09-18 19:58:027201 // Lastly we get the desired content.
7202 MockRead("HTTP/1.1 200 OK\r\n"),
7203 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
7204 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
[email protected]3f918782009-02-28 01:29:247205 };
7206
Ryan Sleevib8d7ea02018-05-07 20:01:017207 StaticSocketDataProvider data1(data_reads1, data_writes1);
7208 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:077209 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7210 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:247211
Bence Béky83eb3512017-09-05 12:56:097212 SSLSocketDataProvider ssl1(ASYNC, OK);
7213 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
7214 SSLSocketDataProvider ssl2(ASYNC, OK);
7215 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
7216
[email protected]49639fa2011-12-20 23:22:417217 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:247218
bnc691fda62016-08-12 00:43:167219 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:507220
tfarina42834112016-09-22 13:38:207221 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017222 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:247223
7224 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017225 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:247226
bnc691fda62016-08-12 00:43:167227 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227228
bnc691fda62016-08-12 00:43:167229 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527230 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047231 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:247232
[email protected]49639fa2011-12-20 23:22:417233 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:257234
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377235 rv = trans.RestartWithAuth(
7236 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
7237 callback2.callback());
robpercival214763f2016-07-01 23:27:017238 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:257239
7240 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017241 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:257242
bnc691fda62016-08-12 00:43:167243 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:257244
bnc691fda62016-08-12 00:43:167245 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527246 ASSERT_TRUE(response);
7247 EXPECT_FALSE(response->auth_challenge);
[email protected]10af5fe72011-01-31 16:17:257248
[email protected]49639fa2011-12-20 23:22:417249 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:247250
bnc691fda62016-08-12 00:43:167251 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:017252 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:247253
[email protected]0757e7702009-03-27 04:00:227254 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017255 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:247256
bnc691fda62016-08-12 00:43:167257 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527258 ASSERT_TRUE(response);
7259 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:027260 EXPECT_EQ(14, response->headers->GetContentLength());
7261
7262 std::string response_data;
7263 rv = ReadTransaction(&trans, &response_data);
7264 EXPECT_THAT(rv, IsOk());
7265 EXPECT_EQ("Please Login\r\n", response_data);
7266
7267 EXPECT_TRUE(data1.AllReadDataConsumed());
7268 EXPECT_TRUE(data1.AllWriteDataConsumed());
7269 EXPECT_TRUE(data2.AllReadDataConsumed());
7270 EXPECT_TRUE(data2.AllWriteDataConsumed());
[email protected]3f918782009-02-28 01:29:247271}
7272
[email protected]385a4672009-03-11 22:21:297273// Enter a wrong password, and then the correct one.
Zentaro Kavanagh1890a3d2018-01-29 19:52:557274TEST_F(HttpNetworkTransactionTest, NTLMAuthV2WrongThenRightPassword) {
[email protected]1c773ea12009-04-28 19:58:427275 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:297276 request.method = "GET";
Zentaro Kavanagh1890a3d2018-01-29 19:52:557277 request.url = GURL("https://server/kids/login.aspx");
Ramin Halavatib5e433e2018-02-07 07:41:107278 request.traffic_annotation =
7279 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]385a4672009-03-11 22:21:297280
Zentaro Kavanagh6ccee512017-09-28 18:34:097281 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
7282 MockGetMSTime, MockGenerateRandom, MockGetHostName);
danakj1fd259a02016-04-16 03:17:097283 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277284
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377285 // Generate the NTLM messages based on known test data.
7286 std::string negotiate_msg;
7287 std::string challenge_msg;
7288 std::string authenticate_msg;
7289 base::Base64Encode(
7290 base::StringPiece(
7291 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
Avi Drissman4365a4782018-12-28 19:26:247292 base::size(ntlm::test::kExpectedNegotiateMsg)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377293 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:557294 base::Base64Encode(
7295 base::StringPiece(
7296 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
Avi Drissman4365a4782018-12-28 19:26:247297 base::size(ntlm::test::kChallengeMsgFromSpecV2)),
Zentaro Kavanagh1890a3d2018-01-29 19:52:557298 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377299 base::Base64Encode(
7300 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:097301 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557302 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
Avi Drissman4365a4782018-12-28 19:26:247303 base::size(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557304 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377305 &authenticate_msg);
7306
7307 // The authenticate message when |kWrongPassword| is sent.
7308 std::string wrong_password_authenticate_msg(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557309 "TlRMTVNTUAADAAAAGAAYAFgAAACKAIoAcAAAAAwADAD6AAAACAAIAAYBAAAQABAADgEAAAAA"
7310 "AABYAAAAA4IIAAAAAAAAAAAAAPknEYqtJQtusopDRSfYzAAAAAAAAAAAAAAAAAAAAAAAAAAA"
7311 "AAAAAOtVz38osnFdRRggUQHUJ3EBAQAAAAAAAIALyP0A1NIBqqqqqqqqqqoAAAAAAgAMAEQA"
7312 "bwBtAGEAaQBuAAEADABTAGUAcgB2AGUAcgAGAAQAAgAAAAoAEAAAAAAAAAAAAAAAAAAAAAAA"
7313 "CQAWAEgAVABUAFAALwBzAGUAcgB2AGUAcgAAAAAAAAAAAEQAbwBtAGEAaQBuAFUAcwBlAHIA"
7314 "QwBPAE0AUABVAFQARQBSAA==");
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377315
Zentaro Kavanagh1890a3d2018-01-29 19:52:557316 // Sanity check that it's the same length as the correct authenticate message
7317 // and that it's different.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377318 ASSERT_EQ(authenticate_msg.length(),
7319 wrong_password_authenticate_msg.length());
Zentaro Kavanagh1890a3d2018-01-29 19:52:557320 ASSERT_NE(authenticate_msg, wrong_password_authenticate_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377321
[email protected]385a4672009-03-11 22:21:297322 MockWrite data_writes1[] = {
Zentaro Kavanagh1890a3d2018-01-29 19:52:557323 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
7324 "Host: server\r\n"
7325 "Connection: keep-alive\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297326 };
7327
7328 MockRead data_reads1[] = {
7329 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:047330 // Negotiate and NTLM are often requested together. However, we only want
7331 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
7332 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:297333 MockRead("WWW-Authenticate: NTLM\r\n"),
7334 MockRead("Connection: close\r\n"),
7335 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:367336 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297337 // Missing content -- won't matter, as connection will be reset.
[email protected]385a4672009-03-11 22:21:297338 };
7339
7340 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:167341 // After restarting with a null identity, this is the
7342 // request we should be issuing -- the final header line contains a Type
7343 // 1 message.
7344 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557345 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167346 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377347 "Authorization: NTLM "),
7348 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297349
bnc691fda62016-08-12 00:43:167350 // After calling trans.RestartWithAuth(), we should send a Type 3 message
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377351 // (using incorrect credentials). The second request continues on the
7352 // same connection.
bnc691fda62016-08-12 00:43:167353 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557354 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167355 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377356 "Authorization: NTLM "),
7357 MockWrite(wrong_password_authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297358 };
7359
7360 MockRead data_reads2[] = {
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377361 // The origin server responds with a Type 2 message.
7362 MockRead("HTTP/1.1 401 Access Denied\r\n"),
7363 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
7364 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
7365 MockRead("Content-Type: text/html\r\n\r\n"),
7366 MockRead("You are not authorized to view this page\r\n"),
[email protected]385a4672009-03-11 22:21:297367
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377368 // Wrong password.
7369 MockRead("HTTP/1.1 401 Access Denied\r\n"),
7370 MockRead("WWW-Authenticate: NTLM\r\n"), MockRead("Connection: close\r\n"),
7371 MockRead("Content-Length: 42\r\n"),
7372 MockRead("Content-Type: text/html\r\n\r\n"),
7373 // Missing content -- won't matter, as connection will be reset.
[email protected]385a4672009-03-11 22:21:297374 };
7375
7376 MockWrite data_writes3[] = {
bnc691fda62016-08-12 00:43:167377 // After restarting with a null identity, this is the
7378 // request we should be issuing -- the final header line contains a Type
7379 // 1 message.
7380 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557381 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167382 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377383 "Authorization: NTLM "),
7384 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297385
bnc691fda62016-08-12 00:43:167386 // After calling trans.RestartWithAuth(), we should send a Type 3 message
7387 // (the credentials for the origin server). The second request continues
7388 // on the same connection.
7389 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557390 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167391 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377392 "Authorization: NTLM "),
7393 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297394 };
7395
7396 MockRead data_reads3[] = {
Bence Béky1e4ef192017-09-18 19:58:027397 // The origin server responds with a Type 2 message.
7398 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377399 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
7400 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky1e4ef192017-09-18 19:58:027401 MockRead("Content-Type: text/html\r\n\r\n"),
7402 MockRead("You are not authorized to view this page\r\n"),
[email protected]385a4672009-03-11 22:21:297403
Bence Béky1e4ef192017-09-18 19:58:027404 // Lastly we get the desired content.
7405 MockRead("HTTP/1.1 200 OK\r\n"),
7406 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
7407 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
[email protected]385a4672009-03-11 22:21:297408 };
7409
Ryan Sleevib8d7ea02018-05-07 20:01:017410 StaticSocketDataProvider data1(data_reads1, data_writes1);
7411 StaticSocketDataProvider data2(data_reads2, data_writes2);
7412 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]bb88e1d32013-05-03 23:11:077413 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7414 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7415 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:297416
Bence Béky83eb3512017-09-05 12:56:097417 SSLSocketDataProvider ssl1(ASYNC, OK);
7418 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
7419 SSLSocketDataProvider ssl2(ASYNC, OK);
7420 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
7421 SSLSocketDataProvider ssl3(ASYNC, OK);
7422 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
7423
[email protected]49639fa2011-12-20 23:22:417424 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:297425
bnc691fda62016-08-12 00:43:167426 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:507427
tfarina42834112016-09-22 13:38:207428 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017429 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:297430
7431 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017432 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:297433
bnc691fda62016-08-12 00:43:167434 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:297435
bnc691fda62016-08-12 00:43:167436 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527437 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047438 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:297439
[email protected]49639fa2011-12-20 23:22:417440 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:297441
[email protected]0757e7702009-03-27 04:00:227442 // Enter the wrong password.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377443 rv = trans.RestartWithAuth(
7444 AuthCredentials(ntlm::test::kDomainUserCombined, kWrongPassword),
7445 callback2.callback());
robpercival214763f2016-07-01 23:27:017446 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:297447
[email protected]10af5fe72011-01-31 16:17:257448 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017449 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:297450
bnc691fda62016-08-12 00:43:167451 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:417452 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:167453 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:017454 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:257455 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017456 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167457 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227458
bnc691fda62016-08-12 00:43:167459 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527460 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047461 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:227462
[email protected]49639fa2011-12-20 23:22:417463 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:227464
7465 // Now enter the right password.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377466 rv = trans.RestartWithAuth(
7467 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
7468 callback4.callback());
robpercival214763f2016-07-01 23:27:017469 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:257470
7471 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:017472 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:257473
bnc691fda62016-08-12 00:43:167474 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:257475
[email protected]49639fa2011-12-20 23:22:417476 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:257477
7478 // One more roundtrip
bnc691fda62016-08-12 00:43:167479 rv = trans.RestartWithAuth(AuthCredentials(), callback5.callback());
robpercival214763f2016-07-01 23:27:017480 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:227481
7482 rv = callback5.WaitForResult();
robpercival214763f2016-07-01 23:27:017483 EXPECT_THAT(rv, IsOk());
[email protected]0757e7702009-03-27 04:00:227484
bnc691fda62016-08-12 00:43:167485 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527486 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:027487 EXPECT_EQ(14, response->headers->GetContentLength());
7488
7489 std::string response_data;
7490 rv = ReadTransaction(&trans, &response_data);
7491 EXPECT_THAT(rv, IsOk());
7492 EXPECT_EQ("Please Login\r\n", response_data);
7493
7494 EXPECT_TRUE(data1.AllReadDataConsumed());
7495 EXPECT_TRUE(data1.AllWriteDataConsumed());
7496 EXPECT_TRUE(data2.AllReadDataConsumed());
7497 EXPECT_TRUE(data2.AllWriteDataConsumed());
7498 EXPECT_TRUE(data3.AllReadDataConsumed());
7499 EXPECT_TRUE(data3.AllWriteDataConsumed());
[email protected]385a4672009-03-11 22:21:297500}
Bence Béky83eb3512017-09-05 12:56:097501
Bence Béky3238f2e12017-09-22 22:44:497502// Server requests NTLM authentication, which is not supported over HTTP/2.
7503// Subsequent request with authorization header should be sent over HTTP/1.1.
Bence Béky83eb3512017-09-05 12:56:097504TEST_F(HttpNetworkTransactionTest, NTLMOverHttp2) {
Zentaro Kavanagh6ccee512017-09-28 18:34:097505 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
7506 MockGetMSTime, MockGenerateRandom, MockGetHostName);
Bence Béky83eb3512017-09-05 12:56:097507
Zentaro Kavanagh1890a3d2018-01-29 19:52:557508 const char* kUrl = "https://server/kids/login.aspx";
Bence Béky83eb3512017-09-05 12:56:097509
7510 HttpRequestInfo request;
7511 request.method = "GET";
7512 request.url = GURL(kUrl);
Ramin Halavatib5e433e2018-02-07 07:41:107513 request.traffic_annotation =
7514 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Béky83eb3512017-09-05 12:56:097515
7516 // First request without credentials.
Ryan Hamilton0239aac2018-05-19 00:03:137517 spdy::SpdyHeaderBlock request_headers0(
7518 spdy_util_.ConstructGetHeaderBlock(kUrl));
7519 spdy::SpdySerializedFrame request0(spdy_util_.ConstructSpdyHeaders(
Bence Béky83eb3512017-09-05 12:56:097520 1, std::move(request_headers0), LOWEST, true));
7521
Ryan Hamilton0239aac2018-05-19 00:03:137522 spdy::SpdyHeaderBlock response_headers0;
7523 response_headers0[spdy::kHttp2StatusHeader] = "401";
Bence Béky83eb3512017-09-05 12:56:097524 response_headers0["www-authenticate"] = "NTLM";
Ryan Hamilton0239aac2018-05-19 00:03:137525 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyResponseHeaders(
Bence Béky83eb3512017-09-05 12:56:097526 1, std::move(response_headers0), true));
7527
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377528 // Stream 1 is closed.
7529 spdy_util_.UpdateWithStreamDestruction(1);
7530
7531 // Generate the NTLM messages based on known test data.
7532 std::string negotiate_msg;
7533 std::string challenge_msg;
7534 std::string authenticate_msg;
7535 base::Base64Encode(
7536 base::StringPiece(
7537 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
Avi Drissman4365a4782018-12-28 19:26:247538 base::size(ntlm::test::kExpectedNegotiateMsg)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377539 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:557540 base::Base64Encode(
7541 base::StringPiece(
7542 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
Avi Drissman4365a4782018-12-28 19:26:247543 base::size(ntlm::test::kChallengeMsgFromSpecV2)),
Zentaro Kavanagh1890a3d2018-01-29 19:52:557544 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377545 base::Base64Encode(
7546 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:097547 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557548 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
Avi Drissman4365a4782018-12-28 19:26:247549 base::size(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557550 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377551 &authenticate_msg);
7552
7553 // Retry with authorization header.
Ryan Hamilton0239aac2018-05-19 00:03:137554 spdy::SpdyHeaderBlock request_headers1(
7555 spdy_util_.ConstructGetHeaderBlock(kUrl));
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377556 request_headers1["authorization"] = std::string("NTLM ") + negotiate_msg;
Ryan Hamilton0239aac2018-05-19 00:03:137557 spdy::SpdySerializedFrame request1(spdy_util_.ConstructSpdyHeaders(
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377558 3, std::move(request_headers1), LOWEST, true));
7559
Ryan Hamilton0239aac2018-05-19 00:03:137560 spdy::SpdySerializedFrame rst(
7561 spdy_util_.ConstructSpdyRstStream(3, spdy::ERROR_CODE_HTTP_1_1_REQUIRED));
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377562
Bence Béky3238f2e12017-09-22 22:44:497563 MockWrite writes0[] = {CreateMockWrite(request0, 0)};
7564 MockRead reads0[] = {CreateMockRead(resp, 1), MockRead(ASYNC, 0, 2)};
Bence Béky83eb3512017-09-05 12:56:097565
7566 // Retry yet again using HTTP/1.1.
7567 MockWrite writes1[] = {
7568 // After restarting with a null identity, this is the
7569 // request we should be issuing -- the final header line contains a Type
7570 // 1 message.
7571 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557572 "Host: server\r\n"
Bence Béky83eb3512017-09-05 12:56:097573 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377574 "Authorization: NTLM "),
7575 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
Bence Béky83eb3512017-09-05 12:56:097576
7577 // After calling trans.RestartWithAuth(), we should send a Type 3 message
7578 // (the credentials for the origin server). The second request continues
7579 // on the same connection.
7580 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557581 "Host: server\r\n"
Bence Béky83eb3512017-09-05 12:56:097582 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377583 "Authorization: NTLM "),
7584 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
Bence Béky83eb3512017-09-05 12:56:097585 };
7586
7587 MockRead reads1[] = {
7588 // The origin server responds with a Type 2 message.
7589 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377590 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
7591 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky83eb3512017-09-05 12:56:097592 MockRead("Content-Type: text/html\r\n\r\n"),
7593 MockRead("You are not authorized to view this page\r\n"),
7594
7595 // Lastly we get the desired content.
7596 MockRead("HTTP/1.1 200 OK\r\n"),
7597 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
Bence Béky1e4ef192017-09-18 19:58:027598 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
Bence Béky83eb3512017-09-05 12:56:097599 };
Ryan Sleevib8d7ea02018-05-07 20:01:017600 SequencedSocketData data0(reads0, writes0);
7601 StaticSocketDataProvider data1(reads1, writes1);
Bence Béky83eb3512017-09-05 12:56:097602 session_deps_.socket_factory->AddSocketDataProvider(&data0);
7603 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7604
7605 SSLSocketDataProvider ssl0(ASYNC, OK);
7606 ssl0.next_proto = kProtoHTTP2;
7607 SSLSocketDataProvider ssl1(ASYNC, OK);
7608 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl0);
7609 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
7610
7611 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7612 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
7613
7614 TestCompletionCallback callback1;
7615 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
7616 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7617
7618 rv = callback1.WaitForResult();
7619 EXPECT_THAT(rv, IsOk());
7620
7621 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
7622
7623 const HttpResponseInfo* response = trans.GetResponseInfo();
7624 ASSERT_TRUE(response);
7625 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
7626
7627 TestCompletionCallback callback2;
7628
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377629 rv = trans.RestartWithAuth(
7630 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
7631 callback2.callback());
Bence Béky83eb3512017-09-05 12:56:097632 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7633
7634 rv = callback2.WaitForResult();
7635 EXPECT_THAT(rv, IsOk());
7636
7637 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
7638
7639 response = trans.GetResponseInfo();
7640 ASSERT_TRUE(response);
7641 EXPECT_FALSE(response->auth_challenge);
7642
7643 TestCompletionCallback callback3;
7644
7645 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
7646 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7647
7648 rv = callback3.WaitForResult();
7649 EXPECT_THAT(rv, IsOk());
7650
7651 response = trans.GetResponseInfo();
7652 ASSERT_TRUE(response);
7653 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:027654 EXPECT_EQ(14, response->headers->GetContentLength());
7655
7656 std::string response_data;
7657 rv = ReadTransaction(&trans, &response_data);
7658 EXPECT_THAT(rv, IsOk());
7659 EXPECT_EQ("Please Login\r\n", response_data);
7660
7661 EXPECT_TRUE(data0.AllReadDataConsumed());
7662 EXPECT_TRUE(data0.AllWriteDataConsumed());
7663 EXPECT_TRUE(data1.AllReadDataConsumed());
7664 EXPECT_TRUE(data1.AllWriteDataConsumed());
Bence Béky83eb3512017-09-05 12:56:097665}
David Benjamin5cb91132018-04-06 05:54:497666
7667// Test that, if we have an NTLM proxy and the origin resets the connection, we
7668// do no retry forever checking for TLS version interference. This is a
7669// regression test for https://crbug.com/823387.
7670TEST_F(HttpNetworkTransactionTest, NTLMProxyTLSHandshakeReset) {
7671 // The NTLM test data expects the proxy to be named 'server'. The origin is
7672 // https://origin/.
7673 session_deps_.proxy_resolution_service =
7674 ProxyResolutionService::CreateFixedFromPacResult(
7675 "PROXY server", TRAFFIC_ANNOTATION_FOR_TESTS);
7676
7677 SSLConfig config;
David Benjamin5cb91132018-04-06 05:54:497678 session_deps_.ssl_config_service =
Ryan Sleevib8449e02018-07-15 04:31:077679 std::make_unique<TestSSLConfigService>(config);
David Benjamin5cb91132018-04-06 05:54:497680
7681 HttpRequestInfo request;
7682 request.method = "GET";
7683 request.url = GURL("https://origin/");
7684 request.traffic_annotation =
7685 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7686
7687 // Ensure load is not disrupted by flags which suppress behaviour specific
7688 // to other auth schemes.
7689 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
7690
7691 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
7692 MockGetMSTime, MockGenerateRandom, MockGetHostName);
7693 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7694
7695 // Generate the NTLM messages based on known test data.
7696 std::string negotiate_msg;
7697 std::string challenge_msg;
7698 std::string authenticate_msg;
7699 base::Base64Encode(
7700 base::StringPiece(
7701 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
Avi Drissman4365a4782018-12-28 19:26:247702 base::size(ntlm::test::kExpectedNegotiateMsg)),
David Benjamin5cb91132018-04-06 05:54:497703 &negotiate_msg);
7704 base::Base64Encode(
7705 base::StringPiece(
7706 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
Avi Drissman4365a4782018-12-28 19:26:247707 base::size(ntlm::test::kChallengeMsgFromSpecV2)),
David Benjamin5cb91132018-04-06 05:54:497708 &challenge_msg);
7709 base::Base64Encode(
7710 base::StringPiece(
7711 reinterpret_cast<const char*>(
7712 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
Avi Drissman4365a4782018-12-28 19:26:247713 base::size(
David Benjamin5cb91132018-04-06 05:54:497714 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
7715 &authenticate_msg);
7716
7717 MockWrite data_writes[] = {
7718 // The initial CONNECT request.
7719 MockWrite("CONNECT origin:443 HTTP/1.1\r\n"
7720 "Host: origin:443\r\n"
7721 "Proxy-Connection: keep-alive\r\n\r\n"),
7722
7723 // After restarting with an identity.
7724 MockWrite("CONNECT origin:443 HTTP/1.1\r\n"
7725 "Host: origin:443\r\n"
7726 "Proxy-Connection: keep-alive\r\n"
7727 "Proxy-Authorization: NTLM "),
7728 MockWrite(negotiate_msg.c_str()),
7729 // End headers.
7730 MockWrite("\r\n\r\n"),
7731
7732 // The second restart.
7733 MockWrite("CONNECT origin:443 HTTP/1.1\r\n"
7734 "Host: origin:443\r\n"
7735 "Proxy-Connection: keep-alive\r\n"
7736 "Proxy-Authorization: NTLM "),
7737 MockWrite(authenticate_msg.c_str()),
7738 // End headers.
7739 MockWrite("\r\n\r\n"),
7740 };
7741
7742 MockRead data_reads[] = {
7743 // The initial NTLM response.
7744 MockRead("HTTP/1.1 407 Access Denied\r\n"
7745 "Content-Length: 0\r\n"
7746 "Proxy-Authenticate: NTLM\r\n\r\n"),
7747
7748 // The NTLM challenge message.
7749 MockRead("HTTP/1.1 407 Access Denied\r\n"
7750 "Content-Length: 0\r\n"
7751 "Proxy-Authenticate: NTLM "),
7752 MockRead(challenge_msg.c_str()),
7753 // End headers.
7754 MockRead("\r\n\r\n"),
7755
7756 // Finally the tunnel is established.
7757 MockRead("HTTP/1.1 200 Connected\r\n\r\n"),
7758 };
7759
Ryan Sleevib8d7ea02018-05-07 20:01:017760 StaticSocketDataProvider data(data_reads, data_writes);
David Benjamin5cb91132018-04-06 05:54:497761 SSLSocketDataProvider data_ssl(ASYNC, ERR_CONNECTION_RESET);
Ryan Sleevib8d7ea02018-05-07 20:01:017762 StaticSocketDataProvider data2(data_reads, data_writes);
David Benjamin5cb91132018-04-06 05:54:497763 SSLSocketDataProvider data_ssl2(ASYNC, ERR_CONNECTION_RESET);
Steven Valdez0ef94d02018-11-19 23:28:137764 data_ssl2.expected_ssl_version_max = SSL_PROTOCOL_VERSION_TLS1_2;
David Benjamin5cb91132018-04-06 05:54:497765 session_deps_.socket_factory->AddSocketDataProvider(&data);
7766 session_deps_.socket_factory->AddSSLSocketDataProvider(&data_ssl);
7767 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7768 session_deps_.socket_factory->AddSSLSocketDataProvider(&data_ssl2);
7769
7770 // Start the transaction. The proxy responds with an NTLM authentication
7771 // request.
7772 TestCompletionCallback callback;
7773 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
7774 int rv = callback.GetResult(
7775 trans.Start(&request, callback.callback(), NetLogWithSource()));
7776
7777 EXPECT_THAT(rv, IsOk());
7778 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
7779 const HttpResponseInfo* response = trans.GetResponseInfo();
7780 ASSERT_TRUE(response);
7781 EXPECT_TRUE(CheckNTLMProxyAuth(response->auth_challenge.get()));
7782
7783 // Configure credentials. The proxy responds with the challenge message.
7784 rv = callback.GetResult(trans.RestartWithAuth(
7785 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
7786 callback.callback()));
7787 EXPECT_THAT(rv, IsOk());
7788 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
7789 response = trans.GetResponseInfo();
7790 ASSERT_TRUE(response);
7791 EXPECT_FALSE(response->auth_challenge);
7792
7793 // Restart once more. The tunnel will be established and the the SSL handshake
7794 // will reset. The TLS 1.3 version interference probe will then kick in and
7795 // restart the process. The proxy responds with another NTLM authentiation
7796 // request, but we don't need to provide credentials as the cached ones work/
7797 rv = callback.GetResult(
7798 trans.RestartWithAuth(AuthCredentials(), callback.callback()));
7799 EXPECT_THAT(rv, IsOk());
7800 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
7801 response = trans.GetResponseInfo();
7802 ASSERT_TRUE(response);
7803 EXPECT_FALSE(response->auth_challenge);
7804
7805 // The proxy responds with the NTLM challenge message.
7806 rv = callback.GetResult(
7807 trans.RestartWithAuth(AuthCredentials(), callback.callback()));
7808 EXPECT_THAT(rv, IsOk());
7809 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
7810 response = trans.GetResponseInfo();
7811 ASSERT_TRUE(response);
7812 EXPECT_FALSE(response->auth_challenge);
7813
7814 // Send the NTLM authenticate message. The tunnel is established and the
7815 // handshake resets again. We should not retry again.
7816 rv = callback.GetResult(
7817 trans.RestartWithAuth(AuthCredentials(), callback.callback()));
7818 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
7819}
7820
[email protected]ea9dc9a2009-09-05 00:43:327821#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:297822
[email protected]4ddaf2502008-10-23 18:26:197823// Test reading a server response which has only headers, and no body.
7824// After some maximum number of bytes is consumed, the transaction should
7825// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
bncd16676a2016-07-20 16:23:017826TEST_F(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:427827 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:197828 request.method = "GET";
bncce36dca22015-04-21 22:11:237829 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:107830 request.traffic_annotation =
7831 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]4ddaf2502008-10-23 18:26:197832
danakj1fd259a02016-04-16 03:17:097833 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167834 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277835
[email protected]b75b7b2f2009-10-06 00:54:537836 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:437837 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:537838 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:197839
7840 MockRead data_reads[] = {
7841 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:067842 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:197843 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:067844 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:197845 };
Ryan Sleevib8d7ea02018-05-07 20:01:017846 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:077847 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:197848
[email protected]49639fa2011-12-20 23:22:417849 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:197850
tfarina42834112016-09-22 13:38:207851 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017852 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]4ddaf2502008-10-23 18:26:197853
7854 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017855 EXPECT_THAT(rv, IsError(ERR_RESPONSE_HEADERS_TOO_BIG));
[email protected]4ddaf2502008-10-23 18:26:197856}
[email protected]f4e426b2008-11-05 00:24:497857
7858// Make sure that we don't try to reuse a TCPClientSocket when failing to
7859// establish tunnel.
7860// http://code.google.com/p/chromium/issues/detail?id=3772
bncd16676a2016-07-20 16:23:017861TEST_F(HttpNetworkTransactionTest, DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:277862 HttpRequestInfo request;
7863 request.method = "GET";
bncce36dca22015-04-21 22:11:237864 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:107865 request.traffic_annotation =
7866 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:277867
[email protected]f4e426b2008-11-05 00:24:497868 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:497869 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
7870 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]db8f44c2008-12-13 04:52:017871
danakj1fd259a02016-04-16 03:17:097872 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:497873
bnc87dcefc2017-05-25 12:47:587874 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:197875 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]f4e426b2008-11-05 00:24:497876
[email protected]f4e426b2008-11-05 00:24:497877 // Since we have proxy, should try to establish tunnel.
7878 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:177879 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7880 "Host: www.example.org:443\r\n"
7881 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:497882 };
7883
[email protected]77848d12008-11-14 00:00:227884 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:497885 // connection. Usually a proxy would return 501 (not implemented),
7886 // or 200 (tunnel established).
7887 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:237888 MockRead("HTTP/1.1 404 Not Found\r\n"),
7889 MockRead("Content-Length: 10\r\n\r\n"),
7890 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]f4e426b2008-11-05 00:24:497891 };
7892
Ryan Sleevib8d7ea02018-05-07 20:01:017893 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:077894 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:497895
[email protected]49639fa2011-12-20 23:22:417896 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:497897
tfarina42834112016-09-22 13:38:207898 int rv = trans->Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017899 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f4e426b2008-11-05 00:24:497900
7901 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017902 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]f4e426b2008-11-05 00:24:497903
[email protected]b4404c02009-04-10 16:38:527904 // Empty the current queue. This is necessary because idle sockets are
7905 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557906 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:527907
[email protected]f4e426b2008-11-05 00:24:497908 // We now check to make sure the TCPClientSocket was not added back to
7909 // the pool.
[email protected]90499482013-06-01 00:39:507910 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:497911 trans.reset();
fdoray92e35a72016-06-10 15:54:557912 base::RunLoop().RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:497913 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:507914 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:497915}
[email protected]372d34a2008-11-05 21:30:517916
[email protected]1b157c02009-04-21 01:55:407917// Make sure that we recycle a socket after reading all of the response body.
bncd16676a2016-07-20 16:23:017918TEST_F(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:427919 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:407920 request.method = "GET";
bncce36dca22015-04-21 22:11:237921 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:107922 request.traffic_annotation =
7923 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1b157c02009-04-21 01:55:407924
danakj1fd259a02016-04-16 03:17:097925 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277926
bnc691fda62016-08-12 00:43:167927 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277928
[email protected]1b157c02009-04-21 01:55:407929 MockRead data_reads[] = {
7930 // A part of the response body is received with the response headers.
7931 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
7932 // The rest of the response body is received in two parts.
7933 MockRead("lo"),
7934 MockRead(" world"),
7935 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:067936 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:407937 };
7938
Ryan Sleevib8d7ea02018-05-07 20:01:017939 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:077940 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:407941
[email protected]49639fa2011-12-20 23:22:417942 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:407943
tfarina42834112016-09-22 13:38:207944 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017945 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1b157c02009-04-21 01:55:407946
7947 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017948 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:407949
bnc691fda62016-08-12 00:43:167950 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527951 ASSERT_TRUE(response);
[email protected]1b157c02009-04-21 01:55:407952
wezca1070932016-05-26 20:30:527953 EXPECT_TRUE(response->headers);
[email protected]1b157c02009-04-21 01:55:407954 std::string status_line = response->headers->GetStatusLine();
7955 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
7956
[email protected]90499482013-06-01 00:39:507957 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:407958
7959 std::string response_data;
bnc691fda62016-08-12 00:43:167960 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017961 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:407962 EXPECT_EQ("hello world", response_data);
7963
7964 // Empty the current queue. This is necessary because idle sockets are
7965 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557966 base::RunLoop().RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:407967
7968 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507969 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:407970}
7971
[email protected]76a505b2010-08-25 06:23:007972// Make sure that we recycle a SSL socket after reading all of the response
7973// body.
bncd16676a2016-07-20 16:23:017974TEST_F(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:007975 HttpRequestInfo request;
7976 request.method = "GET";
bncce36dca22015-04-21 22:11:237977 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:107978 request.traffic_annotation =
7979 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:007980
7981 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237982 MockWrite(
7983 "GET / HTTP/1.1\r\n"
7984 "Host: www.example.org\r\n"
7985 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:007986 };
7987
7988 MockRead data_reads[] = {
7989 MockRead("HTTP/1.1 200 OK\r\n"),
7990 MockRead("Content-Length: 11\r\n\r\n"),
7991 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:067992 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:007993 };
7994
[email protected]8ddf8322012-02-23 18:08:067995 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077996 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:007997
Ryan Sleevib8d7ea02018-05-07 20:01:017998 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:077999 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:008000
[email protected]49639fa2011-12-20 23:22:418001 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:008002
danakj1fd259a02016-04-16 03:17:098003 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168004 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:008005
tfarina42834112016-09-22 13:38:208006 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:008007
robpercival214763f2016-07-01 23:27:018008 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8009 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:008010
bnc691fda62016-08-12 00:43:168011 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528012 ASSERT_TRUE(response);
8013 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:008014 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8015
[email protected]90499482013-06-01 00:39:508016 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008017
8018 std::string response_data;
bnc691fda62016-08-12 00:43:168019 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:018020 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:008021 EXPECT_EQ("hello world", response_data);
8022
8023 // Empty the current queue. This is necessary because idle sockets are
8024 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:558025 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:008026
8027 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:508028 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008029}
8030
8031// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
8032// from the pool and make sure that we recover okay.
bncd16676a2016-07-20 16:23:018033TEST_F(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:008034 HttpRequestInfo request;
8035 request.method = "GET";
bncce36dca22015-04-21 22:11:238036 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:108037 request.traffic_annotation =
8038 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:008039
8040 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238041 MockWrite(
8042 "GET / HTTP/1.1\r\n"
8043 "Host: www.example.org\r\n"
8044 "Connection: keep-alive\r\n\r\n"),
8045 MockWrite(
8046 "GET / HTTP/1.1\r\n"
8047 "Host: www.example.org\r\n"
8048 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:008049 };
8050
8051 MockRead data_reads[] = {
mmenke911ee0222015-12-04 03:58:428052 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
8053 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
[email protected]76a505b2010-08-25 06:23:008054
[email protected]8ddf8322012-02-23 18:08:068055 SSLSocketDataProvider ssl(ASYNC, OK);
8056 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078057 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8058 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:008059
Ryan Sleevib8d7ea02018-05-07 20:01:018060 StaticSocketDataProvider data(data_reads, data_writes);
8061 StaticSocketDataProvider data2(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:078062 session_deps_.socket_factory->AddSocketDataProvider(&data);
8063 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:008064
[email protected]49639fa2011-12-20 23:22:418065 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:008066
danakj1fd259a02016-04-16 03:17:098067 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:588068 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:198069 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:008070
tfarina42834112016-09-22 13:38:208071 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:008072
robpercival214763f2016-07-01 23:27:018073 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8074 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:008075
8076 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528077 ASSERT_TRUE(response);
8078 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:008079 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8080
[email protected]90499482013-06-01 00:39:508081 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008082
8083 std::string response_data;
8084 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018085 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:008086 EXPECT_EQ("hello world", response_data);
8087
8088 // Empty the current queue. This is necessary because idle sockets are
8089 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:558090 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:008091
8092 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:508093 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008094
8095 // Now start the second transaction, which should reuse the previous socket.
8096
bnc87dcefc2017-05-25 12:47:588097 trans =
Jeremy Roman0579ed62017-08-29 15:56:198098 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:008099
tfarina42834112016-09-22 13:38:208100 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:008101
robpercival214763f2016-07-01 23:27:018102 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8103 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:008104
8105 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528106 ASSERT_TRUE(response);
8107 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:008108 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8109
[email protected]90499482013-06-01 00:39:508110 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008111
8112 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018113 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:008114 EXPECT_EQ("hello world", response_data);
8115
8116 // Empty the current queue. This is necessary because idle sockets are
8117 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:558118 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:008119
8120 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:508121 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008122}
8123
maksim.sisov0adf8592016-07-15 06:25:568124// Grab a socket, use it, and put it back into the pool. Then, make
8125// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:018126TEST_F(HttpNetworkTransactionTest, FlushSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:568127 HttpRequestInfo request;
8128 request.method = "GET";
8129 request.url = GURL("http://www.example.org/");
8130 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:108131 request.traffic_annotation =
8132 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
maksim.sisov0adf8592016-07-15 06:25:568133
8134 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8135
bnc691fda62016-08-12 00:43:168136 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:568137
8138 MockRead data_reads[] = {
8139 // A part of the response body is received with the response headers.
8140 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
8141 // The rest of the response body is received in two parts.
8142 MockRead("lo"), MockRead(" world"),
8143 MockRead("junk"), // Should not be read!!
8144 MockRead(SYNCHRONOUS, OK),
8145 };
8146
Ryan Sleevib8d7ea02018-05-07 20:01:018147 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
maksim.sisov0adf8592016-07-15 06:25:568148 session_deps_.socket_factory->AddSocketDataProvider(&data);
8149
8150 TestCompletionCallback callback;
8151
tfarina42834112016-09-22 13:38:208152 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:568153 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8154
8155 EXPECT_THAT(callback.GetResult(rv), IsOk());
8156
bnc691fda62016-08-12 00:43:168157 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:568158 ASSERT_TRUE(response);
8159 EXPECT_TRUE(response->headers);
8160 std::string status_line = response->headers->GetStatusLine();
8161 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
8162
8163 // Make memory critical notification and ensure the transaction still has been
8164 // operating right.
8165 base::MemoryPressureListener::NotifyMemoryPressure(
8166 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8167 base::RunLoop().RunUntilIdle();
8168
8169 // Socket should not be flushed as long as it is not idle.
8170 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
8171
8172 std::string response_data;
bnc691fda62016-08-12 00:43:168173 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:568174 EXPECT_THAT(rv, IsOk());
8175 EXPECT_EQ("hello world", response_data);
8176
8177 // Empty the current queue. This is necessary because idle sockets are
8178 // added to the connection pool asynchronously with a PostTask.
8179 base::RunLoop().RunUntilIdle();
8180
8181 // We now check to make sure the socket was added back to the pool.
8182 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
8183
8184 // Idle sockets should be flushed now.
8185 base::MemoryPressureListener::NotifyMemoryPressure(
8186 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8187 base::RunLoop().RunUntilIdle();
8188
8189 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
8190}
8191
yucliu48f235d2018-01-11 00:59:558192// Disable idle socket closing on memory pressure.
8193// Grab a socket, use it, and put it back into the pool. Then, make
8194// low memory notification and ensure the socket pool is NOT flushed.
8195TEST_F(HttpNetworkTransactionTest, NoFlushSocketPoolOnLowMemoryNotifications) {
8196 HttpRequestInfo request;
8197 request.method = "GET";
8198 request.url = GURL("http://www.example.org/");
8199 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:108200 request.traffic_annotation =
8201 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
yucliu48f235d2018-01-11 00:59:558202
8203 // Disable idle socket closing on memory pressure.
8204 session_deps_.disable_idle_sockets_close_on_memory_pressure = true;
8205 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8206
8207 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
8208
8209 MockRead data_reads[] = {
8210 // A part of the response body is received with the response headers.
8211 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
8212 // The rest of the response body is received in two parts.
8213 MockRead("lo"), MockRead(" world"),
8214 MockRead("junk"), // Should not be read!!
8215 MockRead(SYNCHRONOUS, OK),
8216 };
8217
Ryan Sleevib8d7ea02018-05-07 20:01:018218 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
yucliu48f235d2018-01-11 00:59:558219 session_deps_.socket_factory->AddSocketDataProvider(&data);
8220
8221 TestCompletionCallback callback;
8222
8223 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
8224 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8225
8226 EXPECT_THAT(callback.GetResult(rv), IsOk());
8227
8228 const HttpResponseInfo* response = trans.GetResponseInfo();
8229 ASSERT_TRUE(response);
8230 EXPECT_TRUE(response->headers);
8231 std::string status_line = response->headers->GetStatusLine();
8232 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
8233
8234 // Make memory critical notification and ensure the transaction still has been
8235 // operating right.
8236 base::MemoryPressureListener::NotifyMemoryPressure(
8237 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8238 base::RunLoop().RunUntilIdle();
8239
8240 // Socket should not be flushed as long as it is not idle.
8241 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
8242
8243 std::string response_data;
8244 rv = ReadTransaction(&trans, &response_data);
8245 EXPECT_THAT(rv, IsOk());
8246 EXPECT_EQ("hello world", response_data);
8247
8248 // Empty the current queue. This is necessary because idle sockets are
8249 // added to the connection pool asynchronously with a PostTask.
8250 base::RunLoop().RunUntilIdle();
8251
8252 // We now check to make sure the socket was added back to the pool.
8253 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
8254
8255 // Idle sockets should NOT be flushed on moderate memory pressure.
8256 base::MemoryPressureListener::NotifyMemoryPressure(
8257 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE);
8258 base::RunLoop().RunUntilIdle();
8259
8260 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
8261
8262 // Idle sockets should NOT be flushed on critical memory pressure.
8263 base::MemoryPressureListener::NotifyMemoryPressure(
8264 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8265 base::RunLoop().RunUntilIdle();
8266
8267 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
8268}
8269
maksim.sisov0adf8592016-07-15 06:25:568270// Grab an SSL socket, use it, and put it back into the pool. Then, make
8271// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:018272TEST_F(HttpNetworkTransactionTest, FlushSSLSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:568273 HttpRequestInfo request;
8274 request.method = "GET";
8275 request.url = GURL("https://www.example.org/");
8276 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:108277 request.traffic_annotation =
8278 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
maksim.sisov0adf8592016-07-15 06:25:568279
8280 MockWrite data_writes[] = {
8281 MockWrite("GET / HTTP/1.1\r\n"
8282 "Host: www.example.org\r\n"
8283 "Connection: keep-alive\r\n\r\n"),
8284 };
8285
8286 MockRead data_reads[] = {
8287 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
8288 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
8289
8290 SSLSocketDataProvider ssl(ASYNC, OK);
8291 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8292
Ryan Sleevib8d7ea02018-05-07 20:01:018293 StaticSocketDataProvider data(data_reads, data_writes);
maksim.sisov0adf8592016-07-15 06:25:568294 session_deps_.socket_factory->AddSocketDataProvider(&data);
8295
8296 TestCompletionCallback callback;
8297
8298 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168299 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:568300
8301 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
tfarina42834112016-09-22 13:38:208302 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:568303
8304 EXPECT_THAT(callback.GetResult(rv), IsOk());
8305
bnc691fda62016-08-12 00:43:168306 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:568307 ASSERT_TRUE(response);
8308 ASSERT_TRUE(response->headers);
8309 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8310
8311 // Make memory critical notification and ensure the transaction still has been
8312 // operating right.
8313 base::MemoryPressureListener::NotifyMemoryPressure(
8314 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8315 base::RunLoop().RunUntilIdle();
8316
8317 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
8318
8319 std::string response_data;
bnc691fda62016-08-12 00:43:168320 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:568321 EXPECT_THAT(rv, IsOk());
8322 EXPECT_EQ("hello world", response_data);
8323
8324 // Empty the current queue. This is necessary because idle sockets are
8325 // added to the connection pool asynchronously with a PostTask.
8326 base::RunLoop().RunUntilIdle();
8327
8328 // We now check to make sure the socket was added back to the pool.
8329 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
8330
8331 // Make memory notification once again and ensure idle socket is closed.
8332 base::MemoryPressureListener::NotifyMemoryPressure(
8333 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8334 base::RunLoop().RunUntilIdle();
8335
8336 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
8337}
8338
[email protected]b4404c02009-04-10 16:38:528339// Make sure that we recycle a socket after a zero-length response.
8340// http://crbug.com/9880
bncd16676a2016-07-20 16:23:018341TEST_F(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:428342 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:528343 request.method = "GET";
bncce36dca22015-04-21 22:11:238344 request.url = GURL(
8345 "http://www.example.org/csi?v=3&s=web&action=&"
8346 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
8347 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
8348 "rt=prt.2642,ol.2649,xjs.2951");
Ramin Halavatib5e433e2018-02-07 07:41:108349 request.traffic_annotation =
8350 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]b4404c02009-04-10 16:38:528351
danakj1fd259a02016-04-16 03:17:098352 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:278353
[email protected]b4404c02009-04-10 16:38:528354 MockRead data_reads[] = {
8355 MockRead("HTTP/1.1 204 No Content\r\n"
8356 "Content-Length: 0\r\n"
8357 "Content-Type: text/html\r\n\r\n"),
8358 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:068359 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:528360 };
8361
Ryan Sleevib8d7ea02018-05-07 20:01:018362 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:078363 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:528364
mmenkecc2298e2015-12-07 18:20:188365 // Transaction must be created after the MockReads, so it's destroyed before
8366 // them.
bnc691fda62016-08-12 00:43:168367 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkecc2298e2015-12-07 18:20:188368
[email protected]49639fa2011-12-20 23:22:418369 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:528370
tfarina42834112016-09-22 13:38:208371 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018372 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]b4404c02009-04-10 16:38:528373
8374 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018375 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:528376
bnc691fda62016-08-12 00:43:168377 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528378 ASSERT_TRUE(response);
[email protected]b4404c02009-04-10 16:38:528379
wezca1070932016-05-26 20:30:528380 EXPECT_TRUE(response->headers);
[email protected]b4404c02009-04-10 16:38:528381 std::string status_line = response->headers->GetStatusLine();
8382 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
8383
[email protected]90499482013-06-01 00:39:508384 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:528385
8386 std::string response_data;
bnc691fda62016-08-12 00:43:168387 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:018388 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:528389 EXPECT_EQ("", response_data);
8390
8391 // Empty the current queue. This is necessary because idle sockets are
8392 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:558393 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:528394
8395 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:508396 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:528397}
8398
bncd16676a2016-07-20 16:23:018399TEST_F(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
danakj1fd259a02016-04-16 03:17:098400 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:228401 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:198402 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:228403 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:278404
[email protected]1c773ea12009-04-28 19:58:428405 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:518406 // Transaction 1: a GET request that succeeds. The socket is recycled
8407 // after use.
8408 request[0].method = "GET";
8409 request[0].url = GURL("http://www.google.com/");
8410 request[0].load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:108411 request[0].traffic_annotation =
8412 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]372d34a2008-11-05 21:30:518413 // Transaction 2: a POST request. Reuses the socket kept alive from
8414 // transaction 1. The first attempts fails when writing the POST data.
8415 // This causes the transaction to retry with a new socket. The second
8416 // attempt succeeds.
8417 request[1].method = "POST";
8418 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:278419 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:518420 request[1].load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:108421 request[1].traffic_annotation =
8422 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]372d34a2008-11-05 21:30:518423
danakj1fd259a02016-04-16 03:17:098424 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:518425
8426 // The first socket is used for transaction 1 and the first attempt of
8427 // transaction 2.
8428
8429 // The response of transaction 1.
8430 MockRead data_reads1[] = {
8431 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
8432 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068433 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:518434 };
8435 // The mock write results of transaction 1 and the first attempt of
8436 // transaction 2.
8437 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:068438 MockWrite(SYNCHRONOUS, 64), // GET
8439 MockWrite(SYNCHRONOUS, 93), // POST
8440 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:518441 };
Ryan Sleevib8d7ea02018-05-07 20:01:018442 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]372d34a2008-11-05 21:30:518443
8444 // The second socket is used for the second attempt of transaction 2.
8445
8446 // The response of transaction 2.
8447 MockRead data_reads2[] = {
8448 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
8449 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:068450 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:518451 };
8452 // The mock write results of the second attempt of transaction 2.
8453 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:068454 MockWrite(SYNCHRONOUS, 93), // POST
8455 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:518456 };
Ryan Sleevib8d7ea02018-05-07 20:01:018457 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]372d34a2008-11-05 21:30:518458
[email protected]bb88e1d32013-05-03 23:11:078459 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8460 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:518461
thestig9d3bb0c2015-01-24 00:49:518462 const char* const kExpectedResponseData[] = {
[email protected]372d34a2008-11-05 21:30:518463 "hello world", "welcome"
8464 };
8465
8466 for (int i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:168467 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]372d34a2008-11-05 21:30:518468
[email protected]49639fa2011-12-20 23:22:418469 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:518470
tfarina42834112016-09-22 13:38:208471 int rv = trans.Start(&request[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018472 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]372d34a2008-11-05 21:30:518473
8474 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018475 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:518476
bnc691fda62016-08-12 00:43:168477 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528478 ASSERT_TRUE(response);
[email protected]372d34a2008-11-05 21:30:518479
wezca1070932016-05-26 20:30:528480 EXPECT_TRUE(response->headers);
[email protected]372d34a2008-11-05 21:30:518481 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8482
8483 std::string response_data;
bnc691fda62016-08-12 00:43:168484 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:018485 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:518486 EXPECT_EQ(kExpectedResponseData[i], response_data);
8487 }
8488}
[email protected]f9ee6b52008-11-08 06:46:238489
8490// Test the request-challenge-retry sequence for basic auth when there is
8491// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:168492// it fails the identity from the URL is used to answer the challenge.
bncd16676a2016-07-20 16:23:018493TEST_F(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:428494 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238495 request.method = "GET";
bncce36dca22015-04-21 22:11:238496 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:418497 request.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:108498 request.traffic_annotation =
8499 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]a97cca42009-08-14 01:00:298500
danakj1fd259a02016-04-16 03:17:098501 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168502 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278503
[email protected]a97cca42009-08-14 01:00:298504 // The password contains an escaped character -- for this test to pass it
8505 // will need to be unescaped by HttpNetworkTransaction.
8506 EXPECT_EQ("b%40r", request.url.password());
8507
[email protected]f9ee6b52008-11-08 06:46:238508 MockWrite data_writes1[] = {
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\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238513 };
8514
8515 MockRead data_reads1[] = {
8516 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8517 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8518 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068519 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238520 };
8521
[email protected]2262e3a2012-05-22 16:08:168522 // After the challenge above, the transaction will be restarted using the
8523 // identity from the url (foo, b@r) to answer the challenge.
8524 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238525 MockWrite(
8526 "GET / HTTP/1.1\r\n"
8527 "Host: www.example.org\r\n"
8528 "Connection: keep-alive\r\n"
8529 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:168530 };
8531
8532 MockRead data_reads2[] = {
8533 MockRead("HTTP/1.0 200 OK\r\n"),
8534 MockRead("Content-Length: 100\r\n\r\n"),
8535 MockRead(SYNCHRONOUS, OK),
8536 };
8537
Ryan Sleevib8d7ea02018-05-07 20:01:018538 StaticSocketDataProvider data1(data_reads1, data_writes1);
8539 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:078540 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8541 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:238542
[email protected]49639fa2011-12-20 23:22:418543 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:208544 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018545 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238546 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018547 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168548 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:168549
8550 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:168551 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:018552 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:168553 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018554 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168555 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:228556
bnc691fda62016-08-12 00:43:168557 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528558 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:168559
8560 // There is no challenge info, since the identity in URL worked.
wezca1070932016-05-26 20:30:528561 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:168562
8563 EXPECT_EQ(100, response->headers->GetContentLength());
8564
8565 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:558566 base::RunLoop().RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:168567}
8568
8569// Test the request-challenge-retry sequence for basic auth when there is an
8570// incorrect identity in the URL. The identity from the URL should be used only
8571// once.
bncd16676a2016-07-20 16:23:018572TEST_F(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:168573 HttpRequestInfo request;
8574 request.method = "GET";
8575 // Note: the URL has a username:password in it. The password "baz" is
8576 // wrong (should be "bar").
bncce36dca22015-04-21 22:11:238577 request.url = GURL("http://foo:[email protected]/");
[email protected]2262e3a2012-05-22 16:08:168578
8579 request.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:108580 request.traffic_annotation =
8581 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2262e3a2012-05-22 16:08:168582
danakj1fd259a02016-04-16 03:17:098583 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168584 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2262e3a2012-05-22 16:08:168585
8586 MockWrite data_writes1[] = {
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\r\n"),
[email protected]2262e3a2012-05-22 16:08:168591 };
8592
8593 MockRead data_reads1[] = {
8594 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8595 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8596 MockRead("Content-Length: 10\r\n\r\n"),
8597 MockRead(SYNCHRONOUS, ERR_FAILED),
8598 };
8599
8600 // After the challenge above, the transaction will be restarted using the
8601 // identity from the url (foo, baz) to answer the challenge.
8602 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238603 MockWrite(
8604 "GET / HTTP/1.1\r\n"
8605 "Host: www.example.org\r\n"
8606 "Connection: keep-alive\r\n"
8607 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:168608 };
8609
8610 MockRead data_reads2[] = {
8611 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8612 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8613 MockRead("Content-Length: 10\r\n\r\n"),
8614 MockRead(SYNCHRONOUS, ERR_FAILED),
8615 };
8616
8617 // After the challenge above, the transaction will be restarted using the
8618 // identity supplied by the user (foo, bar) to answer the challenge.
8619 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:238620 MockWrite(
8621 "GET / HTTP/1.1\r\n"
8622 "Host: www.example.org\r\n"
8623 "Connection: keep-alive\r\n"
8624 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:168625 };
8626
8627 MockRead data_reads3[] = {
8628 MockRead("HTTP/1.0 200 OK\r\n"),
8629 MockRead("Content-Length: 100\r\n\r\n"),
8630 MockRead(SYNCHRONOUS, OK),
8631 };
8632
Ryan Sleevib8d7ea02018-05-07 20:01:018633 StaticSocketDataProvider data1(data_reads1, data_writes1);
8634 StaticSocketDataProvider data2(data_reads2, data_writes2);
8635 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]bb88e1d32013-05-03 23:11:078636 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8637 session_deps_.socket_factory->AddSocketDataProvider(&data2);
8638 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:168639
8640 TestCompletionCallback callback1;
8641
tfarina42834112016-09-22 13:38:208642 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018643 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:168644
8645 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018646 EXPECT_THAT(rv, IsOk());
[email protected]2262e3a2012-05-22 16:08:168647
bnc691fda62016-08-12 00:43:168648 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:168649 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:168650 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:018651 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:168652 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018653 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168654 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:168655
bnc691fda62016-08-12 00:43:168656 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528657 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:168658 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
8659
8660 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:168661 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:018662 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:168663 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:018664 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168665 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:168666
bnc691fda62016-08-12 00:43:168667 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528668 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:168669
8670 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:528671 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:168672
8673 EXPECT_EQ(100, response->headers->GetContentLength());
8674
[email protected]ea9dc9a2009-09-05 00:43:328675 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:558676 base::RunLoop().RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:328677}
8678
[email protected]2217aa22013-10-11 03:03:548679
8680// Test the request-challenge-retry sequence for basic auth when there is a
8681// correct identity in the URL, but its use is being suppressed. The identity
8682// from the URL should never be used.
bncd16676a2016-07-20 16:23:018683TEST_F(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
[email protected]2217aa22013-10-11 03:03:548684 HttpRequestInfo request;
8685 request.method = "GET";
bncce36dca22015-04-21 22:11:238686 request.url = GURL("http://foo:[email protected]/");
[email protected]2217aa22013-10-11 03:03:548687 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
Ramin Halavatib5e433e2018-02-07 07:41:108688 request.traffic_annotation =
8689 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2217aa22013-10-11 03:03:548690
danakj1fd259a02016-04-16 03:17:098691 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168692 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2217aa22013-10-11 03:03:548693
8694 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238695 MockWrite(
8696 "GET / HTTP/1.1\r\n"
8697 "Host: www.example.org\r\n"
8698 "Connection: keep-alive\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:548699 };
8700
8701 MockRead data_reads1[] = {
8702 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8703 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8704 MockRead("Content-Length: 10\r\n\r\n"),
8705 MockRead(SYNCHRONOUS, ERR_FAILED),
8706 };
8707
8708 // After the challenge above, the transaction will be restarted using the
8709 // identity supplied by the user, not the one in the URL, to answer the
8710 // challenge.
8711 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:238712 MockWrite(
8713 "GET / HTTP/1.1\r\n"
8714 "Host: www.example.org\r\n"
8715 "Connection: keep-alive\r\n"
8716 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:548717 };
8718
8719 MockRead data_reads3[] = {
8720 MockRead("HTTP/1.0 200 OK\r\n"),
8721 MockRead("Content-Length: 100\r\n\r\n"),
8722 MockRead(SYNCHRONOUS, OK),
8723 };
8724
Ryan Sleevib8d7ea02018-05-07 20:01:018725 StaticSocketDataProvider data1(data_reads1, data_writes1);
8726 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]2217aa22013-10-11 03:03:548727 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8728 session_deps_.socket_factory->AddSocketDataProvider(&data3);
8729
8730 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:208731 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018732 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:548733 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018734 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168735 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:548736
bnc691fda62016-08-12 00:43:168737 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528738 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:548739 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
8740
8741 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:168742 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:018743 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:548744 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:018745 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168746 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:548747
bnc691fda62016-08-12 00:43:168748 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528749 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:548750
8751 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:528752 EXPECT_FALSE(response->auth_challenge);
[email protected]2217aa22013-10-11 03:03:548753 EXPECT_EQ(100, response->headers->GetContentLength());
8754
8755 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:558756 base::RunLoop().RunUntilIdle();
[email protected]2217aa22013-10-11 03:03:548757}
8758
[email protected]f9ee6b52008-11-08 06:46:238759// Test that previously tried username/passwords for a realm get re-used.
bncd16676a2016-07-20 16:23:018760TEST_F(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
danakj1fd259a02016-04-16 03:17:098761 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:238762
8763 // Transaction 1: authenticate (foo, bar) on MyRealm1
8764 {
[email protected]1c773ea12009-04-28 19:58:428765 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238766 request.method = "GET";
bncce36dca22015-04-21 22:11:238767 request.url = GURL("http://www.example.org/x/y/z");
Ramin Halavatib5e433e2018-02-07 07:41:108768 request.traffic_annotation =
8769 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238770
bnc691fda62016-08-12 00:43:168771 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278772
[email protected]f9ee6b52008-11-08 06:46:238773 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238774 MockWrite(
8775 "GET /x/y/z HTTP/1.1\r\n"
8776 "Host: www.example.org\r\n"
8777 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238778 };
8779
8780 MockRead data_reads1[] = {
8781 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8782 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8783 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068784 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238785 };
8786
8787 // Resend with authorization (username=foo, password=bar)
8788 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238789 MockWrite(
8790 "GET /x/y/z HTTP/1.1\r\n"
8791 "Host: www.example.org\r\n"
8792 "Connection: keep-alive\r\n"
8793 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238794 };
8795
8796 // Sever accepts the authorization.
8797 MockRead data_reads2[] = {
8798 MockRead("HTTP/1.0 200 OK\r\n"),
8799 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068800 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238801 };
8802
Ryan Sleevib8d7ea02018-05-07 20:01:018803 StaticSocketDataProvider data1(data_reads1, data_writes1);
8804 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:078805 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8806 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:238807
[email protected]49639fa2011-12-20 23:22:418808 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238809
tfarina42834112016-09-22 13:38:208810 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018811 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238812
8813 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018814 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238815
bnc691fda62016-08-12 00:43:168816 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528817 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:048818 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:238819
[email protected]49639fa2011-12-20 23:22:418820 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:238821
bnc691fda62016-08-12 00:43:168822 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
8823 callback2.callback());
robpercival214763f2016-07-01 23:27:018824 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238825
8826 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018827 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238828
bnc691fda62016-08-12 00:43:168829 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528830 ASSERT_TRUE(response);
8831 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238832 EXPECT_EQ(100, response->headers->GetContentLength());
8833 }
8834
8835 // ------------------------------------------------------------------------
8836
8837 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
8838 {
[email protected]1c773ea12009-04-28 19:58:428839 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238840 request.method = "GET";
8841 // Note that Transaction 1 was at /x/y/z, so this is in the same
8842 // protection space as MyRealm1.
bncce36dca22015-04-21 22:11:238843 request.url = GURL("http://www.example.org/x/y/a/b");
Ramin Halavatib5e433e2018-02-07 07:41:108844 request.traffic_annotation =
8845 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238846
bnc691fda62016-08-12 00:43:168847 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278848
[email protected]f9ee6b52008-11-08 06:46:238849 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238850 MockWrite(
8851 "GET /x/y/a/b HTTP/1.1\r\n"
8852 "Host: www.example.org\r\n"
8853 "Connection: keep-alive\r\n"
8854 // Send preemptive authorization for MyRealm1
8855 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238856 };
8857
8858 // The server didn't like the preemptive authorization, and
8859 // challenges us for a different realm (MyRealm2).
8860 MockRead data_reads1[] = {
8861 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8862 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
8863 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068864 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238865 };
8866
8867 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
8868 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238869 MockWrite(
8870 "GET /x/y/a/b HTTP/1.1\r\n"
8871 "Host: www.example.org\r\n"
8872 "Connection: keep-alive\r\n"
8873 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238874 };
8875
8876 // Sever accepts the authorization.
8877 MockRead data_reads2[] = {
8878 MockRead("HTTP/1.0 200 OK\r\n"),
8879 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068880 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238881 };
8882
Ryan Sleevib8d7ea02018-05-07 20:01:018883 StaticSocketDataProvider data1(data_reads1, data_writes1);
8884 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:078885 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8886 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:238887
[email protected]49639fa2011-12-20 23:22:418888 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238889
tfarina42834112016-09-22 13:38:208890 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018891 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238892
8893 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018894 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238895
bnc691fda62016-08-12 00:43:168896 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528897 ASSERT_TRUE(response);
8898 ASSERT_TRUE(response->auth_challenge);
[email protected]79cb5c12011-09-12 13:12:048899 EXPECT_FALSE(response->auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:438900 EXPECT_EQ("http://www.example.org",
8901 response->auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:048902 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
aberentbba302d2015-12-03 10:20:198903 EXPECT_EQ(kBasicAuthScheme, response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:238904
[email protected]49639fa2011-12-20 23:22:418905 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:238906
bnc691fda62016-08-12 00:43:168907 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
8908 callback2.callback());
robpercival214763f2016-07-01 23:27:018909 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238910
8911 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018912 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238913
bnc691fda62016-08-12 00:43:168914 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528915 ASSERT_TRUE(response);
8916 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238917 EXPECT_EQ(100, response->headers->GetContentLength());
8918 }
8919
8920 // ------------------------------------------------------------------------
8921
8922 // Transaction 3: Resend a request in MyRealm's protection space --
8923 // succeed with preemptive authorization.
8924 {
[email protected]1c773ea12009-04-28 19:58:428925 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238926 request.method = "GET";
bncce36dca22015-04-21 22:11:238927 request.url = GURL("http://www.example.org/x/y/z2");
Ramin Halavatib5e433e2018-02-07 07:41:108928 request.traffic_annotation =
8929 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238930
bnc691fda62016-08-12 00:43:168931 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278932
[email protected]f9ee6b52008-11-08 06:46:238933 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238934 MockWrite(
8935 "GET /x/y/z2 HTTP/1.1\r\n"
8936 "Host: www.example.org\r\n"
8937 "Connection: keep-alive\r\n"
8938 // The authorization for MyRealm1 gets sent preemptively
8939 // (since the url is in the same protection space)
8940 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238941 };
8942
8943 // Sever accepts the preemptive authorization
8944 MockRead data_reads1[] = {
8945 MockRead("HTTP/1.0 200 OK\r\n"),
8946 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068947 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238948 };
8949
Ryan Sleevib8d7ea02018-05-07 20:01:018950 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:078951 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:238952
[email protected]49639fa2011-12-20 23:22:418953 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238954
tfarina42834112016-09-22 13:38:208955 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018956 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238957
8958 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018959 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238960
bnc691fda62016-08-12 00:43:168961 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528962 ASSERT_TRUE(response);
[email protected]f9ee6b52008-11-08 06:46:238963
wezca1070932016-05-26 20:30:528964 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238965 EXPECT_EQ(100, response->headers->GetContentLength());
8966 }
8967
8968 // ------------------------------------------------------------------------
8969
8970 // Transaction 4: request another URL in MyRealm (however the
8971 // url is not known to belong to the protection space, so no pre-auth).
8972 {
[email protected]1c773ea12009-04-28 19:58:428973 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238974 request.method = "GET";
bncce36dca22015-04-21 22:11:238975 request.url = GURL("http://www.example.org/x/1");
Ramin Halavatib5e433e2018-02-07 07:41:108976 request.traffic_annotation =
8977 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238978
bnc691fda62016-08-12 00:43:168979 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278980
[email protected]f9ee6b52008-11-08 06:46:238981 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238982 MockWrite(
8983 "GET /x/1 HTTP/1.1\r\n"
8984 "Host: www.example.org\r\n"
8985 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238986 };
8987
8988 MockRead data_reads1[] = {
8989 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8990 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8991 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068992 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238993 };
8994
8995 // Resend with authorization from MyRealm's cache.
8996 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238997 MockWrite(
8998 "GET /x/1 HTTP/1.1\r\n"
8999 "Host: www.example.org\r\n"
9000 "Connection: keep-alive\r\n"
9001 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:239002 };
9003
9004 // Sever accepts the authorization.
9005 MockRead data_reads2[] = {
9006 MockRead("HTTP/1.0 200 OK\r\n"),
9007 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069008 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:239009 };
9010
Ryan Sleevib8d7ea02018-05-07 20:01:019011 StaticSocketDataProvider data1(data_reads1, data_writes1);
9012 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:079013 session_deps_.socket_factory->AddSocketDataProvider(&data1);
9014 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:239015
[email protected]49639fa2011-12-20 23:22:419016 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:239017
tfarina42834112016-09-22 13:38:209018 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019019 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:239020
9021 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019022 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:239023
bnc691fda62016-08-12 00:43:169024 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:419025 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:169026 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:019027 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:229028 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:019029 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:169030 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:229031
bnc691fda62016-08-12 00:43:169032 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529033 ASSERT_TRUE(response);
9034 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:239035 EXPECT_EQ(100, response->headers->GetContentLength());
9036 }
9037
9038 // ------------------------------------------------------------------------
9039
9040 // Transaction 5: request a URL in MyRealm, but the server rejects the
9041 // cached identity. Should invalidate and re-prompt.
9042 {
[email protected]1c773ea12009-04-28 19:58:429043 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:239044 request.method = "GET";
bncce36dca22015-04-21 22:11:239045 request.url = GURL("http://www.example.org/p/q/t");
Ramin Halavatib5e433e2018-02-07 07:41:109046 request.traffic_annotation =
9047 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:239048
bnc691fda62016-08-12 00:43:169049 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279050
[email protected]f9ee6b52008-11-08 06:46:239051 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239052 MockWrite(
9053 "GET /p/q/t HTTP/1.1\r\n"
9054 "Host: www.example.org\r\n"
9055 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:239056 };
9057
9058 MockRead data_reads1[] = {
9059 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
9060 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9061 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069062 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:239063 };
9064
9065 // Resend with authorization from cache for MyRealm.
9066 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:239067 MockWrite(
9068 "GET /p/q/t HTTP/1.1\r\n"
9069 "Host: www.example.org\r\n"
9070 "Connection: keep-alive\r\n"
9071 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:239072 };
9073
9074 // Sever rejects the authorization.
9075 MockRead data_reads2[] = {
9076 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
9077 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9078 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069079 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:239080 };
9081
9082 // At this point we should prompt for new credentials for MyRealm.
9083 // Restart with username=foo3, password=foo4.
9084 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:239085 MockWrite(
9086 "GET /p/q/t HTTP/1.1\r\n"
9087 "Host: www.example.org\r\n"
9088 "Connection: keep-alive\r\n"
9089 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:239090 };
9091
9092 // Sever accepts the authorization.
9093 MockRead data_reads3[] = {
9094 MockRead("HTTP/1.0 200 OK\r\n"),
9095 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069096 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:239097 };
9098
Ryan Sleevib8d7ea02018-05-07 20:01:019099 StaticSocketDataProvider data1(data_reads1, data_writes1);
9100 StaticSocketDataProvider data2(data_reads2, data_writes2);
9101 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]bb88e1d32013-05-03 23:11:079102 session_deps_.socket_factory->AddSocketDataProvider(&data1);
9103 session_deps_.socket_factory->AddSocketDataProvider(&data2);
9104 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:239105
[email protected]49639fa2011-12-20 23:22:419106 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:239107
tfarina42834112016-09-22 13:38:209108 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019109 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:239110
9111 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019112 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:239113
bnc691fda62016-08-12 00:43:169114 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:419115 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:169116 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:019117 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:229118 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:019119 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:169120 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:229121
bnc691fda62016-08-12 00:43:169122 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529123 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:049124 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:239125
[email protected]49639fa2011-12-20 23:22:419126 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:239127
bnc691fda62016-08-12 00:43:169128 rv = trans.RestartWithAuth(AuthCredentials(kFoo3, kBar3),
9129 callback3.callback());
robpercival214763f2016-07-01 23:27:019130 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:239131
[email protected]0757e7702009-03-27 04:00:229132 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:019133 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:239134
bnc691fda62016-08-12 00:43:169135 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529136 ASSERT_TRUE(response);
9137 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:239138 EXPECT_EQ(100, response->headers->GetContentLength());
9139 }
9140}
[email protected]89ceba9a2009-03-21 03:46:069141
[email protected]3c32c5f2010-05-18 15:18:129142// Tests that nonce count increments when multiple auth attempts
9143// are started with the same nonce.
bncd16676a2016-07-20 16:23:019144TEST_F(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:449145 HttpAuthHandlerDigest::Factory* digest_factory =
9146 new HttpAuthHandlerDigest::Factory();
9147 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
9148 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
9149 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:079150 session_deps_.http_auth_handler_factory.reset(digest_factory);
danakj1fd259a02016-04-16 03:17:099151 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:129152
9153 // Transaction 1: authenticate (foo, bar) on MyRealm1
9154 {
[email protected]3c32c5f2010-05-18 15:18:129155 HttpRequestInfo request;
9156 request.method = "GET";
bncce36dca22015-04-21 22:11:239157 request.url = GURL("http://www.example.org/x/y/z");
Ramin Halavatib5e433e2018-02-07 07:41:109158 request.traffic_annotation =
9159 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3c32c5f2010-05-18 15:18:129160
bnc691fda62016-08-12 00:43:169161 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279162
[email protected]3c32c5f2010-05-18 15:18:129163 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239164 MockWrite(
9165 "GET /x/y/z HTTP/1.1\r\n"
9166 "Host: www.example.org\r\n"
9167 "Connection: keep-alive\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:129168 };
9169
9170 MockRead data_reads1[] = {
9171 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
9172 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
9173 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069174 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:129175 };
9176
9177 // Resend with authorization (username=foo, password=bar)
9178 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:239179 MockWrite(
9180 "GET /x/y/z HTTP/1.1\r\n"
9181 "Host: www.example.org\r\n"
9182 "Connection: keep-alive\r\n"
9183 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
9184 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
9185 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
9186 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:129187 };
9188
9189 // Sever accepts the authorization.
9190 MockRead data_reads2[] = {
zmo9528c9f42015-08-04 22:12:089191 MockRead("HTTP/1.0 200 OK\r\n"),
9192 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:129193 };
9194
Ryan Sleevib8d7ea02018-05-07 20:01:019195 StaticSocketDataProvider data1(data_reads1, data_writes1);
9196 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:079197 session_deps_.socket_factory->AddSocketDataProvider(&data1);
9198 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:129199
[email protected]49639fa2011-12-20 23:22:419200 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:129201
tfarina42834112016-09-22 13:38:209202 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019203 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:129204
9205 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019206 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:129207
bnc691fda62016-08-12 00:43:169208 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529209 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:049210 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:129211
[email protected]49639fa2011-12-20 23:22:419212 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:129213
bnc691fda62016-08-12 00:43:169214 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
9215 callback2.callback());
robpercival214763f2016-07-01 23:27:019216 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:129217
9218 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:019219 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:129220
bnc691fda62016-08-12 00:43:169221 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529222 ASSERT_TRUE(response);
9223 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:129224 }
9225
9226 // ------------------------------------------------------------------------
9227
9228 // Transaction 2: Request another resource in digestive's protection space.
9229 // This will preemptively add an Authorization header which should have an
9230 // "nc" value of 2 (as compared to 1 in the first use.
9231 {
[email protected]3c32c5f2010-05-18 15:18:129232 HttpRequestInfo request;
9233 request.method = "GET";
9234 // Note that Transaction 1 was at /x/y/z, so this is in the same
9235 // protection space as digest.
bncce36dca22015-04-21 22:11:239236 request.url = GURL("http://www.example.org/x/y/a/b");
Ramin Halavatib5e433e2018-02-07 07:41:109237 request.traffic_annotation =
9238 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3c32c5f2010-05-18 15:18:129239
bnc691fda62016-08-12 00:43:169240 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279241
[email protected]3c32c5f2010-05-18 15:18:129242 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239243 MockWrite(
9244 "GET /x/y/a/b HTTP/1.1\r\n"
9245 "Host: www.example.org\r\n"
9246 "Connection: keep-alive\r\n"
9247 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
9248 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
9249 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
9250 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:129251 };
9252
9253 // Sever accepts the authorization.
9254 MockRead data_reads1[] = {
9255 MockRead("HTTP/1.0 200 OK\r\n"),
9256 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069257 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:129258 };
9259
Ryan Sleevib8d7ea02018-05-07 20:01:019260 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:079261 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:129262
[email protected]49639fa2011-12-20 23:22:419263 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:129264
tfarina42834112016-09-22 13:38:209265 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019266 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:129267
9268 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019269 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:129270
bnc691fda62016-08-12 00:43:169271 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529272 ASSERT_TRUE(response);
9273 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:129274 }
9275}
9276
[email protected]89ceba9a2009-03-21 03:46:069277// Test the ResetStateForRestart() private method.
bncd16676a2016-07-20 16:23:019278TEST_F(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:069279 // Create a transaction (the dependencies aren't important).
danakj1fd259a02016-04-16 03:17:099280 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169281 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]89ceba9a2009-03-21 03:46:069282
9283 // Setup some state (which we expect ResetStateForRestart() will clear).
Victor Costan9c7302b2018-08-27 16:39:449284 trans.read_buf_ = base::MakeRefCounted<IOBuffer>(15);
bnc691fda62016-08-12 00:43:169285 trans.read_buf_len_ = 15;
9286 trans.request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:069287
9288 // Setup state in response_
bnc691fda62016-08-12 00:43:169289 HttpResponseInfo* response = &trans.response_;
[email protected]0877e3d2009-10-17 22:29:579290 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:089291 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:579292 response->response_time = base::Time::Now();
9293 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:069294
9295 { // Setup state for response_.vary_data
9296 HttpRequestInfo request;
9297 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
9298 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:279299 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:439300 request.extra_headers.SetHeader("Foo", "1");
9301 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:509302 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:069303 }
9304
9305 // Cause the above state to be reset.
bnc691fda62016-08-12 00:43:169306 trans.ResetStateForRestart();
[email protected]89ceba9a2009-03-21 03:46:069307
9308 // Verify that the state that needed to be reset, has been reset.
bnc691fda62016-08-12 00:43:169309 EXPECT_FALSE(trans.read_buf_);
9310 EXPECT_EQ(0, trans.read_buf_len_);
9311 EXPECT_TRUE(trans.request_headers_.IsEmpty());
wezca1070932016-05-26 20:30:529312 EXPECT_FALSE(response->auth_challenge);
9313 EXPECT_FALSE(response->headers);
[email protected]34f40942010-10-04 00:34:049314 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:089315 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:579316 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:069317}
9318
[email protected]bacff652009-03-31 17:50:339319// Test HTTPS connections to a site with a bad certificate
bncd16676a2016-07-20 16:23:019320TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:339321 HttpRequestInfo request;
9322 request.method = "GET";
bncce36dca22015-04-21 22:11:239323 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109324 request.traffic_annotation =
9325 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]bacff652009-03-31 17:50:339326
danakj1fd259a02016-04-16 03:17:099327 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169328 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279329
[email protected]bacff652009-03-31 17:50:339330 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239331 MockWrite(
9332 "GET / HTTP/1.1\r\n"
9333 "Host: www.example.org\r\n"
9334 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:339335 };
9336
9337 MockRead data_reads[] = {
9338 MockRead("HTTP/1.0 200 OK\r\n"),
9339 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9340 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069341 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:339342 };
9343
[email protected]5ecc992a42009-11-11 01:41:599344 StaticSocketDataProvider ssl_bad_certificate;
Ryan Sleevib8d7ea02018-05-07 20:01:019345 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069346 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
9347 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:339348
[email protected]bb88e1d32013-05-03 23:11:079349 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
9350 session_deps_.socket_factory->AddSocketDataProvider(&data);
9351 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
9352 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:339353
[email protected]49639fa2011-12-20 23:22:419354 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:339355
tfarina42834112016-09-22 13:38:209356 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019357 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:339358
9359 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019360 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:339361
bnc691fda62016-08-12 00:43:169362 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:019363 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:339364
9365 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019366 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:339367
bnc691fda62016-08-12 00:43:169368 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:339369
wezca1070932016-05-26 20:30:529370 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:339371 EXPECT_EQ(100, response->headers->GetContentLength());
9372}
9373
9374// Test HTTPS connections to a site with a bad certificate, going through a
9375// proxy
bncd16676a2016-07-20 16:23:019376TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
Ramin Halavatica8d5252018-03-12 05:33:499377 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9378 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]bacff652009-03-31 17:50:339379
9380 HttpRequestInfo request;
9381 request.method = "GET";
bncce36dca22015-04-21 22:11:239382 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109383 request.traffic_annotation =
9384 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]bacff652009-03-31 17:50:339385
9386 MockWrite proxy_writes[] = {
rsleevidb16bb02015-11-12 23:47:179387 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9388 "Host: www.example.org:443\r\n"
9389 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:339390 };
9391
9392 MockRead proxy_reads[] = {
9393 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069394 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:339395 };
9396
9397 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179398 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9399 "Host: www.example.org:443\r\n"
9400 "Proxy-Connection: keep-alive\r\n\r\n"),
9401 MockWrite("GET / HTTP/1.1\r\n"
9402 "Host: www.example.org\r\n"
9403 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:339404 };
9405
9406 MockRead data_reads[] = {
9407 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
9408 MockRead("HTTP/1.0 200 OK\r\n"),
9409 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9410 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069411 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:339412 };
9413
Ryan Sleevib8d7ea02018-05-07 20:01:019414 StaticSocketDataProvider ssl_bad_certificate(proxy_reads, proxy_writes);
9415 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069416 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
9417 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:339418
[email protected]bb88e1d32013-05-03 23:11:079419 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
9420 session_deps_.socket_factory->AddSocketDataProvider(&data);
9421 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
9422 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:339423
[email protected]49639fa2011-12-20 23:22:419424 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:339425
9426 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:079427 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:339428
danakj1fd259a02016-04-16 03:17:099429 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169430 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bacff652009-03-31 17:50:339431
tfarina42834112016-09-22 13:38:209432 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019433 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:339434
9435 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019436 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:339437
bnc691fda62016-08-12 00:43:169438 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:019439 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:339440
9441 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019442 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:339443
bnc691fda62016-08-12 00:43:169444 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:339445
wezca1070932016-05-26 20:30:529446 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:339447 EXPECT_EQ(100, response->headers->GetContentLength());
9448 }
9449}
9450
[email protected]2df19bb2010-08-25 20:13:469451
9452// Test HTTPS connections to a site, going through an HTTPS proxy
bncd16676a2016-07-20 16:23:019453TEST_F(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:599454 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499455 ProxyResolutionService::CreateFixedFromPacResult(
9456 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519457 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079458 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:469459
9460 HttpRequestInfo request;
9461 request.method = "GET";
bncce36dca22015-04-21 22:11:239462 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109463 request.traffic_annotation =
9464 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:469465
9466 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179467 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9468 "Host: www.example.org:443\r\n"
9469 "Proxy-Connection: keep-alive\r\n\r\n"),
9470 MockWrite("GET / HTTP/1.1\r\n"
9471 "Host: www.example.org\r\n"
9472 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:469473 };
9474
9475 MockRead data_reads[] = {
9476 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
9477 MockRead("HTTP/1.1 200 OK\r\n"),
9478 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9479 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069480 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:469481 };
9482
Ryan Sleevib8d7ea02018-05-07 20:01:019483 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069484 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
9485 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:469486
[email protected]bb88e1d32013-05-03 23:11:079487 session_deps_.socket_factory->AddSocketDataProvider(&data);
9488 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
9489 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:469490
[email protected]49639fa2011-12-20 23:22:419491 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:469492
danakj1fd259a02016-04-16 03:17:099493 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169494 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:469495
tfarina42834112016-09-22 13:38:209496 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019497 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:469498
9499 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019500 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:169501 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:469502
wezca1070932016-05-26 20:30:529503 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:469504
tbansal2ecbbc72016-10-06 17:15:479505 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:469506 EXPECT_TRUE(response->headers->IsKeepAlive());
9507 EXPECT_EQ(200, response->headers->response_code());
9508 EXPECT_EQ(100, response->headers->GetContentLength());
9509 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:209510
9511 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169512 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209513 TestLoadTimingNotReusedWithPac(load_timing_info,
9514 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:469515}
9516
[email protected]511f6f52010-12-17 03:58:299517// Test an HTTPS Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:019518TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:599519 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499520 ProxyResolutionService::CreateFixedFromPacResult(
9521 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519522 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079523 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:299524
9525 HttpRequestInfo request;
9526 request.method = "GET";
bncce36dca22015-04-21 22:11:239527 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109528 request.traffic_annotation =
9529 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299530
9531 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179532 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9533 "Host: www.example.org:443\r\n"
9534 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:299535 };
9536
9537 MockRead data_reads[] = {
9538 MockRead("HTTP/1.1 302 Redirect\r\n"),
9539 MockRead("Location: http://login.example.com/\r\n"),
9540 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069541 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:299542 };
9543
Ryan Sleevib8d7ea02018-05-07 20:01:019544 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069545 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:299546
[email protected]bb88e1d32013-05-03 23:11:079547 session_deps_.socket_factory->AddSocketDataProvider(&data);
9548 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:299549
[email protected]49639fa2011-12-20 23:22:419550 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:299551
danakj1fd259a02016-04-16 03:17:099552 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169553 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:299554
tfarina42834112016-09-22 13:38:209555 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019556 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:299557
9558 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019559 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:169560 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:299561
wezca1070932016-05-26 20:30:529562 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:299563
9564 EXPECT_EQ(302, response->headers->response_code());
9565 std::string url;
9566 EXPECT_TRUE(response->headers->IsRedirect(&url));
9567 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:209568
9569 // In the case of redirects from proxies, HttpNetworkTransaction returns
9570 // timing for the proxy connection instead of the connection to the host,
9571 // and no send / receive times.
9572 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
9573 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169574 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209575
9576 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:199577 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:209578
9579 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
9580 EXPECT_LE(load_timing_info.proxy_resolve_start,
9581 load_timing_info.proxy_resolve_end);
9582 EXPECT_LE(load_timing_info.proxy_resolve_end,
9583 load_timing_info.connect_timing.connect_start);
9584 ExpectConnectTimingHasTimes(
9585 load_timing_info.connect_timing,
9586 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
9587
9588 EXPECT_TRUE(load_timing_info.send_start.is_null());
9589 EXPECT_TRUE(load_timing_info.send_end.is_null());
9590 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:299591}
9592
9593// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:019594TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
Ramin Halavatica8d5252018-03-12 05:33:499595 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9596 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299597
9598 HttpRequestInfo request;
9599 request.method = "GET";
bncce36dca22015-04-21 22:11:239600 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109601 request.traffic_annotation =
9602 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299603
Ryan Hamilton0239aac2018-05-19 00:03:139604 spdy::SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:239605 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:139606 spdy::SpdySerializedFrame goaway(
9607 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:299608 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:419609 CreateMockWrite(conn, 0, SYNCHRONOUS),
9610 CreateMockWrite(goaway, 2, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:299611 };
9612
9613 static const char* const kExtraHeaders[] = {
9614 "location",
9615 "http://login.example.com/",
9616 };
Ryan Hamilton0239aac2018-05-19 00:03:139617 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
Avi Drissman4365a4782018-12-28 19:26:249618 "302", kExtraHeaders, base::size(kExtraHeaders) / 2, 1));
[email protected]511f6f52010-12-17 03:58:299619 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:419620 CreateMockRead(resp, 1), MockRead(ASYNC, 0, 3), // EOF
[email protected]511f6f52010-12-17 03:58:299621 };
9622
Ryan Sleevib8d7ea02018-05-07 20:01:019623 SequencedSocketData data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069624 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:369625 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:299626
[email protected]bb88e1d32013-05-03 23:11:079627 session_deps_.socket_factory->AddSocketDataProvider(&data);
9628 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:299629
[email protected]49639fa2011-12-20 23:22:419630 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:299631
danakj1fd259a02016-04-16 03:17:099632 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169633 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:299634
tfarina42834112016-09-22 13:38:209635 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019636 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:299637
9638 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019639 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:169640 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:299641
wezca1070932016-05-26 20:30:529642 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:299643
9644 EXPECT_EQ(302, response->headers->response_code());
9645 std::string url;
9646 EXPECT_TRUE(response->headers->IsRedirect(&url));
9647 EXPECT_EQ("http://login.example.com/", url);
9648}
9649
[email protected]4eddbc732012-08-09 05:40:179650// Test that an HTTPS proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:019651TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaHttpsProxy) {
Ramin Halavatica8d5252018-03-12 05:33:499652 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9653 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299654
9655 HttpRequestInfo request;
9656 request.method = "GET";
bncce36dca22015-04-21 22:11:239657 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109658 request.traffic_annotation =
9659 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299660
9661 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179662 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9663 "Host: www.example.org:443\r\n"
9664 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:299665 };
9666
9667 MockRead data_reads[] = {
9668 MockRead("HTTP/1.1 404 Not Found\r\n"),
9669 MockRead("Content-Length: 23\r\n\r\n"),
9670 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:069671 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:299672 };
9673
Ryan Sleevib8d7ea02018-05-07 20:01:019674 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069675 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:299676
[email protected]bb88e1d32013-05-03 23:11:079677 session_deps_.socket_factory->AddSocketDataProvider(&data);
9678 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:299679
[email protected]49639fa2011-12-20 23:22:419680 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:299681
danakj1fd259a02016-04-16 03:17:099682 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169683 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:299684
tfarina42834112016-09-22 13:38:209685 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019686 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:299687
9688 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019689 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:299690
ttuttle960fcbf2016-04-19 13:26:329691 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:299692}
9693
[email protected]4eddbc732012-08-09 05:40:179694// Test that a SPDY proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:019695TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaSpdyProxy) {
Ramin Halavatica8d5252018-03-12 05:33:499696 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9697 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299698
9699 HttpRequestInfo request;
9700 request.method = "GET";
bncce36dca22015-04-21 22:11:239701 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109702 request.traffic_annotation =
9703 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299704
Ryan Hamilton0239aac2018-05-19 00:03:139705 spdy::SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:239706 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:139707 spdy::SpdySerializedFrame rst(
9708 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:299709 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:419710 CreateMockWrite(conn, 0), CreateMockWrite(rst, 3),
[email protected]511f6f52010-12-17 03:58:299711 };
9712
9713 static const char* const kExtraHeaders[] = {
9714 "location",
9715 "http://login.example.com/",
9716 };
Ryan Hamilton0239aac2018-05-19 00:03:139717 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
Avi Drissman4365a4782018-12-28 19:26:249718 "404", kExtraHeaders, base::size(kExtraHeaders) / 2, 1));
Ryan Hamilton0239aac2018-05-19 00:03:139719 spdy::SpdySerializedFrame body(
Bence Békyd74f4382018-02-20 18:26:199720 spdy_util_.ConstructSpdyDataFrame(1, "The host does not exist", true));
[email protected]511f6f52010-12-17 03:58:299721 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:419722 CreateMockRead(resp, 1), CreateMockRead(body, 2),
rch8e6c6c42015-05-01 14:05:139723 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:299724 };
9725
Ryan Sleevib8d7ea02018-05-07 20:01:019726 SequencedSocketData data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069727 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:369728 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:299729
[email protected]bb88e1d32013-05-03 23:11:079730 session_deps_.socket_factory->AddSocketDataProvider(&data);
9731 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:299732
[email protected]49639fa2011-12-20 23:22:419733 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:299734
danakj1fd259a02016-04-16 03:17:099735 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169736 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:299737
tfarina42834112016-09-22 13:38:209738 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019739 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:299740
9741 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019742 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:299743
ttuttle960fcbf2016-04-19 13:26:329744 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:299745}
9746
[email protected]0c5fb722012-02-28 11:50:359747// Test the request-challenge-retry sequence for basic auth, through
9748// a SPDY proxy over a single SPDY session.
bncd16676a2016-07-20 16:23:019749TEST_F(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:359750 HttpRequestInfo request;
9751 request.method = "GET";
bncce36dca22015-04-21 22:11:239752 request.url = GURL("https://www.example.org/");
[email protected]0c5fb722012-02-28 11:50:359753 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:299754 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:109755 request.traffic_annotation =
9756 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0c5fb722012-02-28 11:50:359757
9758 // Configure against https proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:599759 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499760 ProxyResolutionService::CreateFixedFromPacResult(
9761 "HTTPS myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519762 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:079763 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:099764 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:359765
9766 // Since we have proxy, should try to establish tunnel.
Ryan Hamilton0239aac2018-05-19 00:03:139767 spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:239768 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:139769 spdy::SpdySerializedFrame rst(
9770 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
rdsmithebb50aa2015-11-12 03:44:389771 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]0c5fb722012-02-28 11:50:359772
bnc691fda62016-08-12 00:43:169773 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0c5fb722012-02-28 11:50:359774 // be issuing -- the final header line contains the credentials.
9775 const char* const kAuthCredentials[] = {
9776 "proxy-authorization", "Basic Zm9vOmJhcg==",
9777 };
Ryan Hamilton0239aac2018-05-19 00:03:139778 spdy::SpdySerializedFrame connect2(spdy_util_.ConstructSpdyConnect(
Avi Drissman4365a4782018-12-28 19:26:249779 kAuthCredentials, base::size(kAuthCredentials) / 2, 3, LOWEST,
bncce36dca22015-04-21 22:11:239780 HostPortPair("www.example.org", 443)));
9781 // fetch https://www.example.org/ via HTTP
9782 const char get[] =
9783 "GET / HTTP/1.1\r\n"
9784 "Host: www.example.org\r\n"
9785 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:139786 spdy::SpdySerializedFrame wrapped_get(
Bence Békyd74f4382018-02-20 18:26:199787 spdy_util_.ConstructSpdyDataFrame(3, get, false));
[email protected]0c5fb722012-02-28 11:50:359788
9789 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:419790 CreateMockWrite(req, 0, ASYNC), CreateMockWrite(rst, 2, ASYNC),
9791 CreateMockWrite(connect2, 3), CreateMockWrite(wrapped_get, 5),
[email protected]0c5fb722012-02-28 11:50:359792 };
9793
9794 // The proxy responds to the connect with a 407, using a persistent
9795 // connection.
thestig9d3bb0c2015-01-24 00:49:519796 const char kAuthStatus[] = "407";
[email protected]0c5fb722012-02-28 11:50:359797 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:359798 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
9799 };
Ryan Hamilton0239aac2018-05-19 00:03:139800 spdy::SpdySerializedFrame conn_auth_resp(spdy_util_.ConstructSpdyReplyError(
Avi Drissman4365a4782018-12-28 19:26:249801 kAuthStatus, kAuthChallenge, base::size(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:359802
Ryan Hamilton0239aac2018-05-19 00:03:139803 spdy::SpdySerializedFrame conn_resp(
9804 spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:359805 const char resp[] = "HTTP/1.1 200 OK\r\n"
9806 "Content-Length: 5\r\n\r\n";
9807
Ryan Hamilton0239aac2018-05-19 00:03:139808 spdy::SpdySerializedFrame wrapped_get_resp(
Bence Békyd74f4382018-02-20 18:26:199809 spdy_util_.ConstructSpdyDataFrame(3, resp, false));
Ryan Hamilton0239aac2018-05-19 00:03:139810 spdy::SpdySerializedFrame wrapped_body(
Bence Békyd74f4382018-02-20 18:26:199811 spdy_util_.ConstructSpdyDataFrame(3, "hello", false));
[email protected]0c5fb722012-02-28 11:50:359812 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:419813 CreateMockRead(conn_auth_resp, 1, ASYNC),
9814 CreateMockRead(conn_resp, 4, ASYNC),
9815 CreateMockRead(wrapped_get_resp, 6, ASYNC),
9816 CreateMockRead(wrapped_body, 7, ASYNC),
rch8e6c6c42015-05-01 14:05:139817 MockRead(ASYNC, OK, 8), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:359818 };
9819
Ryan Sleevib8d7ea02018-05-07 20:01:019820 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:079821 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:359822 // Negotiate SPDY to the proxy
9823 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:369824 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:079825 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:359826 // Vanilla SSL to the server
9827 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:079828 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:359829
9830 TestCompletionCallback callback1;
9831
bnc87dcefc2017-05-25 12:47:589832 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:199833 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0c5fb722012-02-28 11:50:359834
9835 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:019836 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:359837
9838 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019839 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:469840 TestNetLogEntry::List entries;
[email protected]0c5fb722012-02-28 11:50:359841 log.GetEntries(&entries);
9842 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:009843 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
9844 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:359845 ExpectLogContainsSomewhere(
9846 entries, pos,
mikecirone8b85c432016-09-08 19:11:009847 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
9848 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:359849
9850 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529851 ASSERT_TRUE(response);
9852 ASSERT_TRUE(response->headers);
[email protected]0c5fb722012-02-28 11:50:359853 EXPECT_EQ(407, response->headers->response_code());
9854 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
wezca1070932016-05-26 20:30:529855 EXPECT_TRUE(response->auth_challenge);
asanka098c0092016-06-16 20:18:439856 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]0c5fb722012-02-28 11:50:359857
9858 TestCompletionCallback callback2;
9859
9860 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
9861 callback2.callback());
robpercival214763f2016-07-01 23:27:019862 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:359863
9864 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:019865 EXPECT_THAT(rv, IsOk());
[email protected]0c5fb722012-02-28 11:50:359866
9867 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529868 ASSERT_TRUE(response);
[email protected]0c5fb722012-02-28 11:50:359869
9870 EXPECT_TRUE(response->headers->IsKeepAlive());
9871 EXPECT_EQ(200, response->headers->response_code());
9872 EXPECT_EQ(5, response->headers->GetContentLength());
9873 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
9874
9875 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:529876 EXPECT_FALSE(response->auth_challenge);
[email protected]0c5fb722012-02-28 11:50:359877
[email protected]029c83b62013-01-24 05:28:209878 LoadTimingInfo load_timing_info;
9879 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
9880 TestLoadTimingNotReusedWithPac(load_timing_info,
9881 CONNECT_TIMING_HAS_SSL_TIMES);
9882
[email protected]0c5fb722012-02-28 11:50:359883 trans.reset();
9884 session->CloseAllConnections();
9885}
9886
[email protected]7c6f7ba2012-04-03 04:09:299887// Test that an explicitly trusted SPDY proxy can push a resource from an
9888// origin that is different from that of its associated resource.
bncd16676a2016-07-20 16:23:019889TEST_F(HttpNetworkTransactionTest, CrossOriginSPDYProxyPush) {
tbansal28e68f82016-02-04 02:56:159890 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:199891 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:159892 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
9893 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]7c6f7ba2012-04-03 04:09:299894 HttpRequestInfo request;
9895 HttpRequestInfo push_request;
Ramin Halavatib5e433e2018-02-07 07:41:109896 request.traffic_annotation =
9897 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7c6f7ba2012-04-03 04:09:299898
[email protected]7c6f7ba2012-04-03 04:09:299899 request.method = "GET";
bncce36dca22015-04-21 22:11:239900 request.url = GURL("http://www.example.org/");
[email protected]7c6f7ba2012-04-03 04:09:299901 push_request.method = "GET";
9902 push_request.url = GURL("http://www.another-origin.com/foo.dat");
Ramin Halavatib5e433e2018-02-07 07:41:109903 push_request.traffic_annotation =
9904 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7c6f7ba2012-04-03 04:09:299905
tbansal28e68f82016-02-04 02:56:159906 // Configure against https proxy server "myproxy:443".
Lily Houghton8c2f97d2018-01-22 05:06:599907 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499908 ProxyResolutionService::CreateFixedFromPacResult(
9909 "HTTPS myproxy:443", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519910 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:079911 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:509912
Eric Roman3d8546a2018-09-10 17:00:529913 session_deps_.proxy_resolution_service->SetProxyDelegate(
9914 proxy_delegate.get());
[email protected]61b4efc2012-04-27 18:12:509915
danakj1fd259a02016-04-16 03:17:099916 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:299917
Ryan Hamilton0239aac2018-05-19 00:03:139918 spdy::SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:459919 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:139920 spdy::SpdySerializedFrame stream2_priority(
tombergan5d22c182017-01-11 02:05:359921 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
[email protected]7c6f7ba2012-04-03 04:09:299922
9923 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:419924 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:359925 CreateMockWrite(stream2_priority, 3, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:299926 };
9927
Ryan Hamilton0239aac2018-05-19 00:03:139928 spdy::SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
Bence Béky7bf94362018-01-10 13:19:369929 NULL, 0, 2, 1, "http://www.another-origin.com/foo.dat"));
9930
Ryan Hamilton0239aac2018-05-19 00:03:139931 spdy::SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:159932 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:299933
Ryan Hamilton0239aac2018-05-19 00:03:139934 spdy::SpdySerializedFrame stream1_body(
9935 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:299936
Ryan Hamilton0239aac2018-05-19 00:03:139937 spdy::SpdySerializedFrame stream2_body(
Bence Békyd74f4382018-02-20 18:26:199938 spdy_util_.ConstructSpdyDataFrame(2, "pushed", true));
[email protected]7c6f7ba2012-04-03 04:09:299939
9940 MockRead spdy_reads[] = {
Bence Béky7bf94362018-01-10 13:19:369941 CreateMockRead(stream2_syn, 1, ASYNC),
9942 CreateMockRead(stream1_reply, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:359943 CreateMockRead(stream1_body, 4, ASYNC),
9944 CreateMockRead(stream2_body, 5, ASYNC),
9945 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
[email protected]7c6f7ba2012-04-03 04:09:299946 };
9947
Ryan Sleevib8d7ea02018-05-07 20:01:019948 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:079949 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:299950 // Negotiate SPDY to the proxy
9951 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:369952 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:079953 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:299954
bnc87dcefc2017-05-25 12:47:589955 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:199956 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7c6f7ba2012-04-03 04:09:299957 TestCompletionCallback callback;
9958 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:019959 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:299960
9961 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019962 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:299963 const HttpResponseInfo* response = trans->GetResponseInfo();
9964
bnc87dcefc2017-05-25 12:47:589965 auto push_trans =
Jeremy Roman0579ed62017-08-29 15:56:199966 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]90499482013-06-01 00:39:509967 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:019968 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:299969
9970 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019971 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:299972 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
9973
wezca1070932016-05-26 20:30:529974 ASSERT_TRUE(response);
[email protected]7c6f7ba2012-04-03 04:09:299975 EXPECT_TRUE(response->headers->IsKeepAlive());
9976
9977 EXPECT_EQ(200, response->headers->response_code());
9978 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
9979
9980 std::string response_data;
9981 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:019982 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:299983 EXPECT_EQ("hello!", response_data);
9984
[email protected]029c83b62013-01-24 05:28:209985 LoadTimingInfo load_timing_info;
9986 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
9987 TestLoadTimingNotReusedWithPac(load_timing_info,
9988 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9989
[email protected]7c6f7ba2012-04-03 04:09:299990 // Verify the pushed stream.
wezca1070932016-05-26 20:30:529991 EXPECT_TRUE(push_response->headers);
[email protected]7c6f7ba2012-04-03 04:09:299992 EXPECT_EQ(200, push_response->headers->response_code());
9993
9994 rv = ReadTransaction(push_trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:019995 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:299996 EXPECT_EQ("pushed", response_data);
9997
[email protected]029c83b62013-01-24 05:28:209998 LoadTimingInfo push_load_timing_info;
9999 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
10000 TestLoadTimingReusedWithPac(push_load_timing_info);
10001 // The transactions should share a socket ID, despite being for different
10002 // origins.
10003 EXPECT_EQ(load_timing_info.socket_log_id,
10004 push_load_timing_info.socket_log_id);
10005
[email protected]7c6f7ba2012-04-03 04:09:2910006 trans.reset();
10007 push_trans.reset();
10008 session->CloseAllConnections();
10009}
10010
[email protected]8c843192012-04-05 07:15:0010011// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
bncd16676a2016-07-20 16:23:0110012TEST_F(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:1510013 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:1910014 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:1510015 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
10016 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]8c843192012-04-05 07:15:0010017 HttpRequestInfo request;
10018
10019 request.method = "GET";
bncce36dca22015-04-21 22:11:2310020 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010021 request.traffic_annotation =
10022 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c843192012-04-05 07:15:0010023
Ramin Halavatica8d5252018-03-12 05:33:4910024 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
10025 "https://myproxy:443", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110026 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710027 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:5010028
10029 // Enable cross-origin push.
Eric Roman3d8546a2018-09-10 17:00:5210030 session_deps_.proxy_resolution_service->SetProxyDelegate(
10031 proxy_delegate.get());
[email protected]61b4efc2012-04-27 18:12:5010032
danakj1fd259a02016-04-16 03:17:0910033 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:0010034
Ryan Hamilton0239aac2018-05-19 00:03:1310035 spdy::SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:4510036 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
[email protected]8c843192012-04-05 07:15:0010037
Ryan Hamilton0239aac2018-05-19 00:03:1310038 spdy::SpdySerializedFrame push_rst(
10039 spdy_util_.ConstructSpdyRstStream(2, spdy::ERROR_CODE_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:0010040
10041 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4110042 CreateMockWrite(stream1_syn, 0, ASYNC), CreateMockWrite(push_rst, 3),
[email protected]8c843192012-04-05 07:15:0010043 };
10044
Ryan Hamilton0239aac2018-05-19 00:03:1310045 spdy::SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:1510046 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:0010047
Ryan Hamilton0239aac2018-05-19 00:03:1310048 spdy::SpdySerializedFrame stream1_body(
10049 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]8c843192012-04-05 07:15:0010050
Ryan Hamilton0239aac2018-05-19 00:03:1310051 spdy::SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
bncb03b1092016-04-06 11:19:5510052 NULL, 0, 2, 1, "https://www.another-origin.com/foo.dat"));
[email protected]8c843192012-04-05 07:15:0010053
10054 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4110055 CreateMockRead(stream1_reply, 1, ASYNC),
10056 CreateMockRead(stream2_syn, 2, ASYNC),
10057 CreateMockRead(stream1_body, 4, ASYNC),
mmenkee24011922015-12-17 22:12:5910058 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
[email protected]8c843192012-04-05 07:15:0010059 };
10060
Ryan Sleevib8d7ea02018-05-07 20:01:0110061 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0710062 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:0010063 // Negotiate SPDY to the proxy
10064 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610065 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0710066 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:0010067
bnc87dcefc2017-05-25 12:47:5810068 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1910069 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]8c843192012-04-05 07:15:0010070 TestCompletionCallback callback;
10071 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0110072 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c843192012-04-05 07:15:0010073
10074 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110075 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:0010076 const HttpResponseInfo* response = trans->GetResponseInfo();
10077
wezca1070932016-05-26 20:30:5210078 ASSERT_TRUE(response);
[email protected]8c843192012-04-05 07:15:0010079 EXPECT_TRUE(response->headers->IsKeepAlive());
10080
10081 EXPECT_EQ(200, response->headers->response_code());
10082 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10083
10084 std::string response_data;
10085 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:0110086 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:0010087 EXPECT_EQ("hello!", response_data);
10088
10089 trans.reset();
10090 session->CloseAllConnections();
10091}
10092
tbansal8ef1d3e2016-02-03 04:05:4210093// Test that an explicitly trusted SPDY proxy can push same-origin HTTPS
10094// resources.
bncd16676a2016-07-20 16:23:0110095TEST_F(HttpNetworkTransactionTest, SameOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:1510096 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:1910097 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:1510098 proxy_delegate->set_trusted_spdy_proxy(
10099 net::ProxyServer::FromURI("myproxy:70", net::ProxyServer::SCHEME_HTTP));
10100
tbansal8ef1d3e2016-02-03 04:05:4210101 HttpRequestInfo request;
10102
10103 request.method = "GET";
10104 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010105 request.traffic_annotation =
10106 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal8ef1d3e2016-02-03 04:05:4210107
10108 // Configure against https proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:4910109 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
10110 "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal8ef1d3e2016-02-03 04:05:4210111 BoundTestNetLog log;
10112 session_deps_.net_log = log.bound().net_log();
10113
10114 // Enable cross-origin push.
Eric Roman3d8546a2018-09-10 17:00:5210115 session_deps_.proxy_resolution_service->SetProxyDelegate(
10116 proxy_delegate.get());
tbansal8ef1d3e2016-02-03 04:05:4210117
danakj1fd259a02016-04-16 03:17:0910118 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
tbansal8ef1d3e2016-02-03 04:05:4210119
Ryan Hamilton0239aac2018-05-19 00:03:1310120 spdy::SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:4510121 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1310122 spdy::SpdySerializedFrame stream2_priority(
tombergan5d22c182017-01-11 02:05:3510123 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
tbansal8ef1d3e2016-02-03 04:05:4210124
10125 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4110126 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:3510127 CreateMockWrite(stream2_priority, 3, ASYNC),
tbansal8ef1d3e2016-02-03 04:05:4210128 };
10129
Ryan Hamilton0239aac2018-05-19 00:03:1310130 spdy::SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:1510131 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:4210132
Ryan Hamilton0239aac2018-05-19 00:03:1310133 spdy::SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
Bence Béky096cf052017-08-08 23:55:3310134 nullptr, 0, 2, 1, "http://www.example.org/foo.dat"));
bnc38dcd392016-02-09 23:19:4910135
Ryan Hamilton0239aac2018-05-19 00:03:1310136 spdy::SpdySerializedFrame stream1_body(
10137 spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:4210138
Ryan Hamilton0239aac2018-05-19 00:03:1310139 spdy::SpdySerializedFrame stream2_reply(
bnc42331402016-07-25 13:36:1510140 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:4210141
Ryan Hamilton0239aac2018-05-19 00:03:1310142 spdy::SpdySerializedFrame stream2_body(
10143 spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:4210144
10145 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4110146 CreateMockRead(stream1_reply, 1, ASYNC),
10147 CreateMockRead(stream2_syn, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:3510148 CreateMockRead(stream1_body, 4, ASYNC),
10149 CreateMockRead(stream2_body, 5, ASYNC),
10150 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
tbansal8ef1d3e2016-02-03 04:05:4210151 };
10152
Ryan Sleevib8d7ea02018-05-07 20:01:0110153 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
tbansal8ef1d3e2016-02-03 04:05:4210154 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
10155 // Negotiate SPDY to the proxy
10156 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610157 proxy.next_proto = kProtoHTTP2;
tbansal8ef1d3e2016-02-03 04:05:4210158 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
10159
bnc87dcefc2017-05-25 12:47:5810160 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1910161 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tbansal8ef1d3e2016-02-03 04:05:4210162 TestCompletionCallback callback;
10163 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0110164 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
tbansal8ef1d3e2016-02-03 04:05:4210165
10166 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110167 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:4210168 const HttpResponseInfo* response = trans->GetResponseInfo();
10169
wezca1070932016-05-26 20:30:5210170 ASSERT_TRUE(response);
tbansal8ef1d3e2016-02-03 04:05:4210171 EXPECT_TRUE(response->headers->IsKeepAlive());
10172
10173 EXPECT_EQ(200, response->headers->response_code());
10174 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10175
10176 std::string response_data;
10177 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:0110178 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:4210179 EXPECT_EQ("hello!", response_data);
10180
10181 trans.reset();
10182 session->CloseAllConnections();
10183}
10184
[email protected]2df19bb2010-08-25 20:13:4610185// Test HTTPS connections to a site with a bad certificate, going through an
10186// HTTPS proxy
bncd16676a2016-07-20 16:23:0110187TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
Ramin Halavatica8d5252018-03-12 05:33:4910188 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
10189 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:4610190
10191 HttpRequestInfo request;
10192 request.method = "GET";
bncce36dca22015-04-21 22:11:2310193 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010194 request.traffic_annotation =
10195 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:4610196
10197 // Attempt to fetch the URL from a server with a bad cert
10198 MockWrite bad_cert_writes[] = {
rsleevidb16bb02015-11-12 23:47:1710199 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
10200 "Host: www.example.org:443\r\n"
10201 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:4610202 };
10203
10204 MockRead bad_cert_reads[] = {
10205 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610206 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:4610207 };
10208
10209 // Attempt to fetch the URL with a good cert
10210 MockWrite good_data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1710211 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
10212 "Host: www.example.org:443\r\n"
10213 "Proxy-Connection: keep-alive\r\n\r\n"),
10214 MockWrite("GET / HTTP/1.1\r\n"
10215 "Host: www.example.org\r\n"
10216 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:4610217 };
10218
10219 MockRead good_cert_reads[] = {
10220 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
10221 MockRead("HTTP/1.0 200 OK\r\n"),
10222 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10223 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610224 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:4610225 };
10226
Ryan Sleevib8d7ea02018-05-07 20:01:0110227 StaticSocketDataProvider ssl_bad_certificate(bad_cert_reads, bad_cert_writes);
10228 StaticSocketDataProvider data(good_cert_reads, good_data_writes);
[email protected]8ddf8322012-02-23 18:08:0610229 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
10230 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:4610231
10232 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:0710233 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10234 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
10235 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:4610236
10237 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:0710238 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10239 session_deps_.socket_factory->AddSocketDataProvider(&data);
10240 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:4610241
[email protected]49639fa2011-12-20 23:22:4110242 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:4610243
danakj1fd259a02016-04-16 03:17:0910244 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610245 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:4610246
tfarina42834112016-09-22 13:38:2010247 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110248 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:4610249
10250 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110251 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]2df19bb2010-08-25 20:13:4610252
bnc691fda62016-08-12 00:43:1610253 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:0110254 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:4610255
10256 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110257 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:4610258
bnc691fda62016-08-12 00:43:1610259 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:4610260
wezca1070932016-05-26 20:30:5210261 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:4610262 EXPECT_EQ(100, response->headers->GetContentLength());
10263}
10264
bncd16676a2016-07-20 16:23:0110265TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:4210266 HttpRequestInfo request;
10267 request.method = "GET";
bncce36dca22015-04-21 22:11:2310268 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:4310269 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
10270 "Chromium Ultra Awesome X Edition");
Ramin Halavatib5e433e2018-02-07 07:41:1010271 request.traffic_annotation =
10272 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210273
danakj1fd259a02016-04-16 03:17:0910274 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610275 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710276
[email protected]1c773ea12009-04-28 19:58:4210277 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310278 MockWrite(
10279 "GET / HTTP/1.1\r\n"
10280 "Host: www.example.org\r\n"
10281 "Connection: keep-alive\r\n"
10282 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210283 };
10284
10285 // Lastly, the server responds with the actual content.
10286 MockRead data_reads[] = {
10287 MockRead("HTTP/1.0 200 OK\r\n"),
10288 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10289 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610290 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210291 };
10292
Ryan Sleevib8d7ea02018-05-07 20:01:0110293 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710294 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210295
[email protected]49639fa2011-12-20 23:22:4110296 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210297
tfarina42834112016-09-22 13:38:2010298 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110299 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210300
10301 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110302 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210303}
10304
bncd16676a2016-07-20 16:23:0110305TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:2910306 HttpRequestInfo request;
10307 request.method = "GET";
bncce36dca22015-04-21 22:11:2310308 request.url = GURL("https://www.example.org/");
[email protected]da81f132010-08-18 23:39:2910309 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
10310 "Chromium Ultra Awesome X Edition");
Ramin Halavatib5e433e2018-02-07 07:41:1010311 request.traffic_annotation =
10312 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]da81f132010-08-18 23:39:2910313
Ramin Halavatica8d5252018-03-12 05:33:4910314 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
10315 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:0910316 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610317 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710318
[email protected]da81f132010-08-18 23:39:2910319 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1710320 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
10321 "Host: www.example.org:443\r\n"
10322 "Proxy-Connection: keep-alive\r\n"
10323 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]da81f132010-08-18 23:39:2910324 };
10325 MockRead data_reads[] = {
10326 // Return an error, so the transaction stops here (this test isn't
10327 // interested in the rest).
10328 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
10329 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
10330 MockRead("Proxy-Connection: close\r\n\r\n"),
10331 };
10332
Ryan Sleevib8d7ea02018-05-07 20:01:0110333 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710334 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:2910335
[email protected]49639fa2011-12-20 23:22:4110336 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:2910337
tfarina42834112016-09-22 13:38:2010338 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110339 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]da81f132010-08-18 23:39:2910340
10341 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110342 EXPECT_THAT(rv, IsOk());
[email protected]da81f132010-08-18 23:39:2910343}
10344
bncd16676a2016-07-20 16:23:0110345TEST_F(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:4210346 HttpRequestInfo request;
10347 request.method = "GET";
bncce36dca22015-04-21 22:11:2310348 request.url = GURL("http://www.example.org/");
[email protected]c10450102011-06-27 09:06:1610349 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
10350 "http://the.previous.site.com/");
Ramin Halavatib5e433e2018-02-07 07:41:1010351 request.traffic_annotation =
10352 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210353
danakj1fd259a02016-04-16 03:17:0910354 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610355 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710356
[email protected]1c773ea12009-04-28 19:58:4210357 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310358 MockWrite(
10359 "GET / HTTP/1.1\r\n"
10360 "Host: www.example.org\r\n"
10361 "Connection: keep-alive\r\n"
10362 "Referer: http://the.previous.site.com/\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210363 };
10364
10365 // Lastly, the server responds with the actual content.
10366 MockRead data_reads[] = {
10367 MockRead("HTTP/1.0 200 OK\r\n"),
10368 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10369 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610370 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210371 };
10372
Ryan Sleevib8d7ea02018-05-07 20:01:0110373 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710374 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210375
[email protected]49639fa2011-12-20 23:22:4110376 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210377
tfarina42834112016-09-22 13:38:2010378 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110379 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210380
10381 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110382 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210383}
10384
bncd16676a2016-07-20 16:23:0110385TEST_F(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:4210386 HttpRequestInfo request;
10387 request.method = "POST";
bncce36dca22015-04-21 22:11:2310388 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010389 request.traffic_annotation =
10390 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210391
danakj1fd259a02016-04-16 03:17:0910392 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610393 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710394
[email protected]1c773ea12009-04-28 19:58:4210395 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310396 MockWrite(
10397 "POST / HTTP/1.1\r\n"
10398 "Host: www.example.org\r\n"
10399 "Connection: keep-alive\r\n"
10400 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210401 };
10402
10403 // Lastly, the server responds with the actual content.
10404 MockRead data_reads[] = {
10405 MockRead("HTTP/1.0 200 OK\r\n"),
10406 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10407 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610408 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210409 };
10410
Ryan Sleevib8d7ea02018-05-07 20:01:0110411 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710412 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210413
[email protected]49639fa2011-12-20 23:22:4110414 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210415
tfarina42834112016-09-22 13:38:2010416 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110417 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210418
10419 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110420 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210421}
10422
bncd16676a2016-07-20 16:23:0110423TEST_F(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:4210424 HttpRequestInfo request;
10425 request.method = "PUT";
bncce36dca22015-04-21 22:11:2310426 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010427 request.traffic_annotation =
10428 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210429
danakj1fd259a02016-04-16 03:17:0910430 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610431 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710432
[email protected]1c773ea12009-04-28 19:58:4210433 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310434 MockWrite(
10435 "PUT / HTTP/1.1\r\n"
10436 "Host: www.example.org\r\n"
10437 "Connection: keep-alive\r\n"
10438 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210439 };
10440
10441 // Lastly, the server responds with the actual content.
10442 MockRead data_reads[] = {
10443 MockRead("HTTP/1.0 200 OK\r\n"),
10444 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10445 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610446 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210447 };
10448
Ryan Sleevib8d7ea02018-05-07 20:01:0110449 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710450 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210451
[email protected]49639fa2011-12-20 23:22:4110452 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210453
tfarina42834112016-09-22 13:38:2010454 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110455 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210456
10457 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110458 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210459}
10460
bncd16676a2016-07-20 16:23:0110461TEST_F(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:4210462 HttpRequestInfo request;
10463 request.method = "HEAD";
bncce36dca22015-04-21 22:11:2310464 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010465 request.traffic_annotation =
10466 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210467
danakj1fd259a02016-04-16 03:17:0910468 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610469 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710470
[email protected]1c773ea12009-04-28 19:58:4210471 MockWrite data_writes[] = {
csharrisonf473dd192015-08-18 13:54:1310472 MockWrite("HEAD / HTTP/1.1\r\n"
10473 "Host: www.example.org\r\n"
10474 "Connection: keep-alive\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210475 };
10476
10477 // Lastly, the server responds with the actual content.
10478 MockRead data_reads[] = {
10479 MockRead("HTTP/1.0 200 OK\r\n"),
10480 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10481 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610482 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210483 };
10484
Ryan Sleevib8d7ea02018-05-07 20:01:0110485 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710486 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210487
[email protected]49639fa2011-12-20 23:22:4110488 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210489
tfarina42834112016-09-22 13:38:2010490 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110491 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210492
10493 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110494 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210495}
10496
bncd16676a2016-07-20 16:23:0110497TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:4210498 HttpRequestInfo request;
10499 request.method = "GET";
bncce36dca22015-04-21 22:11:2310500 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:4210501 request.load_flags = LOAD_BYPASS_CACHE;
Ramin Halavatib5e433e2018-02-07 07:41:1010502 request.traffic_annotation =
10503 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210504
danakj1fd259a02016-04-16 03:17:0910505 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610506 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710507
[email protected]1c773ea12009-04-28 19:58:4210508 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310509 MockWrite(
10510 "GET / HTTP/1.1\r\n"
10511 "Host: www.example.org\r\n"
10512 "Connection: keep-alive\r\n"
10513 "Pragma: no-cache\r\n"
10514 "Cache-Control: no-cache\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210515 };
10516
10517 // Lastly, the server responds with the actual content.
10518 MockRead data_reads[] = {
10519 MockRead("HTTP/1.0 200 OK\r\n"),
10520 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10521 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610522 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210523 };
10524
Ryan Sleevib8d7ea02018-05-07 20:01:0110525 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710526 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210527
[email protected]49639fa2011-12-20 23:22:4110528 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210529
tfarina42834112016-09-22 13:38:2010530 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110531 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210532
10533 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110534 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210535}
10536
bncd16676a2016-07-20 16:23:0110537TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:4210538 HttpRequestInfo request;
10539 request.method = "GET";
bncce36dca22015-04-21 22:11:2310540 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:4210541 request.load_flags = LOAD_VALIDATE_CACHE;
Ramin Halavatib5e433e2018-02-07 07:41:1010542 request.traffic_annotation =
10543 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210544
danakj1fd259a02016-04-16 03:17:0910545 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610546 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710547
[email protected]1c773ea12009-04-28 19:58:4210548 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310549 MockWrite(
10550 "GET / HTTP/1.1\r\n"
10551 "Host: www.example.org\r\n"
10552 "Connection: keep-alive\r\n"
10553 "Cache-Control: max-age=0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210554 };
10555
10556 // Lastly, the server responds with the actual content.
10557 MockRead data_reads[] = {
10558 MockRead("HTTP/1.0 200 OK\r\n"),
10559 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10560 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610561 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210562 };
10563
Ryan Sleevib8d7ea02018-05-07 20:01:0110564 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710565 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210566
[email protected]49639fa2011-12-20 23:22:4110567 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210568
tfarina42834112016-09-22 13:38:2010569 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110570 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210571
10572 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110573 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210574}
10575
bncd16676a2016-07-20 16:23:0110576TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:4210577 HttpRequestInfo request;
10578 request.method = "GET";
bncce36dca22015-04-21 22:11:2310579 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:4310580 request.extra_headers.SetHeader("FooHeader", "Bar");
Ramin Halavatib5e433e2018-02-07 07:41:1010581 request.traffic_annotation =
10582 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210583
danakj1fd259a02016-04-16 03:17:0910584 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610585 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710586
[email protected]1c773ea12009-04-28 19:58:4210587 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310588 MockWrite(
10589 "GET / HTTP/1.1\r\n"
10590 "Host: www.example.org\r\n"
10591 "Connection: keep-alive\r\n"
10592 "FooHeader: Bar\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210593 };
10594
10595 // Lastly, the server responds with the actual content.
10596 MockRead data_reads[] = {
10597 MockRead("HTTP/1.0 200 OK\r\n"),
10598 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10599 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610600 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210601 };
10602
Ryan Sleevib8d7ea02018-05-07 20:01:0110603 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710604 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210605
[email protected]49639fa2011-12-20 23:22:4110606 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210607
tfarina42834112016-09-22 13:38:2010608 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110609 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210610
10611 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110612 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210613}
10614
bncd16676a2016-07-20 16:23:0110615TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:4710616 HttpRequestInfo request;
10617 request.method = "GET";
bncce36dca22015-04-21 22:11:2310618 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:4310619 request.extra_headers.SetHeader("referer", "www.foo.com");
10620 request.extra_headers.SetHeader("hEllo", "Kitty");
10621 request.extra_headers.SetHeader("FoO", "bar");
Ramin Halavatib5e433e2018-02-07 07:41:1010622 request.traffic_annotation =
10623 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]270c6412010-03-29 22:02:4710624
danakj1fd259a02016-04-16 03:17:0910625 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610626 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710627
[email protected]270c6412010-03-29 22:02:4710628 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310629 MockWrite(
10630 "GET / HTTP/1.1\r\n"
10631 "Host: www.example.org\r\n"
10632 "Connection: keep-alive\r\n"
10633 "referer: www.foo.com\r\n"
10634 "hEllo: Kitty\r\n"
10635 "FoO: bar\r\n\r\n"),
[email protected]270c6412010-03-29 22:02:4710636 };
10637
10638 // Lastly, the server responds with the actual content.
10639 MockRead data_reads[] = {
10640 MockRead("HTTP/1.0 200 OK\r\n"),
10641 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10642 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610643 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:4710644 };
10645
Ryan Sleevib8d7ea02018-05-07 20:01:0110646 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710647 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:4710648
[email protected]49639fa2011-12-20 23:22:4110649 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:4710650
tfarina42834112016-09-22 13:38:2010651 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110652 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]270c6412010-03-29 22:02:4710653
10654 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110655 EXPECT_THAT(rv, IsOk());
[email protected]270c6412010-03-29 22:02:4710656}
10657
bncd16676a2016-07-20 16:23:0110658TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:2710659 HttpRequestInfo request;
10660 request.method = "GET";
bncce36dca22015-04-21 22:11:2310661 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010662 request.traffic_annotation =
10663 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710664
Lily Houghton8c2f97d2018-01-22 05:06:5910665 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910666 ProxyResolutionService::CreateFixedFromPacResult(
10667 "SOCKS myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110668 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710669 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:0210670
danakj1fd259a02016-04-16 03:17:0910671 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610672 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:0210673
[email protected]3cd17242009-06-23 02:59:0210674 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
10675 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
10676
10677 MockWrite data_writes[] = {
Avi Drissman4365a4782018-12-28 19:26:2410678 MockWrite(ASYNC, write_buffer, base::size(write_buffer)),
10679 MockWrite("GET / HTTP/1.1\r\n"
10680 "Host: www.example.org\r\n"
10681 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:0210682
10683 MockRead data_reads[] = {
Avi Drissman4365a4782018-12-28 19:26:2410684 MockRead(ASYNC, read_buffer, base::size(read_buffer)),
10685 MockRead("HTTP/1.0 200 OK\r\n"),
10686 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
10687 MockRead("Payload"), MockRead(SYNCHRONOUS, OK)};
[email protected]3cd17242009-06-23 02:59:0210688
Ryan Sleevib8d7ea02018-05-07 20:01:0110689 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710690 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:0210691
[email protected]49639fa2011-12-20 23:22:4110692 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:0210693
tfarina42834112016-09-22 13:38:2010694 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110695 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:0210696
10697 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110698 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0210699
bnc691fda62016-08-12 00:43:1610700 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210701 ASSERT_TRUE(response);
[email protected]3cd17242009-06-23 02:59:0210702
tbansal2ecbbc72016-10-06 17:15:4710703 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]029c83b62013-01-24 05:28:2010704 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1610705 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2010706 TestLoadTimingNotReusedWithPac(load_timing_info,
10707 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
10708
[email protected]3cd17242009-06-23 02:59:0210709 std::string response_text;
bnc691fda62016-08-12 00:43:1610710 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0110711 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0210712 EXPECT_EQ("Payload", response_text);
10713}
10714
bncd16676a2016-07-20 16:23:0110715TEST_F(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:2710716 HttpRequestInfo request;
10717 request.method = "GET";
bncce36dca22015-04-21 22:11:2310718 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010719 request.traffic_annotation =
10720 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710721
Lily Houghton8c2f97d2018-01-22 05:06:5910722 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910723 ProxyResolutionService::CreateFixedFromPacResult(
10724 "SOCKS myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110725 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710726 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:0210727
danakj1fd259a02016-04-16 03:17:0910728 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610729 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:0210730
[email protected]3cd17242009-06-23 02:59:0210731 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
10732 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
10733
10734 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310735 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
Avi Drissman4365a4782018-12-28 19:26:2410736 base::size(write_buffer)),
10737 MockWrite("GET / HTTP/1.1\r\n"
10738 "Host: www.example.org\r\n"
10739 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:0210740
10741 MockRead data_reads[] = {
Avi Drissman4365a4782018-12-28 19:26:2410742 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
10743 base::size(read_buffer)),
10744 MockRead("HTTP/1.0 200 OK\r\n"),
10745 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
10746 MockRead("Payload"), MockRead(SYNCHRONOUS, OK)};
[email protected]e0c27be2009-07-15 13:09:3510747
Ryan Sleevib8d7ea02018-05-07 20:01:0110748 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710749 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:3510750
[email protected]8ddf8322012-02-23 18:08:0610751 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710752 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:3510753
[email protected]49639fa2011-12-20 23:22:4110754 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:3510755
tfarina42834112016-09-22 13:38:2010756 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110757 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:3510758
10759 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110760 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3510761
[email protected]029c83b62013-01-24 05:28:2010762 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1610763 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2010764 TestLoadTimingNotReusedWithPac(load_timing_info,
10765 CONNECT_TIMING_HAS_SSL_TIMES);
10766
bnc691fda62016-08-12 00:43:1610767 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210768 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:4710769 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:3510770
10771 std::string response_text;
bnc691fda62016-08-12 00:43:1610772 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0110773 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3510774 EXPECT_EQ("Payload", response_text);
10775}
10776
bncd16676a2016-07-20 16:23:0110777TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:2010778 HttpRequestInfo request;
10779 request.method = "GET";
bncce36dca22015-04-21 22:11:2310780 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010781 request.traffic_annotation =
10782 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:2010783
Ramin Halavatica8d5252018-03-12 05:33:4910784 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
10785 "socks4://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]029c83b62013-01-24 05:28:2010788
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]029c83b62013-01-24 05:28:2010791
10792 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
10793 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
10794
10795 MockWrite data_writes[] = {
Avi Drissman4365a4782018-12-28 19:26:2410796 MockWrite(ASYNC, write_buffer, base::size(write_buffer)),
10797 MockWrite("GET / HTTP/1.1\r\n"
10798 "Host: www.example.org\r\n"
10799 "Connection: keep-alive\r\n\r\n")};
[email protected]029c83b62013-01-24 05:28:2010800
10801 MockRead data_reads[] = {
Avi Drissman4365a4782018-12-28 19:26:2410802 MockRead(ASYNC, read_buffer, base::size(read_buffer)),
10803 MockRead("HTTP/1.0 200 OK\r\n"),
10804 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
10805 MockRead("Payload"), MockRead(SYNCHRONOUS, OK)};
[email protected]029c83b62013-01-24 05:28:2010806
Ryan Sleevib8d7ea02018-05-07 20:01:0110807 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710808 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:2010809
10810 TestCompletionCallback callback;
10811
tfarina42834112016-09-22 13:38:2010812 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110813 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:2010814
10815 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110816 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:2010817
bnc691fda62016-08-12 00:43:1610818 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210819 ASSERT_TRUE(response);
[email protected]029c83b62013-01-24 05:28:2010820
10821 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1610822 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2010823 TestLoadTimingNotReused(load_timing_info,
10824 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
10825
10826 std::string response_text;
bnc691fda62016-08-12 00:43:1610827 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0110828 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:2010829 EXPECT_EQ("Payload", response_text);
10830}
10831
bncd16676a2016-07-20 16:23:0110832TEST_F(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:2710833 HttpRequestInfo request;
10834 request.method = "GET";
bncce36dca22015-04-21 22:11:2310835 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010836 request.traffic_annotation =
10837 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710838
Lily Houghton8c2f97d2018-01-22 05:06:5910839 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910840 ProxyResolutionService::CreateFixedFromPacResult(
10841 "SOCKS5 myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110842 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710843 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:3510844
danakj1fd259a02016-04-16 03:17:0910845 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610846 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:3510847
[email protected]e0c27be2009-07-15 13:09:3510848 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
10849 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:3710850 const char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:2310851 0x05, // Version
10852 0x01, // Command (CONNECT)
10853 0x00, // Reserved.
10854 0x03, // Address type (DOMAINNAME).
10855 0x0F, // Length of domain (15)
10856 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
10857 '.', 'o', 'r', 'g', 0x00, 0x50, // 16-bit port (80)
[email protected]f209dba2009-12-18 00:24:3710858 };
[email protected]e0c27be2009-07-15 13:09:3510859 const char kSOCKS5OkResponse[] =
10860 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
10861
10862 MockWrite data_writes[] = {
Avi Drissman4365a4782018-12-28 19:26:2410863 MockWrite(ASYNC, kSOCKS5GreetRequest, base::size(kSOCKS5GreetRequest)),
10864 MockWrite(ASYNC, kSOCKS5OkRequest, base::size(kSOCKS5OkRequest)),
10865 MockWrite("GET / HTTP/1.1\r\n"
10866 "Host: www.example.org\r\n"
10867 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:3510868
10869 MockRead data_reads[] = {
Avi Drissman4365a4782018-12-28 19:26:2410870 MockRead(ASYNC, kSOCKS5GreetResponse, base::size(kSOCKS5GreetResponse)),
10871 MockRead(ASYNC, kSOCKS5OkResponse, base::size(kSOCKS5OkResponse)),
10872 MockRead("HTTP/1.0 200 OK\r\n"),
10873 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
10874 MockRead("Payload"),
10875 MockRead(SYNCHRONOUS, OK)};
[email protected]e0c27be2009-07-15 13:09:3510876
Ryan Sleevib8d7ea02018-05-07 20:01:0110877 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710878 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:3510879
[email protected]49639fa2011-12-20 23:22:4110880 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:3510881
tfarina42834112016-09-22 13:38:2010882 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110883 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:3510884
10885 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110886 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3510887
bnc691fda62016-08-12 00:43:1610888 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210889 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:4710890 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:3510891
[email protected]029c83b62013-01-24 05:28:2010892 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1610893 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2010894 TestLoadTimingNotReusedWithPac(load_timing_info,
10895 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
10896
[email protected]e0c27be2009-07-15 13:09:3510897 std::string response_text;
bnc691fda62016-08-12 00:43:1610898 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0110899 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3510900 EXPECT_EQ("Payload", response_text);
10901}
10902
bncd16676a2016-07-20 16:23:0110903TEST_F(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:2710904 HttpRequestInfo request;
10905 request.method = "GET";
bncce36dca22015-04-21 22:11:2310906 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010907 request.traffic_annotation =
10908 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710909
Lily Houghton8c2f97d2018-01-22 05:06:5910910 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910911 ProxyResolutionService::CreateFixedFromPacResult(
10912 "SOCKS5 myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110913 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710914 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:3510915
danakj1fd259a02016-04-16 03:17:0910916 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610917 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:3510918
[email protected]e0c27be2009-07-15 13:09:3510919 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
10920 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:3710921 const unsigned char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:2310922 0x05, // Version
10923 0x01, // Command (CONNECT)
10924 0x00, // Reserved.
10925 0x03, // Address type (DOMAINNAME).
10926 0x0F, // Length of domain (15)
10927 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
10928 '.', 'o', 'r', 'g', 0x01, 0xBB, // 16-bit port (443)
[email protected]f209dba2009-12-18 00:24:3710929 };
10930
[email protected]e0c27be2009-07-15 13:09:3510931 const char kSOCKS5OkResponse[] =
10932 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
10933
10934 MockWrite data_writes[] = {
Avi Drissman4365a4782018-12-28 19:26:2410935 MockWrite(ASYNC, kSOCKS5GreetRequest, base::size(kSOCKS5GreetRequest)),
bncce36dca22015-04-21 22:11:2310936 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
Avi Drissman4365a4782018-12-28 19:26:2410937 base::size(kSOCKS5OkRequest)),
10938 MockWrite("GET / HTTP/1.1\r\n"
10939 "Host: www.example.org\r\n"
10940 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:3510941
10942 MockRead data_reads[] = {
Avi Drissman4365a4782018-12-28 19:26:2410943 MockRead(ASYNC, kSOCKS5GreetResponse, base::size(kSOCKS5GreetResponse)),
10944 MockRead(ASYNC, kSOCKS5OkResponse, base::size(kSOCKS5OkResponse)),
10945 MockRead("HTTP/1.0 200 OK\r\n"),
10946 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
10947 MockRead("Payload"),
10948 MockRead(SYNCHRONOUS, OK)};
[email protected]3cd17242009-06-23 02:59:0210949
Ryan Sleevib8d7ea02018-05-07 20:01:0110950 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710951 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:0210952
[email protected]8ddf8322012-02-23 18:08:0610953 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710954 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:0210955
[email protected]49639fa2011-12-20 23:22:4110956 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:0210957
tfarina42834112016-09-22 13:38:2010958 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110959 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:0210960
10961 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110962 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0210963
bnc691fda62016-08-12 00:43:1610964 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210965 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:4710966 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]3cd17242009-06-23 02:59:0210967
[email protected]029c83b62013-01-24 05:28:2010968 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1610969 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2010970 TestLoadTimingNotReusedWithPac(load_timing_info,
10971 CONNECT_TIMING_HAS_SSL_TIMES);
10972
[email protected]3cd17242009-06-23 02:59:0210973 std::string response_text;
bnc691fda62016-08-12 00:43:1610974 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0110975 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0210976 EXPECT_EQ("Payload", response_text);
10977}
10978
[email protected]448d4ca52012-03-04 04:12:2310979namespace {
10980
[email protected]04e5be32009-06-26 20:00:3110981// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:0610982
10983struct GroupNameTest {
10984 std::string proxy_server;
10985 std::string url;
10986 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:1810987 bool ssl;
[email protected]2d731a32010-04-29 01:04:0610988};
10989
danakj1fd259a02016-04-16 03:17:0910990std::unique_ptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]bb88e1d32013-05-03 23:11:0710991 SpdySessionDependencies* session_deps_) {
danakj1fd259a02016-04-16 03:17:0910992 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:0610993
bnc525e175a2016-06-20 12:36:4010994 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310995 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110996 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnc7dc7e1b42015-07-28 14:43:1210997 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110998 http_server_properties->SetHttp2AlternativeService(
bncaa60ff402016-06-22 19:12:4210999 url::SchemeHostPort("https", "host.with.alternate", 443),
zhongyi3d4a55e72016-04-22 20:36:4611000 alternative_service, expiration);
[email protected]2d731a32010-04-29 01:04:0611001
11002 return session;
11003}
11004
mmenkee65e7af2015-10-13 17:16:4211005int GroupNameTransactionHelper(const std::string& url,
11006 HttpNetworkSession* session) {
[email protected]2d731a32010-04-29 01:04:0611007 HttpRequestInfo request;
11008 request.method = "GET";
11009 request.url = GURL(url);
Ramin Halavatib5e433e2018-02-07 07:41:1011010 request.traffic_annotation =
11011 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d731a32010-04-29 01:04:0611012
bnc691fda62016-08-12 00:43:1611013 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
[email protected]cb9bf6ca2011-01-28 13:15:2711014
[email protected]49639fa2011-12-20 23:22:4111015 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:0611016
11017 // We do not complete this request, the dtor will clean the transaction up.
tfarina42834112016-09-22 13:38:2011018 return trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]2d731a32010-04-29 01:04:0611019}
11020
[email protected]448d4ca52012-03-04 04:12:2311021} // namespace
11022
bncd16676a2016-07-20 16:23:0111023TEST_F(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:0611024 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:2311025 {
11026 "", // unused
11027 "http://www.example.org/direct",
11028 "www.example.org:80",
11029 false,
11030 },
11031 {
11032 "", // unused
11033 "http://[2001:1418:13:1::25]/direct",
11034 "[2001:1418:13:1::25]:80",
11035 false,
11036 },
[email protected]04e5be32009-06-26 20:00:3111037
bncce36dca22015-04-21 22:11:2311038 // SSL Tests
11039 {
11040 "", // unused
11041 "https://www.example.org/direct_ssl",
11042 "ssl/www.example.org:443",
11043 true,
11044 },
11045 {
11046 "", // unused
11047 "https://[2001:1418:13:1::25]/direct",
11048 "ssl/[2001:1418:13:1::25]:443",
11049 true,
11050 },
11051 {
11052 "", // unused
bncaa60ff402016-06-22 19:12:4211053 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:2311054 "ssl/host.with.alternate:443",
11055 true,
11056 },
[email protected]2d731a32010-04-29 01:04:0611057 };
[email protected]2ff8b312010-04-26 22:20:5411058
Avi Drissman4365a4782018-12-28 19:26:2411059 for (size_t i = 0; i < base::size(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5911060 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4911061 ProxyResolutionService::CreateFixed(tests[i].proxy_server,
11062 TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:0911063 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:4011064 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:0611065
mmenkee65e7af2015-10-13 17:16:4211066 HttpNetworkSessionPeer peer(session.get());
[email protected]ab739042011-04-07 15:22:2811067 CaptureGroupNameTransportSocketPool* transport_conn_pool =
bnc87dcefc2017-05-25 12:47:5811068 new CaptureGroupNameTransportSocketPool(nullptr, nullptr);
[email protected]2431756e2010-09-29 20:26:1311069 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
bnc87dcefc2017-05-25 12:47:5811070 new CaptureGroupNameSSLSocketPool(nullptr, nullptr);
Jeremy Roman0579ed62017-08-29 15:56:1911071 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
[email protected]a42dbd142011-11-17 16:42:0211072 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
11073 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
dchengc7eeda422015-12-26 03:56:4811074 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:0611075
11076 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:4211077 GroupNameTransactionHelper(tests[i].url, session.get()));
Tarun Bansal162eabe52018-01-20 01:16:3911078 if (tests[i].ssl) {
[email protected]e60e47a2010-07-14 03:37:1811079 EXPECT_EQ(tests[i].expected_group_name,
11080 ssl_conn_pool->last_group_name_received());
Tarun Bansal162eabe52018-01-20 01:16:3911081 } else {
[email protected]e60e47a2010-07-14 03:37:1811082 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:2811083 transport_conn_pool->last_group_name_received());
Tarun Bansal162eabe52018-01-20 01:16:3911084 }
11085 // When SSL proxy is in use, socket must be requested from |ssl_conn_pool|.
11086 EXPECT_EQ(tests[i].ssl, ssl_conn_pool->socket_requested());
11087 // When SSL proxy is not in use, socket must be requested from
11088 // |transport_conn_pool|.
11089 EXPECT_EQ(!tests[i].ssl, transport_conn_pool->socket_requested());
[email protected]2d731a32010-04-29 01:04:0611090 }
[email protected]2d731a32010-04-29 01:04:0611091}
11092
bncd16676a2016-07-20 16:23:0111093TEST_F(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:0611094 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:2311095 {
Matt Menked1eb6d42018-01-17 04:54:0611096 "http_proxy", "http://www.example.org/http_proxy_normal",
11097 "http_proxy/www.example.org:80", false,
bncce36dca22015-04-21 22:11:2311098 },
[email protected]2d731a32010-04-29 01:04:0611099
bncce36dca22015-04-21 22:11:2311100 // SSL Tests
11101 {
Matt Menked1eb6d42018-01-17 04:54:0611102 "http_proxy", "https://www.example.org/http_connect_ssl",
11103 "http_proxy/ssl/www.example.org:443", true,
bncce36dca22015-04-21 22:11:2311104 },
[email protected]af3490e2010-10-16 21:02:2911105
bncce36dca22015-04-21 22:11:2311106 {
Matt Menked1eb6d42018-01-17 04:54:0611107 "http_proxy", "https://host.with.alternate/direct",
11108 "http_proxy/ssl/host.with.alternate:443", true,
bncce36dca22015-04-21 22:11:2311109 },
[email protected]45499252013-01-23 17:12:5611110
bncce36dca22015-04-21 22:11:2311111 {
Matt Menked1eb6d42018-01-17 04:54:0611112 "http_proxy", "ftp://ftp.google.com/http_proxy_normal",
11113 "http_proxy/ftp/ftp.google.com:21", false,
bncce36dca22015-04-21 22:11:2311114 },
[email protected]2d731a32010-04-29 01:04:0611115 };
11116
Avi Drissman4365a4782018-12-28 19:26:2411117 for (size_t i = 0; i < base::size(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5911118 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4911119 ProxyResolutionService::CreateFixed(tests[i].proxy_server,
11120 TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:0911121 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:4011122 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:0611123
mmenkee65e7af2015-10-13 17:16:4211124 HttpNetworkSessionPeer peer(session.get());
[email protected]2d731a32010-04-29 01:04:0611125
Matt Menkee8648fa2019-01-17 16:47:0711126 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
11127 HostPortPair("http_proxy", 80));
[email protected]2431756e2010-09-29 20:26:1311128 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:3411129 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:1311130 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:3411131 new CaptureGroupNameSSLSocketPool(NULL, NULL);
Jeremy Roman0579ed62017-08-29 15:56:1911132 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
aviadef3442016-10-03 18:50:3911133 mock_pool_manager->SetSocketPoolForHTTPProxy(
Matt Menkee8648fa2019-01-17 16:47:0711134 proxy_server, base::WrapUnique(http_proxy_pool));
aviadef3442016-10-03 18:50:3911135 mock_pool_manager->SetSocketPoolForSSLWithProxy(
Matt Menkee8648fa2019-01-17 16:47:0711136 proxy_server, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:4811137 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:0611138
11139 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:4211140 GroupNameTransactionHelper(tests[i].url, session.get()));
Matt Menkee8648fa2019-01-17 16:47:0711141 if (tests[i].ssl) {
[email protected]e60e47a2010-07-14 03:37:1811142 EXPECT_EQ(tests[i].expected_group_name,
11143 ssl_conn_pool->last_group_name_received());
Matt Menkee8648fa2019-01-17 16:47:0711144 } else {
[email protected]e60e47a2010-07-14 03:37:1811145 EXPECT_EQ(tests[i].expected_group_name,
11146 http_proxy_pool->last_group_name_received());
Matt Menkee8648fa2019-01-17 16:47:0711147 }
[email protected]2d731a32010-04-29 01:04:0611148 }
[email protected]2d731a32010-04-29 01:04:0611149}
11150
bncd16676a2016-07-20 16:23:0111151TEST_F(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:0611152 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:2311153 {
11154 "socks4://socks_proxy:1080",
11155 "http://www.example.org/socks4_direct",
11156 "socks4/www.example.org:80",
11157 false,
11158 },
11159 {
11160 "socks5://socks_proxy:1080",
11161 "http://www.example.org/socks5_direct",
11162 "socks5/www.example.org:80",
11163 false,
11164 },
[email protected]2d731a32010-04-29 01:04:0611165
bncce36dca22015-04-21 22:11:2311166 // SSL Tests
11167 {
11168 "socks4://socks_proxy:1080",
11169 "https://www.example.org/socks4_ssl",
11170 "socks4/ssl/www.example.org:443",
11171 true,
11172 },
11173 {
11174 "socks5://socks_proxy:1080",
11175 "https://www.example.org/socks5_ssl",
11176 "socks5/ssl/www.example.org:443",
11177 true,
11178 },
[email protected]af3490e2010-10-16 21:02:2911179
bncce36dca22015-04-21 22:11:2311180 {
11181 "socks4://socks_proxy:1080",
bncaa60ff402016-06-22 19:12:4211182 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:2311183 "socks4/ssl/host.with.alternate:443",
11184 true,
11185 },
[email protected]04e5be32009-06-26 20:00:3111186 };
11187
Avi Drissman4365a4782018-12-28 19:26:2411188 for (size_t i = 0; i < base::size(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5911189 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4911190 ProxyResolutionService::CreateFixed(tests[i].proxy_server,
11191 TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:0911192 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:4011193 SetupSessionForGroupNameTests(&session_deps_));
[email protected]8b114dd72011-03-25 05:33:0211194
mmenkee65e7af2015-10-13 17:16:4211195 HttpNetworkSessionPeer peer(session.get());
[email protected]04e5be32009-06-26 20:00:3111196
Matt Menkee8648fa2019-01-17 16:47:0711197 ProxyServer proxy_server(
11198 ProxyServer::FromURI(tests[i].proxy_server, ProxyServer::SCHEME_HTTP));
11199 ASSERT_TRUE(proxy_server.is_valid());
[email protected]2431756e2010-09-29 20:26:1311200 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:3411201 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:1311202 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:3411203 new CaptureGroupNameSSLSocketPool(NULL, NULL);
Jeremy Roman0579ed62017-08-29 15:56:1911204 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
aviadef3442016-10-03 18:50:3911205 mock_pool_manager->SetSocketPoolForSOCKSProxy(
Matt Menkee8648fa2019-01-17 16:47:0711206 proxy_server, base::WrapUnique(socks_conn_pool));
aviadef3442016-10-03 18:50:3911207 mock_pool_manager->SetSocketPoolForSSLWithProxy(
Matt Menkee8648fa2019-01-17 16:47:0711208 proxy_server, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:4811209 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]04e5be32009-06-26 20:00:3111210
bnc691fda62016-08-12 00:43:1611211 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]04e5be32009-06-26 20:00:3111212
[email protected]2d731a32010-04-29 01:04:0611213 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:4211214 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:1811215 if (tests[i].ssl)
11216 EXPECT_EQ(tests[i].expected_group_name,
11217 ssl_conn_pool->last_group_name_received());
11218 else
11219 EXPECT_EQ(tests[i].expected_group_name,
11220 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:3111221 }
11222}
11223
bncd16676a2016-07-20 16:23:0111224TEST_F(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:2711225 HttpRequestInfo request;
11226 request.method = "GET";
bncce36dca22015-04-21 22:11:2311227 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011228 request.traffic_annotation =
11229 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2711230
Ramin Halavatica8d5252018-03-12 05:33:4911231 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
11232 "myproxy:70;foobar:80", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]b59ff372009-07-15 22:04:3211233
[email protected]69719062010-01-05 20:09:2111234 // This simulates failure resolving all hostnames; that means we will fail
11235 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:0711236 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:3211237
danakj1fd259a02016-04-16 03:17:0911238 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611239 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]9172a982009-06-06 00:30:2511240
[email protected]49639fa2011-12-20 23:22:4111241 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:2511242
tfarina42834112016-09-22 13:38:2011243 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111244 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9172a982009-06-06 00:30:2511245
[email protected]9172a982009-06-06 00:30:2511246 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111247 EXPECT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]9172a982009-06-06 00:30:2511248}
11249
Miriam Gershenson2a01b162018-03-22 22:54:4711250// LOAD_BYPASS_CACHE should trigger the host cache bypass.
11251TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh) {
[email protected]cb9bf6ca2011-01-28 13:15:2711252 // Issue a request, asking to bypass the cache(s).
maksim.sisov31452af2016-07-27 06:38:1011253 HttpRequestInfo request_info;
11254 request_info.method = "GET";
Miriam Gershenson2a01b162018-03-22 22:54:4711255 request_info.load_flags = LOAD_BYPASS_CACHE;
maksim.sisov31452af2016-07-27 06:38:1011256 request_info.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011257 request_info.traffic_annotation =
11258 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2711259
[email protected]a2c2fb92009-07-18 07:31:0411260 // Select a host resolver that does caching.
Jeremy Roman0579ed62017-08-29 15:56:1911261 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
[email protected]b59ff372009-07-15 22:04:3211262
danakj1fd259a02016-04-16 03:17:0911263 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611264 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3b9cca42009-06-16 01:08:2811265
bncce36dca22015-04-21 22:11:2311266 // Warm up the host cache so it has an entry for "www.example.org".
[email protected]3b9cca42009-06-16 01:08:2811267 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:2911268 TestCompletionCallback callback;
maksim.sisov31452af2016-07-27 06:38:1011269 std::unique_ptr<HostResolver::Request> request1;
[email protected]bb88e1d32013-05-03 23:11:0711270 int rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:2311271 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:1011272 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request1,
tfarina42834112016-09-22 13:38:2011273 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111274 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4711275 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111276 EXPECT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:2811277
11278 // Verify that it was added to host cache, by doing a subsequent async lookup
11279 // and confirming it completes synchronously.
maksim.sisov31452af2016-07-27 06:38:1011280 std::unique_ptr<HostResolver::Request> request2;
[email protected]bb88e1d32013-05-03 23:11:0711281 rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:2311282 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:1011283 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request2,
tfarina42834112016-09-22 13:38:2011284 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111285 ASSERT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:2811286
bncce36dca22015-04-21 22:11:2311287 // Inject a failure the next time that "www.example.org" is resolved. This way
[email protected]3b9cca42009-06-16 01:08:2811288 // we can tell if the next lookup hit the cache, or the "network".
11289 // (cache --> success, "network" --> failure).
bncce36dca22015-04-21 22:11:2311290 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.example.org");
[email protected]3b9cca42009-06-16 01:08:2811291
11292 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
11293 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:0611294 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
Ryan Sleevib8d7ea02018-05-07 20:01:0111295 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711296 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:2811297
[email protected]3b9cca42009-06-16 01:08:2811298 // Run the request.
tfarina42834112016-09-22 13:38:2011299 rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111300 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]49639fa2011-12-20 23:22:4111301 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:2811302
11303 // If we bypassed the cache, we would have gotten a failure while resolving
bncce36dca22015-04-21 22:11:2311304 // "www.example.org".
robpercival214763f2016-07-01 23:27:0111305 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]3b9cca42009-06-16 01:08:2811306}
11307
[email protected]0877e3d2009-10-17 22:29:5711308// Make sure we can handle an error when writing the request.
bncd16676a2016-07-20 16:23:0111309TEST_F(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:5711310 HttpRequestInfo request;
11311 request.method = "GET";
11312 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:1011313 request.traffic_annotation =
11314 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5711315
11316 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:0611317 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:5711318 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111319 StaticSocketDataProvider data(base::span<MockRead>(), write_failure);
[email protected]bb88e1d32013-05-03 23:11:0711320 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:0911321 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5711322
[email protected]49639fa2011-12-20 23:22:4111323 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5711324
bnc691fda62016-08-12 00:43:1611325 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5711326
tfarina42834112016-09-22 13:38:2011327 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111328 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5711329
11330 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111331 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:5911332
11333 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1611334 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5911335 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:5711336}
11337
zmo9528c9f42015-08-04 22:12:0811338// Check that a connection closed after the start of the headers finishes ok.
bncd16676a2016-07-20 16:23:0111339TEST_F(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:5711340 HttpRequestInfo request;
11341 request.method = "GET";
11342 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:1011343 request.traffic_annotation =
11344 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5711345
11346 MockRead data_reads[] = {
11347 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:0611348 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:5711349 };
11350
Ryan Sleevib8d7ea02018-05-07 20:01:0111351 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711352 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:0911353 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5711354
[email protected]49639fa2011-12-20 23:22:4111355 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5711356
bnc691fda62016-08-12 00:43:1611357 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5711358
tfarina42834112016-09-22 13:38:2011359 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111360 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5711361
11362 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111363 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:0811364
bnc691fda62016-08-12 00:43:1611365 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211366 ASSERT_TRUE(response);
zmo9528c9f42015-08-04 22:12:0811367
wezca1070932016-05-26 20:30:5211368 EXPECT_TRUE(response->headers);
zmo9528c9f42015-08-04 22:12:0811369 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
11370
11371 std::string response_data;
bnc691fda62016-08-12 00:43:1611372 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0111373 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:0811374 EXPECT_EQ("", response_data);
ttuttled9dbc652015-09-29 20:00:5911375
11376 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1611377 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5911378 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:5711379}
11380
11381// Make sure that a dropped connection while draining the body for auth
11382// restart does the right thing.
bncd16676a2016-07-20 16:23:0111383TEST_F(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:5711384 HttpRequestInfo request;
11385 request.method = "GET";
bncce36dca22015-04-21 22:11:2311386 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011387 request.traffic_annotation =
11388 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5711389
11390 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2311391 MockWrite(
11392 "GET / HTTP/1.1\r\n"
11393 "Host: www.example.org\r\n"
11394 "Connection: keep-alive\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:5711395 };
11396
11397 MockRead data_reads1[] = {
11398 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
11399 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
11400 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11401 MockRead("Content-Length: 14\r\n\r\n"),
11402 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:0611403 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:5711404 };
11405
Ryan Sleevib8d7ea02018-05-07 20:01:0111406 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:0711407 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:5711408
bnc691fda62016-08-12 00:43:1611409 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0877e3d2009-10-17 22:29:5711410 // be issuing -- the final header line contains the credentials.
11411 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:2311412 MockWrite(
11413 "GET / HTTP/1.1\r\n"
11414 "Host: www.example.org\r\n"
11415 "Connection: keep-alive\r\n"
11416 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:5711417 };
11418
11419 // Lastly, the server responds with the actual content.
11420 MockRead data_reads2[] = {
11421 MockRead("HTTP/1.1 200 OK\r\n"),
11422 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11423 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0611424 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:5711425 };
11426
Ryan Sleevib8d7ea02018-05-07 20:01:0111427 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:0711428 session_deps_.socket_factory->AddSocketDataProvider(&data2);
danakj1fd259a02016-04-16 03:17:0911429 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5711430
[email protected]49639fa2011-12-20 23:22:4111431 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:5711432
bnc691fda62016-08-12 00:43:1611433 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5011434
tfarina42834112016-09-22 13:38:2011435 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111436 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5711437
11438 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0111439 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:5711440
bnc691fda62016-08-12 00:43:1611441 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211442 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0411443 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:5711444
[email protected]49639fa2011-12-20 23:22:4111445 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:5711446
bnc691fda62016-08-12 00:43:1611447 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:0111448 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5711449
11450 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0111451 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:5711452
bnc691fda62016-08-12 00:43:1611453 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211454 ASSERT_TRUE(response);
11455 EXPECT_FALSE(response->auth_challenge);
[email protected]0877e3d2009-10-17 22:29:5711456 EXPECT_EQ(100, response->headers->GetContentLength());
11457}
11458
11459// Test HTTPS connections going through a proxy that sends extra data.
bncd16676a2016-07-20 16:23:0111460TEST_F(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
Ramin Halavatica8d5252018-03-12 05:33:4911461 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
11462 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5711463
11464 HttpRequestInfo request;
11465 request.method = "GET";
bncce36dca22015-04-21 22:11:2311466 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011467 request.traffic_annotation =
11468 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5711469
11470 MockRead proxy_reads[] = {
11471 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:0611472 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:5711473 };
11474
Ryan Sleevib8d7ea02018-05-07 20:01:0111475 StaticSocketDataProvider data(proxy_reads, base::span<MockWrite>());
[email protected]8ddf8322012-02-23 18:08:0611476 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:5711477
[email protected]bb88e1d32013-05-03 23:11:0711478 session_deps_.socket_factory->AddSocketDataProvider(&data);
11479 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:5711480
[email protected]49639fa2011-12-20 23:22:4111481 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5711482
[email protected]bb88e1d32013-05-03 23:11:0711483 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:5711484
danakj1fd259a02016-04-16 03:17:0911485 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611486 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5711487
tfarina42834112016-09-22 13:38:2011488 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111489 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5711490
11491 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111492 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]0877e3d2009-10-17 22:29:5711493}
11494
bncd16676a2016-07-20 16:23:0111495TEST_F(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:4611496 HttpRequestInfo request;
11497 request.method = "GET";
bncce36dca22015-04-21 22:11:2311498 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011499 request.traffic_annotation =
11500 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]9492e4a2010-02-24 00:58:4611501
danakj1fd259a02016-04-16 03:17:0911502 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611503 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2711504
[email protected]e22e1362009-11-23 21:31:1211505 MockRead data_reads[] = {
11506 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0611507 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:1211508 };
[email protected]9492e4a2010-02-24 00:58:4611509
Ryan Sleevib8d7ea02018-05-07 20:01:0111510 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711511 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:4611512
[email protected]49639fa2011-12-20 23:22:4111513 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:4611514
tfarina42834112016-09-22 13:38:2011515 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111516 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9492e4a2010-02-24 00:58:4611517
robpercival214763f2016-07-01 23:27:0111518 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]9492e4a2010-02-24 00:58:4611519
bnc691fda62016-08-12 00:43:1611520 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211521 ASSERT_TRUE(response);
[email protected]9492e4a2010-02-24 00:58:4611522
wezca1070932016-05-26 20:30:5211523 EXPECT_TRUE(response->headers);
[email protected]9492e4a2010-02-24 00:58:4611524 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
11525
11526 std::string response_data;
bnc691fda62016-08-12 00:43:1611527 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0111528 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]e22e1362009-11-23 21:31:1211529}
11530
bncd16676a2016-07-20 16:23:0111531TEST_F(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:1511532 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:5211533 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
avibf0746c2015-12-09 19:53:1411534 const uint64_t kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:2111535 UploadFileElementReader::ScopedOverridingContentLengthForTests
11536 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:3311537
danakj1fd259a02016-04-16 03:17:0911538 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:1911539 element_readers.push_back(std::make_unique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:1411540 base::ThreadTaskRunnerHandle::Get().get(), temp_file_path, 0,
ricea2deef682016-09-09 08:04:0711541 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:2211542 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:2711543
11544 HttpRequestInfo request;
11545 request.method = "POST";
bncce36dca22015-04-21 22:11:2311546 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:2711547 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1011548 request.traffic_annotation =
11549 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]329b68b2012-11-14 17:54:2711550
danakj1fd259a02016-04-16 03:17:0911551 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611552 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]95d88ffe2010-02-04 21:25:3311553
11554 MockRead data_reads[] = {
11555 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
11556 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611557 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:3311558 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111559 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711560 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:3311561
[email protected]49639fa2011-12-20 23:22:4111562 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:3311563
tfarina42834112016-09-22 13:38:2011564 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111565 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]95d88ffe2010-02-04 21:25:3311566
11567 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111568 EXPECT_THAT(rv, IsError(ERR_UPLOAD_FILE_CHANGED));
[email protected]95d88ffe2010-02-04 21:25:3311569
bnc691fda62016-08-12 00:43:1611570 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211571 ASSERT_TRUE(response);
[email protected]95d88ffe2010-02-04 21:25:3311572
maksim.sisove869bf52016-06-23 17:11:5211573 EXPECT_FALSE(response->headers);
[email protected]95d88ffe2010-02-04 21:25:3311574
[email protected]dd3aa792013-07-16 19:10:2311575 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:3311576}
11577
bncd16676a2016-07-20 16:23:0111578TEST_F(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:1511579 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:5211580 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:3611581 std::string temp_file_content("Unreadable file.");
lazyboy8df84fc2017-04-12 02:12:4811582 ASSERT_EQ(static_cast<int>(temp_file_content.length()),
11583 base::WriteFile(temp_file, temp_file_content.c_str(),
11584 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:1111585 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:3611586
danakj1fd259a02016-04-16 03:17:0911587 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:1911588 element_readers.push_back(std::make_unique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:1411589 base::ThreadTaskRunnerHandle::Get().get(), temp_file, 0,
ricea2deef682016-09-09 08:04:0711590 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:2211591 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:2711592
11593 HttpRequestInfo request;
11594 request.method = "POST";
bncce36dca22015-04-21 22:11:2311595 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:2711596 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1011597 request.traffic_annotation =
11598 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]329b68b2012-11-14 17:54:2711599
[email protected]999dd8c2013-11-12 06:45:5411600 // If we try to upload an unreadable file, the transaction should fail.
danakj1fd259a02016-04-16 03:17:0911601 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611602 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]6624b4622010-03-29 19:58:3611603
Ryan Sleevib8d7ea02018-05-07 20:01:0111604 StaticSocketDataProvider data;
[email protected]bb88e1d32013-05-03 23:11:0711605 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:3611606
[email protected]49639fa2011-12-20 23:22:4111607 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:3611608
tfarina42834112016-09-22 13:38:2011609 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111610 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6624b4622010-03-29 19:58:3611611
11612 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111613 EXPECT_THAT(rv, IsError(ERR_ACCESS_DENIED));
[email protected]6624b4622010-03-29 19:58:3611614
[email protected]dd3aa792013-07-16 19:10:2311615 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:3611616}
11617
bncd16676a2016-07-20 16:23:0111618TEST_F(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
[email protected]02cad5d2013-10-02 08:14:0311619 class FakeUploadElementReader : public UploadElementReader {
11620 public:
Chris Watkins7a41d3552017-12-01 02:13:2711621 FakeUploadElementReader() = default;
11622 ~FakeUploadElementReader() override = default;
[email protected]02cad5d2013-10-02 08:14:0311623
Matt Menkecc1d3a902018-02-05 18:27:3311624 CompletionOnceCallback TakeCallback() { return std::move(callback_); }
[email protected]02cad5d2013-10-02 08:14:0311625
11626 // UploadElementReader overrides:
Matt Menkecc1d3a902018-02-05 18:27:3311627 int Init(CompletionOnceCallback callback) override {
11628 callback_ = std::move(callback);
[email protected]02cad5d2013-10-02 08:14:0311629 return ERR_IO_PENDING;
11630 }
avibf0746c2015-12-09 19:53:1411631 uint64_t GetContentLength() const override { return 0; }
11632 uint64_t BytesRemaining() const override { return 0; }
dchengb03027d2014-10-21 12:00:2011633 int Read(IOBuffer* buf,
11634 int buf_length,
Matt Menkecc1d3a902018-02-05 18:27:3311635 CompletionOnceCallback callback) override {
[email protected]02cad5d2013-10-02 08:14:0311636 return ERR_FAILED;
11637 }
11638
11639 private:
Matt Menkecc1d3a902018-02-05 18:27:3311640 CompletionOnceCallback callback_;
[email protected]02cad5d2013-10-02 08:14:0311641 };
11642
11643 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
danakj1fd259a02016-04-16 03:17:0911644 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
11645 element_readers.push_back(base::WrapUnique(fake_reader));
olli.raula6df48b2a2015-11-26 07:40:2211646 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02cad5d2013-10-02 08:14:0311647
11648 HttpRequestInfo request;
11649 request.method = "POST";
bncce36dca22015-04-21 22:11:2311650 request.url = GURL("http://www.example.org/upload");
[email protected]02cad5d2013-10-02 08:14:0311651 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1011652 request.traffic_annotation =
11653 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02cad5d2013-10-02 08:14:0311654
danakj1fd259a02016-04-16 03:17:0911655 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5811656 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1911657 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]02cad5d2013-10-02 08:14:0311658
11659 StaticSocketDataProvider data;
11660 session_deps_.socket_factory->AddSocketDataProvider(&data);
11661
11662 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2011663 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111664 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
fdoray92e35a72016-06-10 15:54:5511665 base::RunLoop().RunUntilIdle();
[email protected]02cad5d2013-10-02 08:14:0311666
11667 // Transaction is pending on request body initialization.
Matt Menkecc1d3a902018-02-05 18:27:3311668 CompletionOnceCallback init_callback = fake_reader->TakeCallback();
11669 ASSERT_FALSE(init_callback.is_null());
[email protected]02cad5d2013-10-02 08:14:0311670
11671 // Return Init()'s result after the transaction gets destroyed.
11672 trans.reset();
Matt Menkecc1d3a902018-02-05 18:27:3311673 std::move(init_callback).Run(OK); // Should not crash.
[email protected]02cad5d2013-10-02 08:14:0311674}
11675
[email protected]aeefc9e82010-02-19 16:18:2711676// Tests that changes to Auth realms are treated like auth rejections.
bncd16676a2016-07-20 16:23:0111677TEST_F(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:2711678 HttpRequestInfo request;
11679 request.method = "GET";
bncce36dca22015-04-21 22:11:2311680 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011681 request.traffic_annotation =
11682 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]aeefc9e82010-02-19 16:18:2711683
11684 // First transaction will request a resource and receive a Basic challenge
11685 // with realm="first_realm".
11686 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2311687 MockWrite(
11688 "GET / HTTP/1.1\r\n"
11689 "Host: www.example.org\r\n"
11690 "Connection: keep-alive\r\n"
11691 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2711692 };
11693 MockRead data_reads1[] = {
11694 MockRead("HTTP/1.1 401 Unauthorized\r\n"
11695 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
11696 "\r\n"),
11697 };
11698
bnc691fda62016-08-12 00:43:1611699 // After calling trans.RestartWithAuth(), provide an Authentication header
[email protected]aeefc9e82010-02-19 16:18:2711700 // for first_realm. The server will reject and provide a challenge with
11701 // second_realm.
11702 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:2311703 MockWrite(
11704 "GET / HTTP/1.1\r\n"
11705 "Host: www.example.org\r\n"
11706 "Connection: keep-alive\r\n"
11707 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
11708 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2711709 };
11710 MockRead data_reads2[] = {
11711 MockRead("HTTP/1.1 401 Unauthorized\r\n"
11712 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
11713 "\r\n"),
11714 };
11715
11716 // This again fails, and goes back to first_realm. Make sure that the
11717 // entry is removed from cache.
11718 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:2311719 MockWrite(
11720 "GET / HTTP/1.1\r\n"
11721 "Host: www.example.org\r\n"
11722 "Connection: keep-alive\r\n"
11723 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
11724 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2711725 };
11726 MockRead data_reads3[] = {
11727 MockRead("HTTP/1.1 401 Unauthorized\r\n"
11728 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
11729 "\r\n"),
11730 };
11731
11732 // Try one last time (with the correct password) and get the resource.
11733 MockWrite data_writes4[] = {
bncce36dca22015-04-21 22:11:2311734 MockWrite(
11735 "GET / HTTP/1.1\r\n"
11736 "Host: www.example.org\r\n"
11737 "Connection: keep-alive\r\n"
11738 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
11739 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2711740 };
11741 MockRead data_reads4[] = {
11742 MockRead("HTTP/1.1 200 OK\r\n"
11743 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:5011744 "Content-Length: 5\r\n"
11745 "\r\n"
11746 "hello"),
[email protected]aeefc9e82010-02-19 16:18:2711747 };
11748
Ryan Sleevib8d7ea02018-05-07 20:01:0111749 StaticSocketDataProvider data1(data_reads1, data_writes1);
11750 StaticSocketDataProvider data2(data_reads2, data_writes2);
11751 StaticSocketDataProvider data3(data_reads3, data_writes3);
11752 StaticSocketDataProvider data4(data_reads4, data_writes4);
[email protected]bb88e1d32013-05-03 23:11:0711753 session_deps_.socket_factory->AddSocketDataProvider(&data1);
11754 session_deps_.socket_factory->AddSocketDataProvider(&data2);
11755 session_deps_.socket_factory->AddSocketDataProvider(&data3);
11756 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:2711757
[email protected]49639fa2011-12-20 23:22:4111758 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:2711759
danakj1fd259a02016-04-16 03:17:0911760 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611761 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5011762
[email protected]aeefc9e82010-02-19 16:18:2711763 // Issue the first request with Authorize headers. There should be a
11764 // password prompt for first_realm waiting to be filled in after the
11765 // transaction completes.
tfarina42834112016-09-22 13:38:2011766 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111767 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2711768 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0111769 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1611770 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211771 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0411772 const AuthChallengeInfo* challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5211773 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0411774 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4311775 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0411776 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1911777 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2711778
11779 // Issue the second request with an incorrect password. There should be a
11780 // password prompt for second_realm waiting to be filled in after the
11781 // transaction completes.
[email protected]49639fa2011-12-20 23:22:4111782 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:1611783 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBaz),
11784 callback2.callback());
robpercival214763f2016-07-01 23:27:0111785 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2711786 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0111787 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1611788 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211789 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0411790 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5211791 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0411792 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4311793 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0411794 EXPECT_EQ("second_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1911795 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2711796
11797 // Issue the third request with another incorrect password. There should be
11798 // a password prompt for first_realm waiting to be filled in. If the password
11799 // prompt is not present, it indicates that the HttpAuthCacheEntry for
11800 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:4111801 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:1611802 rv = trans.RestartWithAuth(AuthCredentials(kSecond, kFou),
11803 callback3.callback());
robpercival214763f2016-07-01 23:27:0111804 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2711805 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:0111806 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1611807 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211808 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0411809 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5211810 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0411811 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4311812 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0411813 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1911814 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2711815
11816 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:4111817 TestCompletionCallback callback4;
bnc691fda62016-08-12 00:43:1611818 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBar),
11819 callback4.callback());
robpercival214763f2016-07-01 23:27:0111820 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2711821 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:0111822 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1611823 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211824 ASSERT_TRUE(response);
11825 EXPECT_FALSE(response->auth_challenge);
[email protected]aeefc9e82010-02-19 16:18:2711826}
11827
Bence Béky230ac612017-08-30 19:17:0811828// Regression test for https://crbug.com/754395.
11829TEST_F(HttpNetworkTransactionTest, IgnoreAltSvcWithInvalidCert) {
11830 MockRead data_reads[] = {
11831 MockRead("HTTP/1.1 200 OK\r\n"),
11832 MockRead(kAlternativeServiceHttpHeader),
11833 MockRead("\r\n"),
11834 MockRead("hello world"),
11835 MockRead(SYNCHRONOUS, OK),
11836 };
11837
11838 HttpRequestInfo request;
11839 request.method = "GET";
11840 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011841 request.traffic_annotation =
11842 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Béky230ac612017-08-30 19:17:0811843
Ryan Sleevib8d7ea02018-05-07 20:01:0111844 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
Bence Béky230ac612017-08-30 19:17:0811845 session_deps_.socket_factory->AddSocketDataProvider(&data);
11846
11847 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911848 ssl.ssl_info.cert =
11849 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11850 ASSERT_TRUE(ssl.ssl_info.cert);
11851 ssl.ssl_info.cert_status = CERT_STATUS_COMMON_NAME_INVALID;
Bence Béky230ac612017-08-30 19:17:0811852 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11853
11854 TestCompletionCallback callback;
11855
11856 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11857 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11858
11859 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
11860 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11861
11862 url::SchemeHostPort test_server(request.url);
11863 HttpServerProperties* http_server_properties =
11864 session->http_server_properties();
11865 EXPECT_TRUE(
11866 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
11867
11868 EXPECT_THAT(callback.WaitForResult(), IsOk());
11869
11870 const HttpResponseInfo* response = trans.GetResponseInfo();
11871 ASSERT_TRUE(response);
11872 ASSERT_TRUE(response->headers);
11873 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11874 EXPECT_FALSE(response->was_fetched_via_spdy);
11875 EXPECT_FALSE(response->was_alpn_negotiated);
11876
11877 std::string response_data;
11878 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
11879 EXPECT_EQ("hello world", response_data);
11880
11881 EXPECT_TRUE(
11882 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
11883}
11884
bncd16676a2016-07-20 16:23:0111885TEST_F(HttpNetworkTransactionTest, HonorAlternativeServiceHeader) {
bncc958faa2015-07-31 18:14:5211886 MockRead data_reads[] = {
11887 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311888 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211889 MockRead("\r\n"),
11890 MockRead("hello world"),
11891 MockRead(SYNCHRONOUS, OK),
11892 };
11893
11894 HttpRequestInfo request;
11895 request.method = "GET";
bncb26024382016-06-29 02:39:4511896 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011897 request.traffic_annotation =
11898 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bncc958faa2015-07-31 18:14:5211899
Ryan Sleevib8d7ea02018-05-07 20:01:0111900 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:5211901 session_deps_.socket_factory->AddSocketDataProvider(&data);
11902
bncb26024382016-06-29 02:39:4511903 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911904 ssl.ssl_info.cert =
11905 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11906 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4511907 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11908
bncc958faa2015-07-31 18:14:5211909 TestCompletionCallback callback;
11910
danakj1fd259a02016-04-16 03:17:0911911 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611912 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5211913
tfarina42834112016-09-22 13:38:2011914 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111915 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5211916
bncb26024382016-06-29 02:39:4511917 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4011918 HttpServerProperties* http_server_properties =
11919 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3411920 EXPECT_TRUE(
11921 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5211922
robpercival214763f2016-07-01 23:27:0111923 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5211924
bnc691fda62016-08-12 00:43:1611925 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211926 ASSERT_TRUE(response);
11927 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5211928 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11929 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211930 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5211931
11932 std::string response_data;
bnc691fda62016-08-12 00:43:1611933 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5211934 EXPECT_EQ("hello world", response_data);
11935
zhongyic4de03032017-05-19 04:07:3411936 AlternativeServiceInfoVector alternative_service_info_vector =
11937 http_server_properties->GetAlternativeServiceInfos(test_server);
11938 ASSERT_EQ(1u, alternative_service_info_vector.size());
11939 AlternativeService alternative_service(kProtoHTTP2, "mail.example.org", 443);
11940 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5411941 alternative_service_info_vector[0].alternative_service());
bncc958faa2015-07-31 18:14:5211942}
11943
bnce3dd56f2016-06-01 10:37:1111944// Regression test for https://crbug.com/615497.
bncd16676a2016-07-20 16:23:0111945TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1111946 DoNotParseAlternativeServiceHeaderOnInsecureRequest) {
bnce3dd56f2016-06-01 10:37:1111947 MockRead data_reads[] = {
11948 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311949 MockRead(kAlternativeServiceHttpHeader),
bnce3dd56f2016-06-01 10:37:1111950 MockRead("\r\n"),
11951 MockRead("hello world"),
11952 MockRead(SYNCHRONOUS, OK),
11953 };
11954
11955 HttpRequestInfo request;
11956 request.method = "GET";
11957 request.url = GURL("http://www.example.org/");
11958 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1011959 request.traffic_annotation =
11960 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnce3dd56f2016-06-01 10:37:1111961
Ryan Sleevib8d7ea02018-05-07 20:01:0111962 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
bnce3dd56f2016-06-01 10:37:1111963 session_deps_.socket_factory->AddSocketDataProvider(&data);
11964
11965 TestCompletionCallback callback;
11966
11967 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611968 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1111969
11970 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4011971 HttpServerProperties* http_server_properties =
11972 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3411973 EXPECT_TRUE(
11974 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1111975
tfarina42834112016-09-22 13:38:2011976 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111977 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11978 EXPECT_THAT(callback.WaitForResult(), IsOk());
bnce3dd56f2016-06-01 10:37:1111979
bnc691fda62016-08-12 00:43:1611980 const HttpResponseInfo* response = trans.GetResponseInfo();
bnce3dd56f2016-06-01 10:37:1111981 ASSERT_TRUE(response);
11982 ASSERT_TRUE(response->headers);
11983 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11984 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211985 EXPECT_FALSE(response->was_alpn_negotiated);
bnce3dd56f2016-06-01 10:37:1111986
11987 std::string response_data;
bnc691fda62016-08-12 00:43:1611988 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnce3dd56f2016-06-01 10:37:1111989 EXPECT_EQ("hello world", response_data);
11990
zhongyic4de03032017-05-19 04:07:3411991 EXPECT_TRUE(
11992 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1111993}
11994
bnca86731e2017-04-17 12:31:2811995// HTTP/2 Alternative Services should be disabled by default.
bnc8bef8da22016-05-30 01:28:2511996// TODO(bnc): Remove when https://crbug.com/615413 is fixed.
bncd16676a2016-07-20 16:23:0111997TEST_F(HttpNetworkTransactionTest,
bnc8bef8da22016-05-30 01:28:2511998 DisableHTTP2AlternativeServicesWithDifferentHost) {
bnca86731e2017-04-17 12:31:2811999 session_deps_.enable_http2_alternative_service = false;
bncb26024382016-06-29 02:39:4512000
bnc8bef8da22016-05-30 01:28:2512001 HttpRequestInfo request;
12002 request.method = "GET";
bncb26024382016-06-29 02:39:4512003 request.url = GURL("https://www.example.org/");
bnc8bef8da22016-05-30 01:28:2512004 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1012005 request.traffic_annotation =
12006 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8bef8da22016-05-30 01:28:2512007
12008 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
12009 StaticSocketDataProvider first_data;
12010 first_data.set_connect_data(mock_connect);
12011 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4512012 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612013 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512014 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
bnc8bef8da22016-05-30 01:28:2512015
12016 MockRead data_reads[] = {
12017 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
12018 MockRead(ASYNC, OK),
12019 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112020 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
bnc8bef8da22016-05-30 01:28:2512021 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
12022
12023 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12024
bnc525e175a2016-06-20 12:36:4012025 HttpServerProperties* http_server_properties =
bnc8bef8da22016-05-30 01:28:2512026 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2112027 AlternativeService alternative_service(kProtoHTTP2, "different.example.org",
12028 444);
bnc8bef8da22016-05-30 01:28:2512029 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112030 http_server_properties->SetHttp2AlternativeService(
bnc8bef8da22016-05-30 01:28:2512031 url::SchemeHostPort(request.url), alternative_service, expiration);
12032
bnc691fda62016-08-12 00:43:1612033 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc8bef8da22016-05-30 01:28:2512034 TestCompletionCallback callback;
12035
tfarina42834112016-09-22 13:38:2012036 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc8bef8da22016-05-30 01:28:2512037 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0112038 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc8bef8da22016-05-30 01:28:2512039}
12040
bnce3dd56f2016-06-01 10:37:1112041// Regression test for https://crbug.com/615497:
12042// Alternative Services should be disabled for http origin.
bncd16676a2016-07-20 16:23:0112043TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1112044 DisableAlternativeServicesForInsecureOrigin) {
bnce3dd56f2016-06-01 10:37:1112045 HttpRequestInfo request;
12046 request.method = "GET";
12047 request.url = GURL("http://www.example.org/");
12048 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1012049 request.traffic_annotation =
12050 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnce3dd56f2016-06-01 10:37:1112051
12052 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
12053 StaticSocketDataProvider first_data;
12054 first_data.set_connect_data(mock_connect);
12055 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
12056
12057 MockRead data_reads[] = {
12058 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
12059 MockRead(ASYNC, OK),
12060 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112061 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
bnce3dd56f2016-06-01 10:37:1112062 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
12063
12064 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12065
bnc525e175a2016-06-20 12:36:4012066 HttpServerProperties* http_server_properties =
bnce3dd56f2016-06-01 10:37:1112067 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2112068 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnce3dd56f2016-06-01 10:37:1112069 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112070 http_server_properties->SetHttp2AlternativeService(
bnce3dd56f2016-06-01 10:37:1112071 url::SchemeHostPort(request.url), alternative_service, expiration);
12072
bnc691fda62016-08-12 00:43:1612073 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1112074 TestCompletionCallback callback;
12075
tfarina42834112016-09-22 13:38:2012076 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnce3dd56f2016-06-01 10:37:1112077 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0112078 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnce3dd56f2016-06-01 10:37:1112079}
12080
bncd16676a2016-07-20 16:23:0112081TEST_F(HttpNetworkTransactionTest, ClearAlternativeServices) {
bnc4f575852015-10-14 18:35:0812082 // Set an alternative service for origin.
danakj1fd259a02016-04-16 03:17:0912083 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4012084 HttpServerProperties* http_server_properties =
12085 session->http_server_properties();
bncb26024382016-06-29 02:39:4512086 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc3472afd2016-11-17 15:27:2112087 AlternativeService alternative_service(kProtoQUIC, "", 80);
bnc4f575852015-10-14 18:35:0812088 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112089 http_server_properties->SetQuicAlternativeService(
12090 test_server, alternative_service, expiration,
12091 session->params().quic_supported_versions);
zhongyic4de03032017-05-19 04:07:3412092 EXPECT_EQ(
12093 1u,
12094 http_server_properties->GetAlternativeServiceInfos(test_server).size());
bnc4f575852015-10-14 18:35:0812095
12096 // Send a clear header.
12097 MockRead data_reads[] = {
12098 MockRead("HTTP/1.1 200 OK\r\n"),
12099 MockRead("Alt-Svc: clear\r\n"),
12100 MockRead("\r\n"),
12101 MockRead("hello world"),
12102 MockRead(SYNCHRONOUS, OK),
12103 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112104 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
bnc4f575852015-10-14 18:35:0812105 session_deps_.socket_factory->AddSocketDataProvider(&data);
12106
bncb26024382016-06-29 02:39:4512107 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4912108 ssl.ssl_info.cert =
12109 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
12110 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4512111 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12112
bnc4f575852015-10-14 18:35:0812113 HttpRequestInfo request;
12114 request.method = "GET";
bncb26024382016-06-29 02:39:4512115 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1012116 request.traffic_annotation =
12117 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc4f575852015-10-14 18:35:0812118
12119 TestCompletionCallback callback;
12120
bnc691fda62016-08-12 00:43:1612121 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc4f575852015-10-14 18:35:0812122
tfarina42834112016-09-22 13:38:2012123 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112124 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc4f575852015-10-14 18:35:0812125
bnc691fda62016-08-12 00:43:1612126 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212127 ASSERT_TRUE(response);
12128 ASSERT_TRUE(response->headers);
bnc4f575852015-10-14 18:35:0812129 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12130 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212131 EXPECT_FALSE(response->was_alpn_negotiated);
bnc4f575852015-10-14 18:35:0812132
12133 std::string response_data;
bnc691fda62016-08-12 00:43:1612134 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc4f575852015-10-14 18:35:0812135 EXPECT_EQ("hello world", response_data);
12136
zhongyic4de03032017-05-19 04:07:3412137 EXPECT_TRUE(
12138 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnc4f575852015-10-14 18:35:0812139}
12140
bncd16676a2016-07-20 16:23:0112141TEST_F(HttpNetworkTransactionTest, HonorMultipleAlternativeServiceHeaders) {
bncc958faa2015-07-31 18:14:5212142 MockRead data_reads[] = {
12143 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312144 MockRead("Alt-Svc: h2=\"www.example.com:443\","),
12145 MockRead("h2=\":1234\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:5212146 MockRead("hello world"),
12147 MockRead(SYNCHRONOUS, OK),
12148 };
12149
12150 HttpRequestInfo request;
12151 request.method = "GET";
bncb26024382016-06-29 02:39:4512152 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1012153 request.traffic_annotation =
12154 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bncc958faa2015-07-31 18:14:5212155
Ryan Sleevib8d7ea02018-05-07 20:01:0112156 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:5212157 session_deps_.socket_factory->AddSocketDataProvider(&data);
12158
bncb26024382016-06-29 02:39:4512159 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4912160 ssl.ssl_info.cert =
12161 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
12162 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4512163 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12164
bncc958faa2015-07-31 18:14:5212165 TestCompletionCallback callback;
12166
danakj1fd259a02016-04-16 03:17:0912167 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1612168 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5212169
tfarina42834112016-09-22 13:38:2012170 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112171 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5212172
bncb26024382016-06-29 02:39:4512173 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc525e175a2016-06-20 12:36:4012174 HttpServerProperties* http_server_properties =
12175 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3412176 EXPECT_TRUE(
12177 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5212178
robpercival214763f2016-07-01 23:27:0112179 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5212180
bnc691fda62016-08-12 00:43:1612181 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212182 ASSERT_TRUE(response);
12183 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5212184 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12185 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212186 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5212187
12188 std::string response_data;
bnc691fda62016-08-12 00:43:1612189 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5212190 EXPECT_EQ("hello world", response_data);
12191
zhongyic4de03032017-05-19 04:07:3412192 AlternativeServiceInfoVector alternative_service_info_vector =
12193 http_server_properties->GetAlternativeServiceInfos(test_server);
12194 ASSERT_EQ(2u, alternative_service_info_vector.size());
12195
12196 AlternativeService alternative_service(kProtoHTTP2, "www.example.com", 443);
12197 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5412198 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3412199 AlternativeService alternative_service_2(kProtoHTTP2, "www.example.org",
12200 1234);
12201 EXPECT_EQ(alternative_service_2,
zhongyi422ce352017-06-09 23:28:5412202 alternative_service_info_vector[1].alternative_service());
bncc958faa2015-07-31 18:14:5212203}
12204
bncd16676a2016-07-20 16:23:0112205TEST_F(HttpNetworkTransactionTest, IdentifyQuicBroken) {
zhongyi3d4a55e72016-04-22 20:36:4612206 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0212207 HostPortPair alternative("alternative.example.org", 443);
12208 std::string origin_url = "https://origin.example.org:443";
12209 std::string alternative_url = "https://alternative.example.org:443";
12210
12211 // Negotiate HTTP/1.1 with alternative.example.org.
12212 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612213 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0212214 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12215
12216 // HTTP/1.1 data for request.
12217 MockWrite http_writes[] = {
12218 MockWrite("GET / HTTP/1.1\r\n"
12219 "Host: alternative.example.org\r\n"
12220 "Connection: keep-alive\r\n\r\n"),
12221 };
12222
12223 MockRead http_reads[] = {
12224 MockRead("HTTP/1.1 200 OK\r\n"
12225 "Content-Type: text/html; charset=iso-8859-1\r\n"
12226 "Content-Length: 40\r\n\r\n"
12227 "first HTTP/1.1 response from alternative"),
12228 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112229 StaticSocketDataProvider http_data(http_reads, http_writes);
zhongyi48704c182015-12-07 07:52:0212230 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12231
12232 StaticSocketDataProvider data_refused;
12233 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
12234 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
12235
zhongyi3d4a55e72016-04-22 20:36:4612236 // Set up a QUIC alternative service for server.
danakj1fd259a02016-04-16 03:17:0912237 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4012238 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0212239 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2112240 AlternativeService alternative_service(kProtoQUIC, alternative);
zhongyi48704c182015-12-07 07:52:0212241 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112242 http_server_properties->SetQuicAlternativeService(
12243 server, alternative_service, expiration,
12244 HttpNetworkSession::Params().quic_supported_versions);
zhongyi48704c182015-12-07 07:52:0212245 // Mark the QUIC alternative service as broken.
12246 http_server_properties->MarkAlternativeServiceBroken(alternative_service);
12247
zhongyi48704c182015-12-07 07:52:0212248 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4612249 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0212250 request.method = "GET";
12251 request.url = GURL(origin_url);
Ramin Halavatib5e433e2018-02-07 07:41:1012252 request.traffic_annotation =
12253 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
12254
zhongyi48704c182015-12-07 07:52:0212255 TestCompletionCallback callback;
12256 NetErrorDetails details;
12257 EXPECT_FALSE(details.quic_broken);
12258
tfarina42834112016-09-22 13:38:2012259 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1612260 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0212261 EXPECT_TRUE(details.quic_broken);
12262}
12263
bncd16676a2016-07-20 16:23:0112264TEST_F(HttpNetworkTransactionTest, IdentifyQuicNotBroken) {
zhongyi3d4a55e72016-04-22 20:36:4612265 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0212266 HostPortPair alternative1("alternative1.example.org", 443);
12267 HostPortPair alternative2("alternative2.example.org", 443);
12268 std::string origin_url = "https://origin.example.org:443";
12269 std::string alternative_url1 = "https://alternative1.example.org:443";
12270 std::string alternative_url2 = "https://alternative2.example.org:443";
12271
12272 // Negotiate HTTP/1.1 with alternative1.example.org.
12273 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612274 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0212275 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12276
12277 // HTTP/1.1 data for request.
12278 MockWrite http_writes[] = {
12279 MockWrite("GET / HTTP/1.1\r\n"
12280 "Host: alternative1.example.org\r\n"
12281 "Connection: keep-alive\r\n\r\n"),
12282 };
12283
12284 MockRead http_reads[] = {
12285 MockRead("HTTP/1.1 200 OK\r\n"
12286 "Content-Type: text/html; charset=iso-8859-1\r\n"
12287 "Content-Length: 40\r\n\r\n"
12288 "first HTTP/1.1 response from alternative1"),
12289 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112290 StaticSocketDataProvider http_data(http_reads, http_writes);
zhongyi48704c182015-12-07 07:52:0212291 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12292
12293 StaticSocketDataProvider data_refused;
12294 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
12295 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
12296
danakj1fd259a02016-04-16 03:17:0912297 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4012298 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0212299 session->http_server_properties();
12300
zhongyi3d4a55e72016-04-22 20:36:4612301 // Set up two QUIC alternative services for server.
zhongyi48704c182015-12-07 07:52:0212302 AlternativeServiceInfoVector alternative_service_info_vector;
12303 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
12304
bnc3472afd2016-11-17 15:27:2112305 AlternativeService alternative_service1(kProtoQUIC, alternative1);
zhongyie537a002017-06-27 16:48:2112306 alternative_service_info_vector.push_back(
12307 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
12308 alternative_service1, expiration,
12309 session->params().quic_supported_versions));
bnc3472afd2016-11-17 15:27:2112310 AlternativeService alternative_service2(kProtoQUIC, alternative2);
zhongyie537a002017-06-27 16:48:2112311 alternative_service_info_vector.push_back(
12312 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
12313 alternative_service2, expiration,
12314 session->params().quic_supported_versions));
zhongyi48704c182015-12-07 07:52:0212315
12316 http_server_properties->SetAlternativeServices(
zhongyi3d4a55e72016-04-22 20:36:4612317 server, alternative_service_info_vector);
zhongyi48704c182015-12-07 07:52:0212318
12319 // Mark one of the QUIC alternative service as broken.
12320 http_server_properties->MarkAlternativeServiceBroken(alternative_service1);
zhongyic4de03032017-05-19 04:07:3412321 EXPECT_EQ(2u,
12322 http_server_properties->GetAlternativeServiceInfos(server).size());
zhongyi48704c182015-12-07 07:52:0212323
zhongyi48704c182015-12-07 07:52:0212324 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4612325 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0212326 request.method = "GET";
12327 request.url = GURL(origin_url);
Ramin Halavatib5e433e2018-02-07 07:41:1012328 request.traffic_annotation =
12329 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
12330
zhongyi48704c182015-12-07 07:52:0212331 TestCompletionCallback callback;
12332 NetErrorDetails details;
12333 EXPECT_FALSE(details.quic_broken);
12334
tfarina42834112016-09-22 13:38:2012335 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1612336 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0212337 EXPECT_FALSE(details.quic_broken);
12338}
12339
bncd16676a2016-07-20 16:23:0112340TEST_F(HttpNetworkTransactionTest, MarkBrokenAlternateProtocolAndFallback) {
[email protected]564b4912010-03-09 16:30:4212341 HttpRequestInfo request;
12342 request.method = "GET";
bncb26024382016-06-29 02:39:4512343 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1012344 request.traffic_annotation =
12345 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]564b4912010-03-09 16:30:4212346
[email protected]d973e99a2012-02-17 21:02:3612347 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:4212348 StaticSocketDataProvider first_data;
12349 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712350 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4512351 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612352 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512353 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]564b4912010-03-09 16:30:4212354
12355 MockRead data_reads[] = {
12356 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12357 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0612358 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:4212359 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112360 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712361 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:4212362
danakj1fd259a02016-04-16 03:17:0912363 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:4212364
bnc525e175a2016-06-20 12:36:4012365 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5312366 session->http_server_properties();
zhongyi3d4a55e72016-04-22 20:36:4612367 const url::SchemeHostPort server(request.url);
[email protected]3912662a32011-10-04 00:51:1112368 // Port must be < 1024, or the header will be ignored (since initial port was
12369 // port 80 (another restricted port).
zhongyie537a002017-06-27 16:48:2112370 // Port is ignored by MockConnect anyway.
12371 const AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12372 666);
bnc7dc7e1b42015-07-28 14:43:1212373 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112374 http_server_properties->SetHttp2AlternativeService(
12375 server, alternative_service, expiration);
[email protected]564b4912010-03-09 16:30:4212376
bnc691fda62016-08-12 00:43:1612377 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112378 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:4212379
tfarina42834112016-09-22 13:38:2012380 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112381 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12382 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]564b4912010-03-09 16:30:4212383
bnc691fda62016-08-12 00:43:1612384 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212385 ASSERT_TRUE(response);
12386 ASSERT_TRUE(response->headers);
[email protected]564b4912010-03-09 16:30:4212387 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12388
12389 std::string response_data;
bnc691fda62016-08-12 00:43:1612390 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]564b4912010-03-09 16:30:4212391 EXPECT_EQ("hello world", response_data);
12392
zhongyic4de03032017-05-19 04:07:3412393 const AlternativeServiceInfoVector alternative_service_info_vector =
12394 http_server_properties->GetAlternativeServiceInfos(server);
12395 ASSERT_EQ(1u, alternative_service_info_vector.size());
12396 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5412397 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3412398 EXPECT_TRUE(
12399 http_server_properties->IsAlternativeServiceBroken(alternative_service));
[email protected]564b4912010-03-09 16:30:4212400}
12401
bnc55ff9da2015-08-19 18:42:3512402// Ensure that we are not allowed to redirect traffic via an alternate protocol
12403// to an unrestricted (port >= 1024) when the original traffic was on a
12404// restricted port (port < 1024). Ensure that we can redirect in all other
12405// cases.
bncd16676a2016-07-20 16:23:0112406TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:1112407 HttpRequestInfo restricted_port_request;
12408 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4512409 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1112410 restricted_port_request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1012411 restricted_port_request.traffic_annotation =
12412 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1112413
[email protected]d973e99a2012-02-17 21:02:3612414 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1112415 StaticSocketDataProvider first_data;
12416 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712417 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1112418
12419 MockRead data_reads[] = {
12420 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12421 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0612422 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1112423 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112424 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712425 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4512426 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612427 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512428 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1112429
danakj1fd259a02016-04-16 03:17:0912430 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1112431
bnc525e175a2016-06-20 12:36:4012432 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5312433 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1112434 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2112435 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12436 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1212437 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112438 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4612439 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5012440 expiration);
[email protected]3912662a32011-10-04 00:51:1112441
bnc691fda62016-08-12 00:43:1612442 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112443 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1112444
tfarina42834112016-09-22 13:38:2012445 int rv = trans.Start(&restricted_port_request, callback.callback(),
12446 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112447 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1112448 // Invalid change to unrestricted port should fail.
robpercival214763f2016-07-01 23:27:0112449 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_REFUSED));
[email protected]c54c6962013-02-01 04:53:1912450}
[email protected]3912662a32011-10-04 00:51:1112451
bnc55ff9da2015-08-19 18:42:3512452// Ensure that we are allowed to redirect traffic via an alternate protocol to
12453// an unrestricted (port >= 1024) when the original traffic was on a restricted
12454// port (port < 1024) if we set |enable_user_alternate_protocol_ports|.
bncd16676a2016-07-20 16:23:0112455TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedPermitted) {
[email protected]bb88e1d32013-05-03 23:11:0712456 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:1912457
12458 HttpRequestInfo restricted_port_request;
12459 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4512460 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]c54c6962013-02-01 04:53:1912461 restricted_port_request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1012462 restricted_port_request.traffic_annotation =
12463 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]c54c6962013-02-01 04:53:1912464
12465 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
12466 StaticSocketDataProvider first_data;
12467 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712468 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:1912469
12470 MockRead data_reads[] = {
12471 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12472 MockRead("hello world"),
12473 MockRead(ASYNC, OK),
12474 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112475 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712476 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4512477 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612478 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512479 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]c54c6962013-02-01 04:53:1912480
danakj1fd259a02016-04-16 03:17:0912481 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:1912482
bnc525e175a2016-06-20 12:36:4012483 HttpServerProperties* http_server_properties =
[email protected]c54c6962013-02-01 04:53:1912484 session->http_server_properties();
12485 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2112486 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12487 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1212488 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112489 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4612490 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5012491 expiration);
[email protected]c54c6962013-02-01 04:53:1912492
bnc691fda62016-08-12 00:43:1612493 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]c54c6962013-02-01 04:53:1912494 TestCompletionCallback callback;
12495
tfarina42834112016-09-22 13:38:2012496 EXPECT_EQ(ERR_IO_PENDING,
12497 trans.Start(&restricted_port_request, callback.callback(),
12498 NetLogWithSource()));
[email protected]c54c6962013-02-01 04:53:1912499 // Change to unrestricted port should succeed.
robpercival214763f2016-07-01 23:27:0112500 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1112501}
12502
bnc55ff9da2015-08-19 18:42:3512503// Ensure that we are not allowed to redirect traffic via an alternate protocol
12504// to an unrestricted (port >= 1024) when the original traffic was on a
12505// restricted port (port < 1024). Ensure that we can redirect in all other
12506// cases.
bncd16676a2016-07-20 16:23:0112507TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:1112508 HttpRequestInfo restricted_port_request;
12509 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4512510 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1112511 restricted_port_request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1012512 restricted_port_request.traffic_annotation =
12513 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1112514
[email protected]d973e99a2012-02-17 21:02:3612515 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1112516 StaticSocketDataProvider first_data;
12517 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712518 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1112519
12520 MockRead data_reads[] = {
12521 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12522 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0612523 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1112524 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112525 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712526 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1112527
bncb26024382016-06-29 02:39:4512528 SSLSocketDataProvider ssl(ASYNC, OK);
12529 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12530
danakj1fd259a02016-04-16 03:17:0912531 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1112532
bnc525e175a2016-06-20 12:36:4012533 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5312534 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1112535 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2112536 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12537 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1212538 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112539 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4612540 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5012541 expiration);
[email protected]3912662a32011-10-04 00:51:1112542
bnc691fda62016-08-12 00:43:1612543 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112544 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1112545
tfarina42834112016-09-22 13:38:2012546 int rv = trans.Start(&restricted_port_request, callback.callback(),
12547 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112548 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1112549 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0112550 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1112551}
12552
bnc55ff9da2015-08-19 18:42:3512553// Ensure that we are not allowed to redirect traffic via an alternate protocol
12554// to an unrestricted (port >= 1024) when the original traffic was on a
12555// restricted port (port < 1024). Ensure that we can redirect in all other
12556// cases.
bncd16676a2016-07-20 16:23:0112557TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:1112558 HttpRequestInfo unrestricted_port_request;
12559 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4512560 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1112561 unrestricted_port_request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1012562 unrestricted_port_request.traffic_annotation =
12563 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1112564
[email protected]d973e99a2012-02-17 21:02:3612565 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1112566 StaticSocketDataProvider first_data;
12567 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712568 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1112569
12570 MockRead data_reads[] = {
12571 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12572 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0612573 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1112574 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112575 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712576 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4512577 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612578 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512579 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1112580
danakj1fd259a02016-04-16 03:17:0912581 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1112582
bnc525e175a2016-06-20 12:36:4012583 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5312584 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1112585 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2112586 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12587 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1212588 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112589 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4612590 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5012591 expiration);
[email protected]3912662a32011-10-04 00:51:1112592
bnc691fda62016-08-12 00:43:1612593 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112594 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1112595
bnc691fda62016-08-12 00:43:1612596 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2012597 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112598 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1112599 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0112600 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1112601}
12602
bnc55ff9da2015-08-19 18:42:3512603// Ensure that we are not allowed to redirect traffic via an alternate protocol
12604// to an unrestricted (port >= 1024) when the original traffic was on a
12605// restricted port (port < 1024). Ensure that we can redirect in all other
12606// cases.
bncd16676a2016-07-20 16:23:0112607TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:1112608 HttpRequestInfo unrestricted_port_request;
12609 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4512610 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1112611 unrestricted_port_request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1012612 unrestricted_port_request.traffic_annotation =
12613 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1112614
[email protected]d973e99a2012-02-17 21:02:3612615 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1112616 StaticSocketDataProvider first_data;
12617 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712618 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1112619
12620 MockRead data_reads[] = {
12621 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12622 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0612623 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1112624 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112625 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712626 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1112627
bncb26024382016-06-29 02:39:4512628 SSLSocketDataProvider ssl(ASYNC, OK);
12629 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12630
danakj1fd259a02016-04-16 03:17:0912631 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1112632
bnc525e175a2016-06-20 12:36:4012633 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5312634 session->http_server_properties();
bnc0bbb02622015-07-23 10:06:2212635 const int kUnrestrictedAlternatePort = 1025;
bnc3472afd2016-11-17 15:27:2112636 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12637 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1212638 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112639 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4612640 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5012641 expiration);
[email protected]3912662a32011-10-04 00:51:1112642
bnc691fda62016-08-12 00:43:1612643 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112644 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1112645
bnc691fda62016-08-12 00:43:1612646 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2012647 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112648 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1112649 // Valid change to an unrestricted port should pass.
robpercival214763f2016-07-01 23:27:0112650 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1112651}
12652
bnc55ff9da2015-08-19 18:42:3512653// Ensure that we are not allowed to redirect traffic via an alternate protocol
Xida Chen9bfe0b62018-04-24 19:52:2112654// to an unsafe port, and that we resume the second HttpStreamFactory::Job once
12655// the alternate protocol request fails.
bncd16676a2016-07-20 16:23:0112656TEST_F(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:0212657 HttpRequestInfo request;
12658 request.method = "GET";
bncce36dca22015-04-21 22:11:2312659 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1012660 request.traffic_annotation =
12661 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]eb6234e2012-01-19 01:50:0212662
12663 // The alternate protocol request will error out before we attempt to connect,
12664 // so only the standard HTTP request will try to connect.
12665 MockRead data_reads[] = {
12666 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12667 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0612668 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:0212669 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112670 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712671 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:0212672
danakj1fd259a02016-04-16 03:17:0912673 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:0212674
bnc525e175a2016-06-20 12:36:4012675 HttpServerProperties* http_server_properties =
[email protected]eb6234e2012-01-19 01:50:0212676 session->http_server_properties();
12677 const int kUnsafePort = 7;
bnc3472afd2016-11-17 15:27:2112678 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12679 kUnsafePort);
bnc7dc7e1b42015-07-28 14:43:1212680 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112681 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4612682 url::SchemeHostPort(request.url), alternative_service, expiration);
[email protected]eb6234e2012-01-19 01:50:0212683
bnc691fda62016-08-12 00:43:1612684 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]eb6234e2012-01-19 01:50:0212685 TestCompletionCallback callback;
12686
tfarina42834112016-09-22 13:38:2012687 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112688 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]eb6234e2012-01-19 01:50:0212689 // The HTTP request should succeed.
robpercival214763f2016-07-01 23:27:0112690 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb6234e2012-01-19 01:50:0212691
bnc691fda62016-08-12 00:43:1612692 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212693 ASSERT_TRUE(response);
12694 ASSERT_TRUE(response->headers);
[email protected]eb6234e2012-01-19 01:50:0212695 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12696
12697 std::string response_data;
bnc691fda62016-08-12 00:43:1612698 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]eb6234e2012-01-19 01:50:0212699 EXPECT_EQ("hello world", response_data);
12700}
12701
bncd16676a2016-07-20 16:23:0112702TEST_F(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]2ff8b312010-04-26 22:20:5412703 HttpRequestInfo request;
12704 request.method = "GET";
bncb26024382016-06-29 02:39:4512705 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1012706 request.traffic_annotation =
12707 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2ff8b312010-04-26 22:20:5412708
12709 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212710 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312711 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212712 MockRead("\r\n"),
12713 MockRead("hello world"),
12714 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
12715 MockRead(ASYNC, OK)};
[email protected]2ff8b312010-04-26 22:20:5412716
Ryan Sleevib8d7ea02018-05-07 20:01:0112717 StaticSocketDataProvider first_transaction(data_reads,
12718 base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712719 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4512720 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612721 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512722 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5412723
bnc032658ba2016-09-26 18:17:1512724 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5412725
Ryan Hamilton0239aac2018-05-19 00:03:1312726 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4512727 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4112728 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5412729
Ryan Hamilton0239aac2018-05-19 00:03:1312730 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
12731 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5412732 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4112733 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5412734 };
12735
Ryan Sleevib8d7ea02018-05-07 20:01:0112736 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0712737 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5412738
[email protected]d973e99a2012-02-17 21:02:3612739 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0112740 StaticSocketDataProvider hanging_non_alternate_protocol_socket;
[email protected]2d6728692011-03-12 01:39:5512741 hanging_non_alternate_protocol_socket.set_connect_data(
12742 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0712743 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5512744 &hanging_non_alternate_protocol_socket);
12745
[email protected]49639fa2011-12-20 23:22:4112746 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5412747
danakj1fd259a02016-04-16 03:17:0912748 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5812749 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1912750 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5412751
tfarina42834112016-09-22 13:38:2012752 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112753 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12754 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412755
12756 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212757 ASSERT_TRUE(response);
12758 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5412759 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12760
12761 std::string response_data;
robpercival214763f2016-07-01 23:27:0112762 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412763 EXPECT_EQ("hello world", response_data);
12764
bnc87dcefc2017-05-25 12:47:5812765 trans =
Jeremy Roman0579ed62017-08-29 15:56:1912766 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5412767
tfarina42834112016-09-22 13:38:2012768 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112769 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12770 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412771
12772 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212773 ASSERT_TRUE(response);
12774 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212775 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5312776 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212777 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5412778
robpercival214763f2016-07-01 23:27:0112779 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412780 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:5412781}
12782
bncd16676a2016-07-20 16:23:0112783TEST_F(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]2d6728692011-03-12 01:39:5512784 HttpRequestInfo request;
12785 request.method = "GET";
bncb26024382016-06-29 02:39:4512786 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1012787 request.traffic_annotation =
12788 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d6728692011-03-12 01:39:5512789
bncb26024382016-06-29 02:39:4512790 // First transaction receives Alt-Svc header over HTTP/1.1.
[email protected]2d6728692011-03-12 01:39:5512791 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212792 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312793 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212794 MockRead("\r\n"),
12795 MockRead("hello world"),
12796 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
12797 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5512798 };
12799
Ryan Sleevib8d7ea02018-05-07 20:01:0112800 StaticSocketDataProvider http11_data(data_reads, base::span<MockWrite>());
bncb26024382016-06-29 02:39:4512801 session_deps_.socket_factory->AddSocketDataProvider(&http11_data);
[email protected]2d6728692011-03-12 01:39:5512802
bncb26024382016-06-29 02:39:4512803 SSLSocketDataProvider ssl_http11(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4912804 ssl_http11.ssl_info.cert =
12805 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
12806 ASSERT_TRUE(ssl_http11.ssl_info.cert);
bncb26024382016-06-29 02:39:4512807 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
12808
12809 // Second transaction starts an alternative and a non-alternative Job.
12810 // Both sockets hang.
[email protected]d973e99a2012-02-17 21:02:3612811 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0112812 StaticSocketDataProvider hanging_socket1;
mmenkecc2298e2015-12-07 18:20:1812813 hanging_socket1.set_connect_data(never_finishing_connect);
mmenkecc2298e2015-12-07 18:20:1812814 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket1);
12815
Ryan Sleevib8d7ea02018-05-07 20:01:0112816 StaticSocketDataProvider hanging_socket2;
mmenkecc2298e2015-12-07 18:20:1812817 hanging_socket2.set_connect_data(never_finishing_connect);
12818 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket2);
[email protected]2d6728692011-03-12 01:39:5512819
bncb26024382016-06-29 02:39:4512820 // Third transaction starts an alternative and a non-alternative job.
12821 // The non-alternative job hangs, but the alternative one succeeds.
12822 // The second transaction, still pending, binds to this socket.
Ryan Hamilton0239aac2018-05-19 00:03:1312823 spdy::SpdySerializedFrame req1(
bncb26024382016-06-29 02:39:4512824 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1312825 spdy::SpdySerializedFrame req2(
bncb26024382016-06-29 02:39:4512826 spdy_util_.ConstructSpdyGet("https://www.example.org/", 3, LOWEST));
[email protected]2d6728692011-03-12 01:39:5512827 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4112828 CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
[email protected]2d6728692011-03-12 01:39:5512829 };
Ryan Hamilton0239aac2018-05-19 00:03:1312830 spdy::SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
12831 spdy::SpdySerializedFrame data1(spdy_util_.ConstructSpdyDataFrame(1, true));
12832 spdy::SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
12833 spdy::SpdySerializedFrame data2(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]2d6728692011-03-12 01:39:5512834 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4112835 CreateMockRead(resp1, 2), CreateMockRead(data1, 3),
12836 CreateMockRead(resp2, 4), CreateMockRead(data2, 5),
rch8e6c6c42015-05-01 14:05:1312837 MockRead(ASYNC, 0, 6),
[email protected]2d6728692011-03-12 01:39:5512838 };
12839
Ryan Sleevib8d7ea02018-05-07 20:01:0112840 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0712841 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:5512842
bnc032658ba2016-09-26 18:17:1512843 AddSSLSocketData();
bncb26024382016-06-29 02:39:4512844
Ryan Sleevib8d7ea02018-05-07 20:01:0112845 StaticSocketDataProvider hanging_socket3;
mmenkecc2298e2015-12-07 18:20:1812846 hanging_socket3.set_connect_data(never_finishing_connect);
12847 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket3);
[email protected]2d6728692011-03-12 01:39:5512848
danakj1fd259a02016-04-16 03:17:0912849 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:4112850 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:5012851 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5512852
tfarina42834112016-09-22 13:38:2012853 int rv = trans1.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112854 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12855 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512856
12857 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5212858 ASSERT_TRUE(response);
12859 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5512860 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12861
12862 std::string response_data;
robpercival214763f2016-07-01 23:27:0112863 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512864 EXPECT_EQ("hello world", response_data);
12865
[email protected]49639fa2011-12-20 23:22:4112866 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:5012867 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2012868 rv = trans2.Start(&request, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112869 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5512870
[email protected]49639fa2011-12-20 23:22:4112871 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:5012872 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2012873 rv = trans3.Start(&request, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112874 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5512875
robpercival214763f2016-07-01 23:27:0112876 EXPECT_THAT(callback2.WaitForResult(), IsOk());
12877 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512878
12879 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5212880 ASSERT_TRUE(response);
12881 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212882 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5512883 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212884 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0112885 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512886 EXPECT_EQ("hello!", response_data);
12887
12888 response = trans3.GetResponseInfo();
wezca1070932016-05-26 20:30:5212889 ASSERT_TRUE(response);
12890 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212891 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5512892 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212893 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0112894 ASSERT_THAT(ReadTransaction(&trans3, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512895 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:5512896}
12897
bncd16676a2016-07-20 16:23:0112898TEST_F(HttpNetworkTransactionTest, StallAlternativeServiceForNpnSpdy) {
Bence Békybcae37092018-06-12 04:18:5312899 session_deps_.host_resolver->set_synchronous_mode(true);
12900
[email protected]2d6728692011-03-12 01:39:5512901 HttpRequestInfo request;
12902 request.method = "GET";
bncb26024382016-06-29 02:39:4512903 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1012904 request.traffic_annotation =
12905 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d6728692011-03-12 01:39:5512906
12907 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212908 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312909 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212910 MockRead("\r\n"),
12911 MockRead("hello world"),
12912 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
12913 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5512914 };
12915
Ryan Sleevib8d7ea02018-05-07 20:01:0112916 StaticSocketDataProvider first_transaction(data_reads,
12917 base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712918 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:5512919
[email protected]8ddf8322012-02-23 18:08:0612920 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4912921 ssl.ssl_info.cert =
12922 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
12923 ASSERT_TRUE(ssl.ssl_info.cert);
[email protected]bb88e1d32013-05-03 23:11:0712924 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5512925
[email protected]d973e99a2012-02-17 21:02:3612926 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0112927 StaticSocketDataProvider hanging_alternate_protocol_socket;
[email protected]2d6728692011-03-12 01:39:5512928 hanging_alternate_protocol_socket.set_connect_data(
12929 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0712930 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5512931 &hanging_alternate_protocol_socket);
12932
bncb26024382016-06-29 02:39:4512933 // 2nd request is just a copy of the first one, over HTTP/1.1 again.
Ryan Sleevib8d7ea02018-05-07 20:01:0112934 StaticSocketDataProvider second_transaction(data_reads,
12935 base::span<MockWrite>());
mmenkecc2298e2015-12-07 18:20:1812936 session_deps_.socket_factory->AddSocketDataProvider(&second_transaction);
bncb26024382016-06-29 02:39:4512937 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5512938
[email protected]49639fa2011-12-20 23:22:4112939 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:5512940
danakj1fd259a02016-04-16 03:17:0912941 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5812942 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1912943 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5512944
tfarina42834112016-09-22 13:38:2012945 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112946 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12947 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512948
12949 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212950 ASSERT_TRUE(response);
12951 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5512952 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12953
12954 std::string response_data;
robpercival214763f2016-07-01 23:27:0112955 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512956 EXPECT_EQ("hello world", response_data);
12957
bnc87dcefc2017-05-25 12:47:5812958 trans =
Jeremy Roman0579ed62017-08-29 15:56:1912959 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5512960
tfarina42834112016-09-22 13:38:2012961 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112962 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12963 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512964
12965 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212966 ASSERT_TRUE(response);
12967 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5512968 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12969 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212970 EXPECT_FALSE(response->was_alpn_negotiated);
[email protected]2d6728692011-03-12 01:39:5512971
robpercival214763f2016-07-01 23:27:0112972 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512973 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:5512974}
12975
bnc2e884782016-08-11 19:45:1912976// Test that proxy is resolved using the origin url,
12977// regardless of the alternative server.
12978TEST_F(HttpNetworkTransactionTest, UseOriginNotAlternativeForProxy) {
12979 // Configure proxy to bypass www.example.org, which is the origin URL.
12980 ProxyConfig proxy_config;
12981 proxy_config.proxy_rules().ParseFromString("myproxy:70");
12982 proxy_config.proxy_rules().bypass_rules.AddRuleFromString("www.example.org");
Ramin Halavatica8d5252018-03-12 05:33:4912983 auto proxy_config_service = std::make_unique<ProxyConfigServiceFixed>(
12984 ProxyConfigWithAnnotation(proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS));
bnc2e884782016-08-11 19:45:1912985
12986 CapturingProxyResolver capturing_proxy_resolver;
Jeremy Roman0579ed62017-08-29 15:56:1912987 auto proxy_resolver_factory = std::make_unique<CapturingProxyResolverFactory>(
bnc2e884782016-08-11 19:45:1912988 &capturing_proxy_resolver);
12989
12990 TestNetLog net_log;
12991
Bence Béky53a5aef2018-03-29 21:54:1212992 session_deps_.proxy_resolution_service =
12993 std::make_unique<ProxyResolutionService>(
12994 std::move(proxy_config_service), std::move(proxy_resolver_factory),
12995 &net_log);
bnc2e884782016-08-11 19:45:1912996
12997 session_deps_.net_log = &net_log;
12998
12999 // Configure alternative service with a hostname that is not bypassed by the
13000 // proxy.
13001 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13002 HttpServerProperties* http_server_properties =
13003 session->http_server_properties();
13004 url::SchemeHostPort server("https", "www.example.org", 443);
13005 HostPortPair alternative("www.example.com", 443);
bnc3472afd2016-11-17 15:27:2113006 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc2e884782016-08-11 19:45:1913007 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2113008 http_server_properties->SetHttp2AlternativeService(
13009 server, alternative_service, expiration);
bnc2e884782016-08-11 19:45:1913010
13011 // Non-alternative job should hang.
13012 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0113013 StaticSocketDataProvider hanging_alternate_protocol_socket;
bnc2e884782016-08-11 19:45:1913014 hanging_alternate_protocol_socket.set_connect_data(never_finishing_connect);
13015 session_deps_.socket_factory->AddSocketDataProvider(
13016 &hanging_alternate_protocol_socket);
13017
bnc032658ba2016-09-26 18:17:1513018 AddSSLSocketData();
bnc2e884782016-08-11 19:45:1913019
13020 HttpRequestInfo request;
13021 request.method = "GET";
13022 request.url = GURL("https://www.example.org/");
13023 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1013024 request.traffic_annotation =
13025 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc2e884782016-08-11 19:45:1913026
Ryan Hamilton0239aac2018-05-19 00:03:1313027 spdy::SpdySerializedFrame req(
bnc2e884782016-08-11 19:45:1913028 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
13029
13030 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
13031
Ryan Hamilton0239aac2018-05-19 00:03:1313032 spdy::SpdySerializedFrame resp(
13033 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
13034 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
bnc2e884782016-08-11 19:45:1913035 MockRead spdy_reads[] = {
13036 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
13037 };
13038
Ryan Sleevib8d7ea02018-05-07 20:01:0113039 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
bnc2e884782016-08-11 19:45:1913040 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
13041
13042 TestCompletionCallback callback;
13043
13044 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
13045
tfarina42834112016-09-22 13:38:2013046 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc2e884782016-08-11 19:45:1913047 EXPECT_THAT(callback.GetResult(rv), IsOk());
13048
13049 const HttpResponseInfo* response = trans.GetResponseInfo();
13050 ASSERT_TRUE(response);
13051 ASSERT_TRUE(response->headers);
13052 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
13053 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213054 EXPECT_TRUE(response->was_alpn_negotiated);
bnc2e884782016-08-11 19:45:1913055
13056 std::string response_data;
13057 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
13058 EXPECT_EQ("hello!", response_data);
13059
13060 // Origin host bypasses proxy, no resolution should have happened.
13061 ASSERT_TRUE(capturing_proxy_resolver.resolved().empty());
13062}
13063
bncd16676a2016-07-20 16:23:0113064TEST_F(HttpNetworkTransactionTest, UseAlternativeServiceForTunneledNpnSpdy) {
[email protected]631f1322010-04-30 17:59:1113065 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:4213066 proxy_config.set_auto_detect(true);
13067 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:1113068
sammc5dd160c2015-04-02 02:43:1313069 CapturingProxyResolver capturing_proxy_resolver;
Ramin Halavatica8d5252018-03-12 05:33:4913070 session_deps_.proxy_resolution_service =
13071 std::make_unique<ProxyResolutionService>(
13072 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
13073 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
13074 std::make_unique<CapturingProxyResolverFactory>(
13075 &capturing_proxy_resolver),
13076 nullptr);
vishal.b62985ca92015-04-17 08:45:5113077 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0713078 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:1113079
13080 HttpRequestInfo request;
13081 request.method = "GET";
bncb26024382016-06-29 02:39:4513082 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1013083 request.traffic_annotation =
13084 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]631f1322010-04-30 17:59:1113085
13086 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5213087 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4313088 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5213089 MockRead("\r\n"),
13090 MockRead("hello world"),
13091 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
13092 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:1113093 };
13094
Ryan Sleevib8d7ea02018-05-07 20:01:0113095 StaticSocketDataProvider first_transaction(data_reads,
13096 base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0713097 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4513098 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613099 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4513100 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]631f1322010-04-30 17:59:1113101
bnc032658ba2016-09-26 18:17:1513102 AddSSLSocketData();
[email protected]631f1322010-04-30 17:59:1113103
Ryan Hamilton0239aac2018-05-19 00:03:1313104 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4513105 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
[email protected]631f1322010-04-30 17:59:1113106 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1313107 MockWrite(ASYNC, 0,
bnc8bef8da22016-05-30 01:28:2513108 "CONNECT www.example.org:443 HTTP/1.1\r\n"
13109 "Host: www.example.org:443\r\n"
rch8e6c6c42015-05-01 14:05:1313110 "Proxy-Connection: keep-alive\r\n\r\n"),
bncdf80d44fd2016-07-15 20:27:4113111 CreateMockWrite(req, 2),
[email protected]631f1322010-04-30 17:59:1113112 };
13113
[email protected]d911f1b2010-05-05 22:39:4213114 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
13115
Ryan Hamilton0239aac2018-05-19 00:03:1313116 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
13117 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]631f1322010-04-30 17:59:1113118 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113119 MockRead(ASYNC, 1, kCONNECTResponse), CreateMockRead(resp, 3),
13120 CreateMockRead(data, 4), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5),
[email protected]631f1322010-04-30 17:59:1113121 };
13122
Ryan Sleevib8d7ea02018-05-07 20:01:0113123 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0713124 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:1113125
[email protected]d973e99a2012-02-17 21:02:3613126 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0113127 StaticSocketDataProvider hanging_non_alternate_protocol_socket;
[email protected]2d6728692011-03-12 01:39:5513128 hanging_non_alternate_protocol_socket.set_connect_data(
13129 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0713130 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5513131 &hanging_non_alternate_protocol_socket);
13132
[email protected]49639fa2011-12-20 23:22:4113133 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:1113134
danakj1fd259a02016-04-16 03:17:0913135 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5813136 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1913137 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1113138
tfarina42834112016-09-22 13:38:2013139 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea2dcd3bf2016-08-16 21:49:4113140 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13141 EXPECT_THAT(callback.WaitForResult(), IsOk());
13142
13143 const HttpResponseInfo* response = trans->GetResponseInfo();
13144 ASSERT_TRUE(response);
13145 ASSERT_TRUE(response->headers);
13146 EXPECT_EQ("HTTP/0.9 200 OK", response->headers->GetStatusLine());
13147 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213148 EXPECT_TRUE(response->was_alpn_negotiated);
mmenkea2dcd3bf2016-08-16 21:49:4113149
13150 std::string response_data;
13151 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
13152 EXPECT_EQ("hello world", response_data);
[email protected]631f1322010-04-30 17:59:1113153
bnc87dcefc2017-05-25 12:47:5813154 trans =
Jeremy Roman0579ed62017-08-29 15:56:1913155 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1113156
tfarina42834112016-09-22 13:38:2013157 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113158 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13159 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]631f1322010-04-30 17:59:1113160
mmenkea2dcd3bf2016-08-16 21:49:4113161 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5213162 ASSERT_TRUE(response);
13163 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213164 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5313165 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213166 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]631f1322010-04-30 17:59:1113167
robpercival214763f2016-07-01 23:27:0113168 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]631f1322010-04-30 17:59:1113169 EXPECT_EQ("hello!", response_data);
bncb26024382016-06-29 02:39:4513170 ASSERT_EQ(2u, capturing_proxy_resolver.resolved().size());
13171 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1313172 capturing_proxy_resolver.resolved()[0].spec());
bncce36dca22015-04-21 22:11:2313173 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1313174 capturing_proxy_resolver.resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:1113175
[email protected]029c83b62013-01-24 05:28:2013176 LoadTimingInfo load_timing_info;
13177 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
13178 TestLoadTimingNotReusedWithPac(load_timing_info,
13179 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:1113180}
[email protected]631f1322010-04-30 17:59:1113181
bncd16676a2016-07-20 16:23:0113182TEST_F(HttpNetworkTransactionTest,
bnc1c196c6e2016-05-28 13:51:4813183 UseAlternativeServiceForNpnSpdyWithExistingSpdySession) {
[email protected]2ff8b312010-04-26 22:20:5413184 HttpRequestInfo request;
13185 request.method = "GET";
bncb26024382016-06-29 02:39:4513186 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1013187 request.traffic_annotation =
13188 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2ff8b312010-04-26 22:20:5413189
13190 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5213191 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4313192 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5213193 MockRead("\r\n"),
13194 MockRead("hello world"),
13195 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:5413196 };
13197
Ryan Sleevib8d7ea02018-05-07 20:01:0113198 StaticSocketDataProvider first_transaction(data_reads,
13199 base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0713200 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4513201 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613202 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4513203 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5413204
bnc032658ba2016-09-26 18:17:1513205 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5413206
Ryan Hamilton0239aac2018-05-19 00:03:1313207 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4513208 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4113209 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5413210
Ryan Hamilton0239aac2018-05-19 00:03:1313211 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
13212 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5413213 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113214 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5413215 };
13216
Ryan Sleevib8d7ea02018-05-07 20:01:0113217 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0713218 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5413219
[email protected]83039bb2011-12-09 18:43:5513220 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5413221
danakj1fd259a02016-04-16 03:17:0913222 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:5413223
bnc87dcefc2017-05-25 12:47:5813224 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1913225 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5413226
tfarina42834112016-09-22 13:38:2013227 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113228 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13229 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5413230
13231 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5213232 ASSERT_TRUE(response);
13233 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5413234 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13235
13236 std::string response_data;
robpercival214763f2016-07-01 23:27:0113237 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5413238 EXPECT_EQ("hello world", response_data);
13239
13240 // Set up an initial SpdySession in the pool to reuse.
bnc8bef8da22016-05-30 01:28:2513241 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4013242 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
Matt Menke2436b2f2018-12-11 18:07:1113243 PRIVACY_MODE_DISABLED,
13244 SpdySessionKey::IsProxySession::kFalse, SocketTag());
[email protected]795cbf82013-07-22 09:37:2713245 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:5213246 CreateSpdySession(session.get(), key, NetLogWithSource());
[email protected]02b0c342010-09-25 21:09:3813247
bnc87dcefc2017-05-25 12:47:5813248 trans =
Jeremy Roman0579ed62017-08-29 15:56:1913249 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5413250
tfarina42834112016-09-22 13:38:2013251 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113252 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13253 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5413254
13255 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5213256 ASSERT_TRUE(response);
13257 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213258 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5313259 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213260 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5413261
robpercival214763f2016-07-01 23:27:0113262 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5413263 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:4213264}
13265
[email protected]044de0642010-06-17 10:42:1513266// GenerateAuthToken is a mighty big test.
13267// It tests all permutation of GenerateAuthToken behavior:
13268// - Synchronous and Asynchronous completion.
13269// - OK or error on completion.
13270// - Direct connection, non-authenticating proxy, and authenticating proxy.
13271// - HTTP or HTTPS backend (to include proxy tunneling).
13272// - Non-authenticating and authenticating backend.
13273//
[email protected]fe3b7dc2012-02-03 19:52:0913274// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:1513275// problems generating an auth token for an authenticating proxy, we don't
13276// need to test all permutations of the backend server).
13277//
13278// The test proceeds by going over each of the configuration cases, and
13279// potentially running up to three rounds in each of the tests. The TestConfig
13280// specifies both the configuration for the test as well as the expectations
13281// for the results.
bncd16676a2016-07-20 16:23:0113282TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:5013283 static const char kServer[] = "http://www.example.com";
13284 static const char kSecureServer[] = "https://www.example.com";
13285 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:1513286
13287 enum AuthTiming {
13288 AUTH_NONE,
13289 AUTH_SYNC,
13290 AUTH_ASYNC,
13291 };
13292
13293 const MockWrite kGet(
13294 "GET / HTTP/1.1\r\n"
13295 "Host: www.example.com\r\n"
13296 "Connection: keep-alive\r\n\r\n");
13297 const MockWrite kGetProxy(
13298 "GET http://www.example.com/ HTTP/1.1\r\n"
13299 "Host: www.example.com\r\n"
13300 "Proxy-Connection: keep-alive\r\n\r\n");
13301 const MockWrite kGetAuth(
13302 "GET / HTTP/1.1\r\n"
13303 "Host: www.example.com\r\n"
13304 "Connection: keep-alive\r\n"
13305 "Authorization: auth_token\r\n\r\n");
13306 const MockWrite kGetProxyAuth(
13307 "GET http://www.example.com/ HTTP/1.1\r\n"
13308 "Host: www.example.com\r\n"
13309 "Proxy-Connection: keep-alive\r\n"
13310 "Proxy-Authorization: auth_token\r\n\r\n");
13311 const MockWrite kGetAuthThroughProxy(
13312 "GET http://www.example.com/ HTTP/1.1\r\n"
13313 "Host: www.example.com\r\n"
13314 "Proxy-Connection: keep-alive\r\n"
13315 "Authorization: auth_token\r\n\r\n");
13316 const MockWrite kGetAuthWithProxyAuth(
13317 "GET http://www.example.com/ HTTP/1.1\r\n"
13318 "Host: www.example.com\r\n"
13319 "Proxy-Connection: keep-alive\r\n"
13320 "Proxy-Authorization: auth_token\r\n"
13321 "Authorization: auth_token\r\n\r\n");
13322 const MockWrite kConnect(
13323 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1713324 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1513325 "Proxy-Connection: keep-alive\r\n\r\n");
13326 const MockWrite kConnectProxyAuth(
13327 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1713328 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1513329 "Proxy-Connection: keep-alive\r\n"
13330 "Proxy-Authorization: auth_token\r\n\r\n");
13331
13332 const MockRead kSuccess(
13333 "HTTP/1.1 200 OK\r\n"
13334 "Content-Type: text/html; charset=iso-8859-1\r\n"
13335 "Content-Length: 3\r\n\r\n"
13336 "Yes");
13337 const MockRead kFailure(
13338 "Should not be called.");
13339 const MockRead kServerChallenge(
13340 "HTTP/1.1 401 Unauthorized\r\n"
13341 "WWW-Authenticate: Mock realm=server\r\n"
13342 "Content-Type: text/html; charset=iso-8859-1\r\n"
13343 "Content-Length: 14\r\n\r\n"
13344 "Unauthorized\r\n");
13345 const MockRead kProxyChallenge(
13346 "HTTP/1.1 407 Unauthorized\r\n"
13347 "Proxy-Authenticate: Mock realm=proxy\r\n"
13348 "Proxy-Connection: close\r\n"
13349 "Content-Type: text/html; charset=iso-8859-1\r\n"
13350 "Content-Length: 14\r\n\r\n"
13351 "Unauthorized\r\n");
13352 const MockRead kProxyConnected(
13353 "HTTP/1.1 200 Connection Established\r\n\r\n");
13354
13355 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
13356 // no constructors, but the C++ compiler on Windows warns about
13357 // unspecified data in compound literals. So, moved to using constructors,
13358 // and TestRound's created with the default constructor should not be used.
13359 struct TestRound {
13360 TestRound()
13361 : expected_rv(ERR_UNEXPECTED),
13362 extra_write(NULL),
13363 extra_read(NULL) {
13364 }
13365 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
13366 int expected_rv_arg)
13367 : write(write_arg),
13368 read(read_arg),
13369 expected_rv(expected_rv_arg),
13370 extra_write(NULL),
13371 extra_read(NULL) {
13372 }
13373 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
13374 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:0113375 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:1513376 : write(write_arg),
13377 read(read_arg),
13378 expected_rv(expected_rv_arg),
13379 extra_write(extra_write_arg),
13380 extra_read(extra_read_arg) {
13381 }
13382 MockWrite write;
13383 MockRead read;
13384 int expected_rv;
13385 const MockWrite* extra_write;
13386 const MockRead* extra_read;
13387 };
13388
13389 static const int kNoSSL = 500;
13390
13391 struct TestConfig {
asanka463ca4262016-11-16 02:34:3113392 int line_number;
thestig9d3bb0c2015-01-24 00:49:5113393 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:1513394 AuthTiming proxy_auth_timing;
asanka463ca4262016-11-16 02:34:3113395 int first_generate_proxy_token_rv;
thestig9d3bb0c2015-01-24 00:49:5113396 const char* const server_url;
[email protected]044de0642010-06-17 10:42:1513397 AuthTiming server_auth_timing;
asanka463ca4262016-11-16 02:34:3113398 int first_generate_server_token_rv;
[email protected]044de0642010-06-17 10:42:1513399 int num_auth_rounds;
13400 int first_ssl_round;
asankae2257db2016-10-11 22:03:1613401 TestRound rounds[4];
[email protected]044de0642010-06-17 10:42:1513402 } test_configs[] = {
asankac93076192016-10-03 15:46:0213403 // Non-authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3113404 {__LINE__,
13405 nullptr,
asankac93076192016-10-03 15:46:0213406 AUTH_NONE,
13407 OK,
13408 kServer,
13409 AUTH_NONE,
13410 OK,
13411 1,
13412 kNoSSL,
13413 {TestRound(kGet, kSuccess, OK)}},
13414 // Authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3113415 {__LINE__,
13416 nullptr,
asankac93076192016-10-03 15:46:0213417 AUTH_NONE,
13418 OK,
13419 kServer,
13420 AUTH_SYNC,
13421 OK,
13422 2,
13423 kNoSSL,
13424 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513425 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113426 {__LINE__,
13427 nullptr,
asankac93076192016-10-03 15:46:0213428 AUTH_NONE,
13429 OK,
13430 kServer,
13431 AUTH_SYNC,
13432 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1613433 3,
13434 kNoSSL,
13435 {TestRound(kGet, kServerChallenge, OK),
13436 TestRound(kGet, kServerChallenge, OK),
13437 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113438 {__LINE__,
13439 nullptr,
asankae2257db2016-10-11 22:03:1613440 AUTH_NONE,
13441 OK,
13442 kServer,
13443 AUTH_SYNC,
13444 ERR_UNSUPPORTED_AUTH_SCHEME,
13445 2,
13446 kNoSSL,
13447 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113448 {__LINE__,
13449 nullptr,
asankae2257db2016-10-11 22:03:1613450 AUTH_NONE,
13451 OK,
13452 kServer,
13453 AUTH_SYNC,
13454 ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS,
13455 2,
13456 kNoSSL,
13457 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113458 {__LINE__,
13459 kProxy,
asankae2257db2016-10-11 22:03:1613460 AUTH_SYNC,
13461 ERR_FAILED,
13462 kServer,
13463 AUTH_NONE,
13464 OK,
13465 2,
13466 kNoSSL,
13467 {TestRound(kGetProxy, kProxyChallenge, OK),
13468 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3113469 {__LINE__,
13470 kProxy,
asankae2257db2016-10-11 22:03:1613471 AUTH_ASYNC,
13472 ERR_FAILED,
13473 kServer,
13474 AUTH_NONE,
13475 OK,
13476 2,
13477 kNoSSL,
13478 {TestRound(kGetProxy, kProxyChallenge, OK),
13479 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3113480 {__LINE__,
13481 nullptr,
asankae2257db2016-10-11 22:03:1613482 AUTH_NONE,
13483 OK,
13484 kServer,
13485 AUTH_SYNC,
13486 ERR_FAILED,
asankac93076192016-10-03 15:46:0213487 2,
13488 kNoSSL,
13489 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613490 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3113491 {__LINE__,
13492 nullptr,
asankae2257db2016-10-11 22:03:1613493 AUTH_NONE,
13494 OK,
13495 kServer,
13496 AUTH_ASYNC,
13497 ERR_FAILED,
13498 2,
13499 kNoSSL,
13500 {TestRound(kGet, kServerChallenge, OK),
13501 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3113502 {__LINE__,
13503 nullptr,
asankac93076192016-10-03 15:46:0213504 AUTH_NONE,
13505 OK,
13506 kServer,
13507 AUTH_ASYNC,
13508 OK,
13509 2,
13510 kNoSSL,
13511 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513512 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113513 {__LINE__,
13514 nullptr,
asankac93076192016-10-03 15:46:0213515 AUTH_NONE,
13516 OK,
13517 kServer,
13518 AUTH_ASYNC,
13519 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1613520 3,
asankac93076192016-10-03 15:46:0213521 kNoSSL,
13522 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613523 // The second round uses a HttpAuthHandlerMock that always succeeds.
13524 TestRound(kGet, kServerChallenge, OK),
13525 TestRound(kGetAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213526 // Non-authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3113527 {__LINE__,
13528 kProxy,
asankac93076192016-10-03 15:46:0213529 AUTH_NONE,
13530 OK,
13531 kServer,
13532 AUTH_NONE,
13533 OK,
13534 1,
13535 kNoSSL,
13536 {TestRound(kGetProxy, kSuccess, OK)}},
13537 // Authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3113538 {__LINE__,
13539 kProxy,
asankac93076192016-10-03 15:46:0213540 AUTH_NONE,
13541 OK,
13542 kServer,
13543 AUTH_SYNC,
13544 OK,
13545 2,
13546 kNoSSL,
13547 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513548 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113549 {__LINE__,
13550 kProxy,
asankac93076192016-10-03 15:46:0213551 AUTH_NONE,
13552 OK,
13553 kServer,
13554 AUTH_SYNC,
13555 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1613556 3,
asankac93076192016-10-03 15:46:0213557 kNoSSL,
13558 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613559 TestRound(kGetProxy, kServerChallenge, OK),
13560 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113561 {__LINE__,
13562 kProxy,
asankac93076192016-10-03 15:46:0213563 AUTH_NONE,
13564 OK,
13565 kServer,
13566 AUTH_ASYNC,
13567 OK,
13568 2,
13569 kNoSSL,
13570 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513571 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113572 {__LINE__,
13573 kProxy,
asankac93076192016-10-03 15:46:0213574 AUTH_NONE,
13575 OK,
13576 kServer,
13577 AUTH_ASYNC,
13578 ERR_INVALID_AUTH_CREDENTIALS,
13579 2,
13580 kNoSSL,
13581 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613582 TestRound(kGetProxy, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213583 // Non-authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3113584 {__LINE__,
13585 kProxy,
asankac93076192016-10-03 15:46:0213586 AUTH_SYNC,
13587 OK,
13588 kServer,
13589 AUTH_NONE,
13590 OK,
13591 2,
13592 kNoSSL,
13593 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513594 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113595 {__LINE__,
13596 kProxy,
asankac93076192016-10-03 15:46:0213597 AUTH_SYNC,
13598 ERR_INVALID_AUTH_CREDENTIALS,
13599 kServer,
13600 AUTH_NONE,
13601 OK,
13602 2,
13603 kNoSSL,
13604 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1613605 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113606 {__LINE__,
13607 kProxy,
asankac93076192016-10-03 15:46:0213608 AUTH_ASYNC,
13609 OK,
13610 kServer,
13611 AUTH_NONE,
13612 OK,
13613 2,
13614 kNoSSL,
13615 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513616 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113617 {__LINE__,
13618 kProxy,
asankac93076192016-10-03 15:46:0213619 AUTH_ASYNC,
13620 ERR_INVALID_AUTH_CREDENTIALS,
13621 kServer,
13622 AUTH_NONE,
13623 OK,
13624 2,
13625 kNoSSL,
13626 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1613627 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113628 {__LINE__,
13629 kProxy,
13630 AUTH_ASYNC,
13631 ERR_INVALID_AUTH_CREDENTIALS,
13632 kServer,
13633 AUTH_NONE,
13634 OK,
13635 3,
13636 kNoSSL,
13637 {TestRound(kGetProxy, kProxyChallenge, OK),
13638 TestRound(kGetProxy, kProxyChallenge, OK),
13639 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213640 // Authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3113641 {__LINE__,
13642 kProxy,
asankac93076192016-10-03 15:46:0213643 AUTH_SYNC,
13644 OK,
13645 kServer,
13646 AUTH_SYNC,
13647 OK,
13648 3,
13649 kNoSSL,
13650 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513651 TestRound(kGetProxyAuth, kServerChallenge, OK),
13652 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113653 {__LINE__,
13654 kProxy,
asankac93076192016-10-03 15:46:0213655 AUTH_SYNC,
13656 OK,
13657 kServer,
13658 AUTH_SYNC,
13659 ERR_INVALID_AUTH_CREDENTIALS,
13660 3,
13661 kNoSSL,
13662 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513663 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613664 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113665 {__LINE__,
13666 kProxy,
asankac93076192016-10-03 15:46:0213667 AUTH_ASYNC,
13668 OK,
13669 kServer,
13670 AUTH_SYNC,
13671 OK,
13672 3,
13673 kNoSSL,
13674 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513675 TestRound(kGetProxyAuth, kServerChallenge, OK),
13676 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113677 {__LINE__,
13678 kProxy,
asankac93076192016-10-03 15:46:0213679 AUTH_ASYNC,
13680 OK,
13681 kServer,
13682 AUTH_SYNC,
13683 ERR_INVALID_AUTH_CREDENTIALS,
13684 3,
13685 kNoSSL,
13686 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513687 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613688 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113689 {__LINE__,
13690 kProxy,
asankac93076192016-10-03 15:46:0213691 AUTH_SYNC,
13692 OK,
13693 kServer,
13694 AUTH_ASYNC,
13695 OK,
13696 3,
13697 kNoSSL,
13698 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513699 TestRound(kGetProxyAuth, kServerChallenge, OK),
13700 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113701 {__LINE__,
13702 kProxy,
13703 AUTH_SYNC,
13704 ERR_INVALID_AUTH_CREDENTIALS,
13705 kServer,
13706 AUTH_ASYNC,
13707 OK,
13708 4,
13709 kNoSSL,
13710 {TestRound(kGetProxy, kProxyChallenge, OK),
13711 TestRound(kGetProxy, kProxyChallenge, OK),
13712 TestRound(kGetProxyAuth, kServerChallenge, OK),
13713 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
13714 {__LINE__,
13715 kProxy,
asankac93076192016-10-03 15:46:0213716 AUTH_SYNC,
13717 OK,
13718 kServer,
13719 AUTH_ASYNC,
13720 ERR_INVALID_AUTH_CREDENTIALS,
13721 3,
13722 kNoSSL,
13723 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513724 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613725 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113726 {__LINE__,
13727 kProxy,
asankac93076192016-10-03 15:46:0213728 AUTH_ASYNC,
13729 OK,
13730 kServer,
13731 AUTH_ASYNC,
13732 OK,
13733 3,
13734 kNoSSL,
13735 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513736 TestRound(kGetProxyAuth, kServerChallenge, OK),
13737 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113738 {__LINE__,
13739 kProxy,
asankac93076192016-10-03 15:46:0213740 AUTH_ASYNC,
13741 OK,
13742 kServer,
13743 AUTH_ASYNC,
13744 ERR_INVALID_AUTH_CREDENTIALS,
13745 3,
13746 kNoSSL,
13747 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513748 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613749 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113750 {__LINE__,
13751 kProxy,
13752 AUTH_ASYNC,
13753 ERR_INVALID_AUTH_CREDENTIALS,
13754 kServer,
13755 AUTH_ASYNC,
13756 ERR_INVALID_AUTH_CREDENTIALS,
13757 4,
13758 kNoSSL,
13759 {TestRound(kGetProxy, kProxyChallenge, OK),
13760 TestRound(kGetProxy, kProxyChallenge, OK),
13761 TestRound(kGetProxyAuth, kServerChallenge, OK),
13762 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213763 // Non-authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3113764 {__LINE__,
13765 nullptr,
asankac93076192016-10-03 15:46:0213766 AUTH_NONE,
13767 OK,
13768 kSecureServer,
13769 AUTH_NONE,
13770 OK,
13771 1,
13772 0,
13773 {TestRound(kGet, kSuccess, OK)}},
13774 // Authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3113775 {__LINE__,
13776 nullptr,
asankac93076192016-10-03 15:46:0213777 AUTH_NONE,
13778 OK,
13779 kSecureServer,
13780 AUTH_SYNC,
13781 OK,
13782 2,
13783 0,
13784 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513785 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113786 {__LINE__,
13787 nullptr,
asankac93076192016-10-03 15:46:0213788 AUTH_NONE,
13789 OK,
13790 kSecureServer,
13791 AUTH_SYNC,
13792 ERR_INVALID_AUTH_CREDENTIALS,
13793 2,
13794 0,
asankae2257db2016-10-11 22:03:1613795 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113796 {__LINE__,
13797 nullptr,
asankac93076192016-10-03 15:46:0213798 AUTH_NONE,
13799 OK,
13800 kSecureServer,
13801 AUTH_ASYNC,
13802 OK,
13803 2,
13804 0,
13805 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513806 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113807 {__LINE__,
13808 nullptr,
asankac93076192016-10-03 15:46:0213809 AUTH_NONE,
13810 OK,
13811 kSecureServer,
13812 AUTH_ASYNC,
13813 ERR_INVALID_AUTH_CREDENTIALS,
13814 2,
13815 0,
asankae2257db2016-10-11 22:03:1613816 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213817 // Non-authenticating HTTPS server with a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3113818 {__LINE__,
13819 kProxy,
asankac93076192016-10-03 15:46:0213820 AUTH_NONE,
13821 OK,
13822 kSecureServer,
13823 AUTH_NONE,
13824 OK,
13825 1,
13826 0,
13827 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
13828 // Authenticating HTTPS server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3113829 {__LINE__,
13830 kProxy,
asankac93076192016-10-03 15:46:0213831 AUTH_NONE,
13832 OK,
13833 kSecureServer,
13834 AUTH_SYNC,
13835 OK,
13836 2,
13837 0,
13838 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513839 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113840 {__LINE__,
13841 kProxy,
asankac93076192016-10-03 15:46:0213842 AUTH_NONE,
13843 OK,
13844 kSecureServer,
13845 AUTH_SYNC,
13846 ERR_INVALID_AUTH_CREDENTIALS,
13847 2,
13848 0,
13849 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1613850 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113851 {__LINE__,
13852 kProxy,
asankac93076192016-10-03 15:46:0213853 AUTH_NONE,
13854 OK,
13855 kSecureServer,
13856 AUTH_ASYNC,
13857 OK,
13858 2,
13859 0,
13860 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513861 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113862 {__LINE__,
13863 kProxy,
asankac93076192016-10-03 15:46:0213864 AUTH_NONE,
13865 OK,
13866 kSecureServer,
13867 AUTH_ASYNC,
13868 ERR_INVALID_AUTH_CREDENTIALS,
13869 2,
13870 0,
13871 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1613872 TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213873 // Non-Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3113874 {__LINE__,
13875 kProxy,
asankac93076192016-10-03 15:46:0213876 AUTH_SYNC,
13877 OK,
13878 kSecureServer,
13879 AUTH_NONE,
13880 OK,
13881 2,
13882 1,
13883 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513884 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113885 {__LINE__,
13886 kProxy,
asankac93076192016-10-03 15:46:0213887 AUTH_SYNC,
13888 ERR_INVALID_AUTH_CREDENTIALS,
13889 kSecureServer,
13890 AUTH_NONE,
13891 OK,
13892 2,
13893 kNoSSL,
13894 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1613895 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113896 {__LINE__,
13897 kProxy,
asankae2257db2016-10-11 22:03:1613898 AUTH_SYNC,
13899 ERR_UNSUPPORTED_AUTH_SCHEME,
13900 kSecureServer,
13901 AUTH_NONE,
13902 OK,
13903 2,
13904 kNoSSL,
13905 {TestRound(kConnect, kProxyChallenge, OK),
13906 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113907 {__LINE__,
13908 kProxy,
asankae2257db2016-10-11 22:03:1613909 AUTH_SYNC,
13910 ERR_UNEXPECTED,
13911 kSecureServer,
13912 AUTH_NONE,
13913 OK,
13914 2,
13915 kNoSSL,
13916 {TestRound(kConnect, kProxyChallenge, OK),
13917 TestRound(kConnect, kProxyConnected, ERR_UNEXPECTED)}},
asanka463ca4262016-11-16 02:34:3113918 {__LINE__,
13919 kProxy,
asankac93076192016-10-03 15:46:0213920 AUTH_ASYNC,
13921 OK,
13922 kSecureServer,
13923 AUTH_NONE,
13924 OK,
13925 2,
13926 1,
13927 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513928 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113929 {__LINE__,
13930 kProxy,
asankac93076192016-10-03 15:46:0213931 AUTH_ASYNC,
13932 ERR_INVALID_AUTH_CREDENTIALS,
13933 kSecureServer,
13934 AUTH_NONE,
13935 OK,
13936 2,
13937 kNoSSL,
13938 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1613939 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asankac93076192016-10-03 15:46:0213940 // Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3113941 {__LINE__,
13942 kProxy,
asankac93076192016-10-03 15:46:0213943 AUTH_SYNC,
13944 OK,
13945 kSecureServer,
13946 AUTH_SYNC,
13947 OK,
13948 3,
13949 1,
13950 {TestRound(kConnect, kProxyChallenge, OK),
13951 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13952 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513953 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113954 {__LINE__,
13955 kProxy,
asankac93076192016-10-03 15:46:0213956 AUTH_SYNC,
13957 OK,
13958 kSecureServer,
13959 AUTH_SYNC,
13960 ERR_INVALID_AUTH_CREDENTIALS,
13961 3,
13962 1,
13963 {TestRound(kConnect, kProxyChallenge, OK),
13964 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13965 &kServerChallenge),
asankae2257db2016-10-11 22:03:1613966 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113967 {__LINE__,
13968 kProxy,
asankac93076192016-10-03 15:46:0213969 AUTH_ASYNC,
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_ASYNC,
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_SYNC,
13996 OK,
13997 kSecureServer,
13998 AUTH_ASYNC,
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_SYNC,
14009 OK,
14010 kSecureServer,
14011 AUTH_ASYNC,
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_ASYNC,
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_ASYNC,
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,
14047 AUTH_ASYNC,
14048 ERR_INVALID_AUTH_CREDENTIALS,
14049 kSecureServer,
14050 AUTH_ASYNC,
14051 ERR_INVALID_AUTH_CREDENTIALS,
14052 4,
14053 2,
14054 {TestRound(kConnect, kProxyChallenge, OK),
14055 TestRound(kConnect, kProxyChallenge, OK),
14056 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14057 &kServerChallenge),
14058 TestRound(kGet, kSuccess, OK)}},
[email protected]044de0642010-06-17 10:42:1514059 };
14060
asanka463ca4262016-11-16 02:34:3114061 for (const auto& test_config : test_configs) {
14062 SCOPED_TRACE(::testing::Message() << "Test config at "
14063 << test_config.line_number);
[email protected]2d01c262011-08-11 23:07:0814064 HttpAuthHandlerMock::Factory* auth_factory(
14065 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0714066 session_deps_.http_auth_handler_factory.reset(auth_factory);
asanka5ffd5d72016-03-23 16:20:4914067 SSLInfo empty_ssl_info;
[email protected]65d34382010-07-01 18:12:2614068
14069 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:1514070 if (test_config.proxy_auth_timing != AUTH_NONE) {
asanka463ca4262016-11-16 02:34:3114071 for (int n = 0; n < 3; n++) {
[email protected]2d01c262011-08-11 23:07:0814072 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
14073 std::string auth_challenge = "Mock realm=proxy";
14074 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:2414075 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
14076 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:0814077 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
tfarina42834112016-09-22 13:38:2014078 empty_ssl_info, origin,
14079 NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0814080 auth_handler->SetGenerateExpectation(
14081 test_config.proxy_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3114082 n == 0 ? test_config.first_generate_proxy_token_rv : OK);
[email protected]2d01c262011-08-11 23:07:0814083 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
14084 }
[email protected]044de0642010-06-17 10:42:1514085 }
14086 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:0014087 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:1514088 std::string auth_challenge = "Mock realm=server";
14089 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:2414090 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
14091 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:1514092 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2014093 empty_ssl_info, origin,
14094 NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1514095 auth_handler->SetGenerateExpectation(
14096 test_config.server_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3114097 test_config.first_generate_server_token_rv);
[email protected]2d01c262011-08-11 23:07:0814098 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
asankae2257db2016-10-11 22:03:1614099
14100 // The second handler always succeeds. It should only be used where there
14101 // are multiple auth sessions for server auth in the same network
14102 // transaction using the same auth scheme.
14103 std::unique_ptr<HttpAuthHandlerMock> second_handler =
Jeremy Roman0579ed62017-08-29 15:56:1914104 std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:1614105 second_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
14106 empty_ssl_info, origin,
14107 NetLogWithSource());
14108 second_handler->SetGenerateExpectation(true, OK);
14109 auth_factory->AddMockHandler(second_handler.release(),
14110 HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:1514111 }
14112 if (test_config.proxy_url) {
Lily Houghton8c2f97d2018-01-22 05:06:5914113 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4914114 ProxyResolutionService::CreateFixed(test_config.proxy_url,
14115 TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]044de0642010-06-17 10:42:1514116 } else {
Bence Béky53a5aef2018-03-29 21:54:1214117 session_deps_.proxy_resolution_service =
14118 ProxyResolutionService::CreateDirect();
[email protected]044de0642010-06-17 10:42:1514119 }
14120
14121 HttpRequestInfo request;
14122 request.method = "GET";
14123 request.url = GURL(test_config.server_url);
Ramin Halavatib5e433e2018-02-07 07:41:1014124 request.traffic_annotation =
14125 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]044de0642010-06-17 10:42:1514126
danakj1fd259a02016-04-16 03:17:0914127 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]044de0642010-06-17 10:42:1514128
rchcb68dc62015-05-21 04:45:3614129 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
14130
14131 std::vector<std::vector<MockRead>> mock_reads(1);
14132 std::vector<std::vector<MockWrite>> mock_writes(1);
[email protected]044de0642010-06-17 10:42:1514133 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2214134 SCOPED_TRACE(round);
[email protected]044de0642010-06-17 10:42:1514135 const TestRound& read_write_round = test_config.rounds[round];
14136
14137 // Set up expected reads and writes.
rchcb68dc62015-05-21 04:45:3614138 mock_reads.back().push_back(read_write_round.read);
14139 mock_writes.back().push_back(read_write_round.write);
14140
14141 // kProxyChallenge uses Proxy-Connection: close which means that the
14142 // socket is closed and a new one will be created for the next request.
mmenkee71e15332015-10-07 16:39:5414143 if (read_write_round.read.data == kProxyChallenge.data) {
rchcb68dc62015-05-21 04:45:3614144 mock_reads.push_back(std::vector<MockRead>());
14145 mock_writes.push_back(std::vector<MockWrite>());
[email protected]044de0642010-06-17 10:42:1514146 }
14147
rchcb68dc62015-05-21 04:45:3614148 if (read_write_round.extra_read) {
14149 mock_reads.back().push_back(*read_write_round.extra_read);
[email protected]044de0642010-06-17 10:42:1514150 }
rchcb68dc62015-05-21 04:45:3614151 if (read_write_round.extra_write) {
14152 mock_writes.back().push_back(*read_write_round.extra_write);
14153 }
[email protected]044de0642010-06-17 10:42:1514154
14155 // Add an SSL sequence if necessary.
[email protected]044de0642010-06-17 10:42:1514156 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0714157 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1514158 &ssl_socket_data_provider);
rchcb68dc62015-05-21 04:45:3614159 }
[email protected]044de0642010-06-17 10:42:1514160
danakj1fd259a02016-04-16 03:17:0914161 std::vector<std::unique_ptr<StaticSocketDataProvider>> data_providers;
rchcb68dc62015-05-21 04:45:3614162 for (size_t i = 0; i < mock_reads.size(); ++i) {
Jeremy Roman0579ed62017-08-29 15:56:1914163 data_providers.push_back(std::make_unique<StaticSocketDataProvider>(
Ryan Sleevib8d7ea02018-05-07 20:01:0114164 mock_reads[i], mock_writes[i]));
rchcb68dc62015-05-21 04:45:3614165 session_deps_.socket_factory->AddSocketDataProvider(
olli.raula525048c2015-12-10 07:38:3214166 data_providers.back().get());
rchcb68dc62015-05-21 04:45:3614167 }
14168
mmenkecc2298e2015-12-07 18:20:1814169 // Transaction must be created after DataProviders, so it's destroyed before
14170 // they are as well.
14171 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
14172
rchcb68dc62015-05-21 04:45:3614173 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2214174 SCOPED_TRACE(round);
rchcb68dc62015-05-21 04:45:3614175 const TestRound& read_write_round = test_config.rounds[round];
[email protected]044de0642010-06-17 10:42:1514176 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4114177 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1514178 int rv;
14179 if (round == 0) {
tfarina42834112016-09-22 13:38:2014180 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1514181 } else {
[email protected]49639fa2011-12-20 23:22:4114182 rv = trans.RestartWithAuth(
14183 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1514184 }
14185 if (rv == ERR_IO_PENDING)
14186 rv = callback.WaitForResult();
14187
14188 // Compare results with expected data.
asankae2257db2016-10-11 22:03:1614189 EXPECT_THAT(rv, IsError(read_write_round.expected_rv));
[email protected]0b0bf032010-09-21 18:08:5014190 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttlec0c828492015-05-15 01:25:5514191 if (read_write_round.expected_rv != OK) {
[email protected]044de0642010-06-17 10:42:1514192 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
14193 continue;
14194 }
14195 if (round + 1 < test_config.num_auth_rounds) {
wezca1070932016-05-26 20:30:5214196 EXPECT_TRUE(response->auth_challenge);
[email protected]044de0642010-06-17 10:42:1514197 } else {
wezca1070932016-05-26 20:30:5214198 EXPECT_FALSE(response->auth_challenge);
asankae2257db2016-10-11 22:03:1614199 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]044de0642010-06-17 10:42:1514200 }
14201 }
[email protected]e5ae96a2010-04-14 20:12:4514202 }
14203}
14204
bncd16676a2016-07-20 16:23:0114205TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1414206 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1414207 HttpAuthHandlerMock::Factory* auth_factory(
14208 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0714209 session_deps_.http_auth_handler_factory.reset(auth_factory);
Bence Béky53a5aef2018-03-29 21:54:1214210 session_deps_.proxy_resolution_service =
14211 ProxyResolutionService::CreateDirect();
[email protected]bb88e1d32013-05-03 23:11:0714212 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
[email protected]c871bce92010-07-15 21:51:1414213
14214 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
14215 auth_handler->set_connection_based(true);
14216 std::string auth_challenge = "Mock realm=server";
14217 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2414218 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
14219 auth_challenge.end());
asanka5ffd5d72016-03-23 16:20:4914220 SSLInfo empty_ssl_info;
[email protected]c871bce92010-07-15 21:51:1414221 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2014222 empty_ssl_info, origin, NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0814223 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1414224
[email protected]c871bce92010-07-15 21:51:1414225 int rv = OK;
14226 const HttpResponseInfo* response = NULL;
14227 HttpRequestInfo request;
14228 request.method = "GET";
14229 request.url = origin;
Ramin Halavatib5e433e2018-02-07 07:41:1014230 request.traffic_annotation =
14231 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2714232
danakj1fd259a02016-04-16 03:17:0914233 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1014234
14235 // Use a TCP Socket Pool with only one connection per group. This is used
14236 // to validate that the TCP socket is not released to the pool between
14237 // each round of multi-round authentication.
mmenkee65e7af2015-10-13 17:16:4214238 HttpNetworkSessionPeer session_peer(session.get());
[email protected]ab739042011-04-07 15:22:2814239 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:1014240 50, // Max sockets for pool
14241 1, // Max sockets per group
tbansal7b403bcc2016-04-13 22:33:2114242 session_deps_.host_resolver.get(), session_deps_.socket_factory.get(),
14243 NULL, session_deps_.net_log);
Jeremy Roman0579ed62017-08-29 15:56:1914244 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
[email protected]a42dbd142011-11-17 16:42:0214245 mock_pool_manager->SetTransportSocketPool(transport_pool);
dchengc7eeda422015-12-26 03:56:4814246 session_peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]7ef4cbbb2011-02-06 11:19:1014247
bnc691fda62016-08-12 00:43:1614248 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4114249 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1414250
14251 const MockWrite kGet(
14252 "GET / HTTP/1.1\r\n"
14253 "Host: www.example.com\r\n"
14254 "Connection: keep-alive\r\n\r\n");
14255 const MockWrite kGetAuth(
14256 "GET / HTTP/1.1\r\n"
14257 "Host: www.example.com\r\n"
14258 "Connection: keep-alive\r\n"
14259 "Authorization: auth_token\r\n\r\n");
14260
14261 const MockRead kServerChallenge(
14262 "HTTP/1.1 401 Unauthorized\r\n"
14263 "WWW-Authenticate: Mock realm=server\r\n"
14264 "Content-Type: text/html; charset=iso-8859-1\r\n"
14265 "Content-Length: 14\r\n\r\n"
14266 "Unauthorized\r\n");
14267 const MockRead kSuccess(
14268 "HTTP/1.1 200 OK\r\n"
14269 "Content-Type: text/html; charset=iso-8859-1\r\n"
14270 "Content-Length: 3\r\n\r\n"
14271 "Yes");
14272
14273 MockWrite writes[] = {
14274 // First round
14275 kGet,
14276 // Second round
14277 kGetAuth,
14278 // Third round
14279 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3014280 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1014281 kGetAuth,
14282 // Competing request
14283 kGet,
[email protected]c871bce92010-07-15 21:51:1414284 };
14285 MockRead reads[] = {
14286 // First round
14287 kServerChallenge,
14288 // Second round
14289 kServerChallenge,
14290 // Third round
[email protected]eca50e122010-09-11 14:03:3014291 kServerChallenge,
14292 // Fourth round
[email protected]c871bce92010-07-15 21:51:1414293 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1014294 // Competing response
14295 kSuccess,
[email protected]c871bce92010-07-15 21:51:1414296 };
Ryan Sleevib8d7ea02018-05-07 20:01:0114297 StaticSocketDataProvider data_provider(reads, writes);
[email protected]bb88e1d32013-05-03 23:11:0714298 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1414299
thestig9d3bb0c2015-01-24 00:49:5114300 const char kSocketGroup[] = "www.example.com:80";
[email protected]7ef4cbbb2011-02-06 11:19:1014301
14302 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1414303 auth_handler->SetGenerateExpectation(false, OK);
tfarina42834112016-09-22 13:38:2014304 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]c871bce92010-07-15 21:51:1414305 if (rv == ERR_IO_PENDING)
14306 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114307 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1614308 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214309 ASSERT_TRUE(response);
14310 EXPECT_TRUE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2814311 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3114312 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
14313 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1414314
[email protected]7ef4cbbb2011-02-06 11:19:1014315 // In between rounds, another request comes in for the same domain.
14316 // It should not be able to grab the TCP socket that trans has already
14317 // claimed.
bnc691fda62016-08-12 00:43:1614318 HttpNetworkTransaction trans_compete(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4114319 TestCompletionCallback callback_compete;
tfarina42834112016-09-22 13:38:2014320 rv = trans_compete.Start(&request, callback_compete.callback(),
14321 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114322 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7ef4cbbb2011-02-06 11:19:1014323 // callback_compete.WaitForResult at this point would stall forever,
14324 // since the HttpNetworkTransaction does not release the request back to
14325 // the pool until after authentication completes.
14326
14327 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1414328 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1614329 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1414330 if (rv == ERR_IO_PENDING)
14331 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114332 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1614333 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214334 ASSERT_TRUE(response);
14335 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2814336 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3114337 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
14338 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1414339
[email protected]7ef4cbbb2011-02-06 11:19:1014340 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1414341 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1614342 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1414343 if (rv == ERR_IO_PENDING)
14344 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114345 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1614346 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214347 ASSERT_TRUE(response);
14348 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2814349 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3114350 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
14351 auth_handler->state());
[email protected]eca50e122010-09-11 14:03:3014352
[email protected]7ef4cbbb2011-02-06 11:19:1014353 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3014354 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1614355 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3014356 if (rv == ERR_IO_PENDING)
14357 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114358 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1614359 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214360 ASSERT_TRUE(response);
14361 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2814362 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1014363
asanka463ca4262016-11-16 02:34:3114364 // In WAIT_FOR_CHALLENGE, although in reality the auth handler is done. A real
14365 // auth handler should transition to a DONE state in concert with the remote
14366 // server. But that's not something we can test here with a mock handler.
14367 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_CHALLENGE,
14368 auth_handler->state());
14369
[email protected]7ef4cbbb2011-02-06 11:19:1014370 // Read the body since the fourth round was successful. This will also
14371 // release the socket back to the pool.
Victor Costan9c7302b2018-08-27 16:39:4414372 scoped_refptr<IOBufferWithSize> io_buf =
14373 base::MakeRefCounted<IOBufferWithSize>(50);
bnc691fda62016-08-12 00:43:1614374 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1014375 if (rv == ERR_IO_PENDING)
14376 rv = callback.WaitForResult();
14377 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1614378 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1014379 EXPECT_EQ(0, rv);
14380 // There are still 0 idle sockets, since the trans_compete transaction
14381 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:2814382 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1014383
14384 // The competing request can now finish. Wait for the headers and then
14385 // read the body.
14386 rv = callback_compete.WaitForResult();
robpercival214763f2016-07-01 23:27:0114387 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1614388 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1014389 if (rv == ERR_IO_PENDING)
14390 rv = callback.WaitForResult();
14391 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1614392 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1014393 EXPECT_EQ(0, rv);
14394
14395 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:2814396 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1414397}
14398
[email protected]65041fa2010-05-21 06:56:5314399// This tests the case that a request is issued via http instead of spdy after
14400// npn is negotiated.
bncd16676a2016-07-20 16:23:0114401TEST_F(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]65041fa2010-05-21 06:56:5314402 HttpRequestInfo request;
14403 request.method = "GET";
bncce36dca22015-04-21 22:11:2314404 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1014405 request.traffic_annotation =
14406 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]65041fa2010-05-21 06:56:5314407
14408 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2314409 MockWrite(
14410 "GET / HTTP/1.1\r\n"
14411 "Host: www.example.org\r\n"
14412 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5314413 };
14414
14415 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5214416 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4314417 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5214418 MockRead("\r\n"),
14419 MockRead("hello world"),
14420 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5314421 };
14422
[email protected]8ddf8322012-02-23 18:08:0614423 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614424 ssl.next_proto = kProtoHTTP11;
[email protected]65041fa2010-05-21 06:56:5314425
[email protected]bb88e1d32013-05-03 23:11:0714426 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5314427
Ryan Sleevib8d7ea02018-05-07 20:01:0114428 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0714429 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5314430
[email protected]49639fa2011-12-20 23:22:4114431 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5314432
danakj1fd259a02016-04-16 03:17:0914433 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614434 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]65041fa2010-05-21 06:56:5314435
tfarina42834112016-09-22 13:38:2014436 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]65041fa2010-05-21 06:56:5314437
robpercival214763f2016-07-01 23:27:0114438 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14439 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]65041fa2010-05-21 06:56:5314440
bnc691fda62016-08-12 00:43:1614441 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214442 ASSERT_TRUE(response);
14443 ASSERT_TRUE(response->headers);
[email protected]65041fa2010-05-21 06:56:5314444 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
14445
14446 std::string response_data;
bnc691fda62016-08-12 00:43:1614447 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]65041fa2010-05-21 06:56:5314448 EXPECT_EQ("hello world", response_data);
14449
14450 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214451 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]65041fa2010-05-21 06:56:5314452}
[email protected]26ef6582010-06-24 02:30:4714453
bnc55ff9da2015-08-19 18:42:3514454// Simulate the SSL handshake completing with an NPN negotiation followed by an
14455// immediate server closing of the socket.
14456// Regression test for https://crbug.com/46369.
bncd16676a2016-07-20 16:23:0114457TEST_F(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:4714458 HttpRequestInfo request;
14459 request.method = "GET";
bncce36dca22015-04-21 22:11:2314460 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1014461 request.traffic_annotation =
14462 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]26ef6582010-06-24 02:30:4714463
[email protected]8ddf8322012-02-23 18:08:0614464 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614465 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0714466 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4714467
Ryan Hamilton0239aac2018-05-19 00:03:1314468 spdy::SpdySerializedFrame req(
14469 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4114470 MockWrite spdy_writes[] = {CreateMockWrite(req, 1)};
[email protected]26ef6582010-06-24 02:30:4714471
14472 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0614473 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4714474 };
14475
Ryan Sleevib8d7ea02018-05-07 20:01:0114476 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0714477 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4714478
[email protected]49639fa2011-12-20 23:22:4114479 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4714480
danakj1fd259a02016-04-16 03:17:0914481 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614482 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]26ef6582010-06-24 02:30:4714483
tfarina42834112016-09-22 13:38:2014484 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114485 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14486 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]26ef6582010-06-24 02:30:4714487}
[email protected]65d34382010-07-01 18:12:2614488
[email protected]795cbf82013-07-22 09:37:2714489// A subclass of HttpAuthHandlerMock that records the request URL when
14490// it gets it. This is needed since the auth handler may get destroyed
14491// before we get a chance to query it.
14492class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
14493 public:
14494 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
14495
Chris Watkins7a41d3552017-12-01 02:13:2714496 ~UrlRecordingHttpAuthHandlerMock() override = default;
[email protected]795cbf82013-07-22 09:37:2714497
14498 protected:
dchengb03027d2014-10-21 12:00:2014499 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
14500 const HttpRequestInfo* request,
Bence Béky7236fb72018-08-01 14:35:0914501 CompletionOnceCallback callback,
dchengb03027d2014-10-21 12:00:2014502 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2714503 *url_ = request->url;
14504 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
Bence Béky7236fb72018-08-01 14:35:0914505 credentials, request, std::move(callback), auth_token);
[email protected]795cbf82013-07-22 09:37:2714506 }
14507
14508 private:
14509 GURL* url_;
14510};
14511
[email protected]8e6441ca2010-08-19 05:56:3814512// Test that if we cancel the transaction as the connection is completing, that
14513// everything tears down correctly.
bncd16676a2016-07-20 16:23:0114514TEST_F(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3814515 // Setup everything about the connection to complete synchronously, so that
14516 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
14517 // for is the callback from the HttpStreamRequest.
14518 // Then cancel the transaction.
14519 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3614520 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3814521 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0614522 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
14523 MockRead(SYNCHRONOUS, "hello world"),
14524 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3814525 };
14526
[email protected]8e6441ca2010-08-19 05:56:3814527 HttpRequestInfo request;
14528 request.method = "GET";
bncce36dca22015-04-21 22:11:2314529 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1014530 request.traffic_annotation =
14531 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8e6441ca2010-08-19 05:56:3814532
danakj1fd259a02016-04-16 03:17:0914533 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5814534 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1914535 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2714536
Ryan Sleevib8d7ea02018-05-07 20:01:0114537 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]8e6441ca2010-08-19 05:56:3814538 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0714539 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3814540
[email protected]49639fa2011-12-20 23:22:4114541 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3814542
vishal.b62985ca92015-04-17 08:45:5114543 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4114544 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114545 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8e6441ca2010-08-19 05:56:3814546 trans.reset(); // Cancel the transaction here.
14547
fdoray92e35a72016-06-10 15:54:5514548 base::RunLoop().RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3014549}
14550
[email protected]ecab6e052014-05-16 14:58:1214551// Test that if a transaction is cancelled after receiving the headers, the
14552// stream is drained properly and added back to the socket pool. The main
14553// purpose of this test is to make sure that an HttpStreamParser can be read
14554// from after the HttpNetworkTransaction and the objects it owns have been
14555// deleted.
14556// See http://crbug.com/368418
bncd16676a2016-07-20 16:23:0114557TEST_F(HttpNetworkTransactionTest, CancelAfterHeaders) {
[email protected]ecab6e052014-05-16 14:58:1214558 MockRead data_reads[] = {
14559 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
14560 MockRead(ASYNC, "Content-Length: 2\r\n"),
14561 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
14562 MockRead(ASYNC, "1"),
14563 // 2 async reads are necessary to trigger a ReadResponseBody call after the
14564 // HttpNetworkTransaction has been deleted.
14565 MockRead(ASYNC, "2"),
14566 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
14567 };
Ryan Sleevib8d7ea02018-05-07 20:01:0114568 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]ecab6e052014-05-16 14:58:1214569 session_deps_.socket_factory->AddSocketDataProvider(&data);
14570
danakj1fd259a02016-04-16 03:17:0914571 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]ecab6e052014-05-16 14:58:1214572
14573 {
14574 HttpRequestInfo request;
14575 request.method = "GET";
bncce36dca22015-04-21 22:11:2314576 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1014577 request.traffic_annotation =
14578 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ecab6e052014-05-16 14:58:1214579
dcheng48459ac22014-08-26 00:46:4114580 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1214581 TestCompletionCallback callback;
14582
tfarina42834112016-09-22 13:38:2014583 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114584 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ecab6e052014-05-16 14:58:1214585 callback.WaitForResult();
14586
14587 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214588 ASSERT_TRUE(response);
14589 EXPECT_TRUE(response->headers);
[email protected]ecab6e052014-05-16 14:58:1214590 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
14591
14592 // The transaction and HttpRequestInfo are deleted.
14593 }
14594
14595 // Let the HttpResponseBodyDrainer drain the socket.
fdoray92e35a72016-06-10 15:54:5514596 base::RunLoop().RunUntilIdle();
[email protected]ecab6e052014-05-16 14:58:1214597
14598 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4114599 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1214600}
14601
[email protected]76a505b2010-08-25 06:23:0014602// Test a basic GET request through a proxy.
bncd16676a2016-07-20 16:23:0114603TEST_F(HttpNetworkTransactionTest, ProxyGet) {
Lily Houghton8c2f97d2018-01-22 05:06:5914604 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4914605 ProxyResolutionService::CreateFixedFromPacResult(
14606 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5114607 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714608 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0914609 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0014610
[email protected]76a505b2010-08-25 06:23:0014611 HttpRequestInfo request;
14612 request.method = "GET";
bncce36dca22015-04-21 22:11:2314613 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1014614 request.traffic_annotation =
14615 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0014616
14617 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2314618 MockWrite(
14619 "GET http://www.example.org/ HTTP/1.1\r\n"
14620 "Host: www.example.org\r\n"
14621 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014622 };
14623
14624 MockRead data_reads1[] = {
14625 MockRead("HTTP/1.1 200 OK\r\n"),
14626 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14627 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0614628 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0014629 };
14630
Ryan Sleevib8d7ea02018-05-07 20:01:0114631 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:0714632 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0014633
[email protected]49639fa2011-12-20 23:22:4114634 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0014635
bnc691fda62016-08-12 00:43:1614636 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0914637 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1614638 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0914639 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
14640 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5014641
bnc691fda62016-08-12 00:43:1614642 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114643 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0014644
14645 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0114646 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:0014647
bnc691fda62016-08-12 00:43:1614648 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214649 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0014650
14651 EXPECT_TRUE(response->headers->IsKeepAlive());
14652 EXPECT_EQ(200, response->headers->response_code());
14653 EXPECT_EQ(100, response->headers->GetContentLength());
14654 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4714655 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
14656 HostPortPair::FromString("myproxy:70")),
14657 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0914658 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
14659 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
14660 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0014661 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2014662
14663 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1614664 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2014665 TestLoadTimingNotReusedWithPac(load_timing_info,
14666 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0014667}
14668
14669// Test a basic HTTPS GET request through a proxy.
bncd16676a2016-07-20 16:23:0114670TEST_F(HttpNetworkTransactionTest, ProxyTunnelGet) {
Lily Houghton8c2f97d2018-01-22 05:06:5914671 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4914672 ProxyResolutionService::CreateFixedFromPacResult(
14673 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5114674 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714675 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0914676 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0014677
[email protected]76a505b2010-08-25 06:23:0014678 HttpRequestInfo request;
14679 request.method = "GET";
bncce36dca22015-04-21 22:11:2314680 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1014681 request.traffic_annotation =
14682 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0014683
14684 // Since we have proxy, should try to establish tunnel.
14685 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1714686 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
14687 "Host: www.example.org:443\r\n"
14688 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014689
rsleevidb16bb02015-11-12 23:47:1714690 MockWrite("GET / HTTP/1.1\r\n"
14691 "Host: www.example.org\r\n"
14692 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014693 };
14694
14695 MockRead data_reads1[] = {
14696 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
14697
14698 MockRead("HTTP/1.1 200 OK\r\n"),
14699 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14700 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0614701 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0014702 };
14703
Ryan Sleevib8d7ea02018-05-07 20:01:0114704 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:0714705 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0614706 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0714707 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0014708
[email protected]49639fa2011-12-20 23:22:4114709 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0014710
bnc691fda62016-08-12 00:43:1614711 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0914712 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1614713 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0914714 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
14715 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5014716
bnc691fda62016-08-12 00:43:1614717 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114718 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0014719
14720 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0114721 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:4614722 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4014723 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0014724 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014725 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
14726 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0014727 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4014728 entries, pos,
mikecirone8b85c432016-09-08 19:11:0014729 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
14730 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0014731
bnc691fda62016-08-12 00:43:1614732 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214733 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0014734
14735 EXPECT_TRUE(response->headers->IsKeepAlive());
14736 EXPECT_EQ(200, response->headers->response_code());
14737 EXPECT_EQ(100, response->headers->GetContentLength());
14738 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
14739 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4714740 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
14741 HostPortPair::FromString("myproxy:70")),
14742 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0914743 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
14744 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
14745 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]029c83b62013-01-24 05:28:2014746
14747 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1614748 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2014749 TestLoadTimingNotReusedWithPac(load_timing_info,
14750 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0014751}
14752
rsleevidb16bb02015-11-12 23:47:1714753// Test a basic HTTPS GET request through a proxy, connecting to an IPv6
14754// literal host.
bncd16676a2016-07-20 16:23:0114755TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetIPv6) {
Lily Houghton8c2f97d2018-01-22 05:06:5914756 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4914757 ProxyResolutionService::CreateFixedFromPacResult(
14758 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
rsleevidb16bb02015-11-12 23:47:1714759 BoundTestNetLog log;
14760 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0914761 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
rsleevidb16bb02015-11-12 23:47:1714762
14763 HttpRequestInfo request;
14764 request.method = "GET";
Eric Romanda790f92018-11-07 19:17:1514765 request.url = GURL("https://[::2]:443/");
Ramin Halavatib5e433e2018-02-07 07:41:1014766 request.traffic_annotation =
14767 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rsleevidb16bb02015-11-12 23:47:1714768
14769 // Since we have proxy, should try to establish tunnel.
14770 MockWrite data_writes1[] = {
Eric Romanda790f92018-11-07 19:17:1514771 MockWrite("CONNECT [::2]:443 HTTP/1.1\r\n"
14772 "Host: [::2]:443\r\n"
rsleevidb16bb02015-11-12 23:47:1714773 "Proxy-Connection: keep-alive\r\n\r\n"),
14774
14775 MockWrite("GET / HTTP/1.1\r\n"
Eric Romanda790f92018-11-07 19:17:1514776 "Host: [::2]\r\n"
rsleevidb16bb02015-11-12 23:47:1714777 "Connection: keep-alive\r\n\r\n"),
14778 };
14779
14780 MockRead data_reads1[] = {
14781 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
14782
14783 MockRead("HTTP/1.1 200 OK\r\n"),
14784 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14785 MockRead("Content-Length: 100\r\n\r\n"),
14786 MockRead(SYNCHRONOUS, OK),
14787 };
14788
Ryan Sleevib8d7ea02018-05-07 20:01:0114789 StaticSocketDataProvider data1(data_reads1, data_writes1);
rsleevidb16bb02015-11-12 23:47:1714790 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14791 SSLSocketDataProvider ssl(ASYNC, OK);
14792 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14793
14794 TestCompletionCallback callback1;
14795
bnc691fda62016-08-12 00:43:1614796 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
rsleevidb16bb02015-11-12 23:47:1714797
bnc691fda62016-08-12 00:43:1614798 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114799 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rsleevidb16bb02015-11-12 23:47:1714800
14801 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0114802 EXPECT_THAT(rv, IsOk());
rsleevidb16bb02015-11-12 23:47:1714803 TestNetLogEntry::List entries;
14804 log.GetEntries(&entries);
14805 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014806 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
14807 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1714808 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014809 entries, pos,
14810 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
14811 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1714812
bnc691fda62016-08-12 00:43:1614813 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214814 ASSERT_TRUE(response);
rsleevidb16bb02015-11-12 23:47:1714815
14816 EXPECT_TRUE(response->headers->IsKeepAlive());
14817 EXPECT_EQ(200, response->headers->response_code());
14818 EXPECT_EQ(100, response->headers->GetContentLength());
14819 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
14820 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4714821 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
14822 HostPortPair::FromString("myproxy:70")),
14823 response->proxy_server);
rsleevidb16bb02015-11-12 23:47:1714824
14825 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1614826 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
rsleevidb16bb02015-11-12 23:47:1714827 TestLoadTimingNotReusedWithPac(load_timing_info,
14828 CONNECT_TIMING_HAS_SSL_TIMES);
14829}
14830
[email protected]76a505b2010-08-25 06:23:0014831// Test a basic HTTPS GET request through a proxy, but the server hangs up
14832// while establishing the tunnel.
bncd16676a2016-07-20 16:23:0114833TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
Ramin Halavatica8d5252018-03-12 05:33:4914834 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
14835 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5114836 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714837 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0914838 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0014839
[email protected]76a505b2010-08-25 06:23:0014840 HttpRequestInfo request;
14841 request.method = "GET";
bncce36dca22015-04-21 22:11:2314842 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1014843 request.traffic_annotation =
14844 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0014845
14846 // Since we have proxy, should try to establish tunnel.
14847 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1714848 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
14849 "Host: www.example.org:443\r\n"
14850 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014851
rsleevidb16bb02015-11-12 23:47:1714852 MockWrite("GET / HTTP/1.1\r\n"
14853 "Host: www.example.org\r\n"
14854 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014855 };
14856
14857 MockRead data_reads1[] = {
[email protected]76a505b2010-08-25 06:23:0014858 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0614859 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0014860 };
14861
Ryan Sleevib8d7ea02018-05-07 20:01:0114862 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:0714863 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0614864 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0714865 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0014866
[email protected]49639fa2011-12-20 23:22:4114867 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0014868
bnc691fda62016-08-12 00:43:1614869 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5014870
bnc691fda62016-08-12 00:43:1614871 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114872 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0014873
14874 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0114875 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
mmenke43758e62015-05-04 21:09:4614876 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4014877 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0014878 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014879 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
14880 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0014881 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4014882 entries, pos,
mikecirone8b85c432016-09-08 19:11:0014883 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
14884 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0014885}
14886
[email protected]749eefa82010-09-13 22:14:0314887// Test for crbug.com/55424.
bncd16676a2016-07-20 16:23:0114888TEST_F(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
Ryan Hamilton0239aac2018-05-19 00:03:1314889 spdy::SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4914890 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4114891 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]749eefa82010-09-13 22:14:0314892
Ryan Hamilton0239aac2018-05-19 00:03:1314893 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
14894 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0314895 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114896 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0314897 };
14898
Ryan Sleevib8d7ea02018-05-07 20:01:0114899 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0714900 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0314901
[email protected]8ddf8322012-02-23 18:08:0614902 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614903 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0714904 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0314905
danakj1fd259a02016-04-16 03:17:0914906 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0314907
14908 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2314909 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4014910 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
Matt Menke2436b2f2018-12-11 18:07:1114911 PRIVACY_MODE_DISABLED,
14912 SpdySessionKey::IsProxySession::kFalse, SocketTag());
[email protected]795cbf82013-07-22 09:37:2714913 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:5214914 CreateSpdySession(session.get(), key, NetLogWithSource());
[email protected]749eefa82010-09-13 22:14:0314915
14916 HttpRequestInfo request;
14917 request.method = "GET";
bncce36dca22015-04-21 22:11:2314918 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1014919 request.traffic_annotation =
14920 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]749eefa82010-09-13 22:14:0314921
bnc691fda62016-08-12 00:43:1614922 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]749eefa82010-09-13 22:14:0314923
[email protected]41d64e82013-07-03 22:44:2614924 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014925 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114926 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14927 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]749eefa82010-09-13 22:14:0314928}
14929
[email protected]73b8dd222010-11-11 19:55:2414930// Given a net error, cause that error to be returned from the first Write()
bnc691fda62016-08-12 00:43:1614931// call and verify that the HttpNetworkTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0214932void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0714933 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2914934 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2714935 request_info.url = GURL("https://www.example.com/");
14936 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914937 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:1014938 request_info.traffic_annotation =
14939 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2714940
[email protected]8ddf8322012-02-23 18:08:0614941 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2914942 MockWrite data_writes[] = {
14943 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2414944 };
Ryan Sleevib8d7ea02018-05-07 20:01:0114945 StaticSocketDataProvider data(base::span<MockRead>(), data_writes);
[email protected]bb88e1d32013-05-03 23:11:0714946 session_deps_.socket_factory->AddSocketDataProvider(&data);
14947 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2414948
danakj1fd259a02016-04-16 03:17:0914949 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614950 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]73b8dd222010-11-11 19:55:2414951
[email protected]49639fa2011-12-20 23:22:4114952 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014953 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
ttuttle859dc7a2015-04-23 19:42:2914954 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2414955 rv = callback.WaitForResult();
14956 ASSERT_EQ(error, rv);
14957}
14958
bncd16676a2016-07-20 16:23:0114959TEST_F(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2414960 // Just check a grab bag of cert errors.
14961 static const int kErrors[] = {
14962 ERR_CERT_COMMON_NAME_INVALID,
14963 ERR_CERT_AUTHORITY_INVALID,
14964 ERR_CERT_DATE_INVALID,
14965 };
Avi Drissman4365a4782018-12-28 19:26:2414966 for (size_t i = 0; i < base::size(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0614967 CheckErrorIsPassedBack(kErrors[i], ASYNC);
14968 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2414969 }
14970}
14971
[email protected]bd0b6772011-01-11 19:59:3014972// Ensure that a client certificate is removed from the SSL client auth
14973// cache when:
14974// 1) No proxy is involved.
14975// 2) TLS False Start is disabled.
14976// 3) The initial TLS handshake requests a client certificate.
14977// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0114978TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_NoFalseStart) {
ttuttle859dc7a2015-04-23 19:42:2914979 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2714980 request_info.url = GURL("https://www.example.com/");
14981 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914982 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:1014983 request_info.traffic_annotation =
14984 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2714985
[email protected]bd0b6772011-01-11 19:59:3014986 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4114987 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3014988
14989 // [ssl_]data1 contains the data for the first SSL handshake. When a
14990 // CertificateRequest is received for the first time, the handshake will
14991 // be aborted to allow the caller to provide a certificate.
ttuttle859dc7a2015-04-23 19:42:2914992 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3014993 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714994 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
Ryan Sleevib8d7ea02018-05-07 20:01:0114995 StaticSocketDataProvider data1;
[email protected]bb88e1d32013-05-03 23:11:0714996 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3014997
14998 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
14999 // False Start is not being used, the result of the SSL handshake will be
15000 // returned as part of the SSLClientSocket::Connect() call. This test
15001 // matches the result of a server sending a handshake_failure alert,
15002 // rather than a Finished message, because it requires a client
15003 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2915004 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3015005 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715006 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
Ryan Sleevib8d7ea02018-05-07 20:01:0115007 StaticSocketDataProvider data2;
[email protected]bb88e1d32013-05-03 23:11:0715008 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3015009
15010 // [ssl_]data3 contains the data for the third SSL handshake. When a
15011 // connection to a server fails during an SSL handshake,
Steven Valdez0ef94d02018-11-19 23:28:1315012 // HttpNetworkTransaction will attempt to fallback to TLSv1.2 if the previous
15013 // connection was attempted with TLSv1.3. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3015014 // of the HttpNetworkTransaction. Because this test failure is due to
15015 // requiring a client certificate, this fallback handshake should also
15016 // fail.
ttuttle859dc7a2015-04-23 19:42:2915017 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
Steven Valdez0ef94d02018-11-19 23:28:1315018 ssl_data3.expected_ssl_version_max = SSL_PROTOCOL_VERSION_TLS1_2;
[email protected]bd0b6772011-01-11 19:59:3015019 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715020 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
Ryan Sleevib8d7ea02018-05-07 20:01:0115021 StaticSocketDataProvider data3;
[email protected]bb88e1d32013-05-03 23:11:0715022 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3015023
[email protected]80c75f682012-05-26 16:22:1715024 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
15025 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4215026 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
15027 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]80c75f682012-05-26 16:22:1715028 // of the HttpNetworkTransaction. Because this test failure is due to
15029 // requiring a client certificate, this fallback handshake should also
15030 // fail.
ttuttle859dc7a2015-04-23 19:42:2915031 SSLSocketDataProvider ssl_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1715032 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715033 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
Ryan Sleevib8d7ea02018-05-07 20:01:0115034 StaticSocketDataProvider data4;
[email protected]bb88e1d32013-05-03 23:11:0715035 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1715036
danakj1fd259a02016-04-16 03:17:0915037 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615038 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3015039
[email protected]bd0b6772011-01-11 19:59:3015040 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4115041 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2015042 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115043 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3015044
15045 // Complete the SSL handshake, which should abort due to requiring a
15046 // client certificate.
15047 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115048 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3015049
15050 // Indicate that no certificate should be supplied. From the perspective
15051 // of SSLClientCertCache, NULL is just as meaningful as a real
15052 // certificate, so this is the same as supply a
15053 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1615054 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0115055 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3015056
15057 // Ensure the certificate was added to the client auth cache before
15058 // allowing the connection to continue restarting.
15059 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5415060 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4115061 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415062 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5215063 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3015064
15065 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1715066 // then consume ssl_data3 and ssl_data4, both of which should also fail.
15067 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3015068 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115069 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3015070
15071 // Ensure that the client certificate is removed from the cache on a
15072 // handshake failure.
[email protected]791879c2013-12-17 07:22:4115073 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415074 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3015075}
15076
15077// Ensure that a client certificate is removed from the SSL client auth
15078// cache when:
15079// 1) No proxy is involved.
15080// 2) TLS False Start is enabled.
15081// 3) The initial TLS handshake requests a client certificate.
15082// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0115083TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2915084 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2715085 request_info.url = GURL("https://www.example.com/");
15086 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2915087 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:1015088 request_info.traffic_annotation =
15089 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2715090
[email protected]bd0b6772011-01-11 19:59:3015091 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4115092 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3015093
15094 // When TLS False Start is used, SSLClientSocket::Connect() calls will
15095 // return successfully after reading up to the peer's Certificate message.
15096 // This is to allow the caller to call SSLClientSocket::Write(), which can
15097 // enqueue application data to be sent in the same packet as the
15098 // ChangeCipherSpec and Finished messages.
15099 // The actual handshake will be finished when SSLClientSocket::Read() is
15100 // called, which expects to process the peer's ChangeCipherSpec and
15101 // Finished messages. If there was an error negotiating with the peer,
15102 // such as due to the peer requiring a client certificate when none was
15103 // supplied, the alert sent by the peer won't be processed until Read() is
15104 // called.
15105
15106 // Like the non-False Start case, when a client certificate is requested by
15107 // the peer, the handshake is aborted during the Connect() call.
15108 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2915109 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3015110 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715111 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
Ryan Sleevib8d7ea02018-05-07 20:01:0115112 StaticSocketDataProvider data1;
[email protected]bb88e1d32013-05-03 23:11:0715113 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3015114
15115 // When a client certificate is supplied, Connect() will not be aborted
15116 // when the peer requests the certificate. Instead, the handshake will
15117 // artificially succeed, allowing the caller to write the HTTP request to
15118 // the socket. The handshake messages are not processed until Read() is
15119 // called, which then detects that the handshake was aborted, due to the
15120 // peer sending a handshake_failure because it requires a client
15121 // certificate.
ttuttle859dc7a2015-04-23 19:42:2915122 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3015123 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715124 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2915125 MockRead data2_reads[] = {
15126 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3015127 };
Ryan Sleevib8d7ea02018-05-07 20:01:0115128 StaticSocketDataProvider data2(data2_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0715129 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3015130
15131 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1715132 // the data for the SSL handshake once the TLSv1.1 connection falls back to
15133 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2915134 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3015135 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715136 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
Ryan Sleevib8d7ea02018-05-07 20:01:0115137 StaticSocketDataProvider data3(data2_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0715138 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3015139
[email protected]80c75f682012-05-26 16:22:1715140 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
15141 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2915142 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1715143 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715144 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
Ryan Sleevib8d7ea02018-05-07 20:01:0115145 StaticSocketDataProvider data4(data2_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0715146 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1715147
[email protected]7799de12013-05-30 05:52:5115148 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2915149 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5115150 ssl_data5.cert_request_info = cert_request.get();
15151 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
Ryan Sleevib8d7ea02018-05-07 20:01:0115152 StaticSocketDataProvider data5(data2_reads, base::span<MockWrite>());
[email protected]7799de12013-05-30 05:52:5115153 session_deps_.socket_factory->AddSocketDataProvider(&data5);
15154
danakj1fd259a02016-04-16 03:17:0915155 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615156 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3015157
[email protected]bd0b6772011-01-11 19:59:3015158 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4115159 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2015160 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115161 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3015162
15163 // Complete the SSL handshake, which should abort due to requiring a
15164 // client certificate.
15165 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115166 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3015167
15168 // Indicate that no certificate should be supplied. From the perspective
15169 // of SSLClientCertCache, NULL is just as meaningful as a real
15170 // certificate, so this is the same as supply a
15171 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1615172 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0115173 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3015174
15175 // Ensure the certificate was added to the client auth cache before
15176 // allowing the connection to continue restarting.
15177 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5415178 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4115179 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415180 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5215181 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3015182
[email protected]bd0b6772011-01-11 19:59:3015183 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1715184 // then consume ssl_data3 and ssl_data4, both of which should also fail.
15185 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3015186 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115187 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3015188
15189 // Ensure that the client certificate is removed from the cache on a
15190 // handshake failure.
[email protected]791879c2013-12-17 07:22:4115191 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415192 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3015193}
15194
[email protected]8c405132011-01-11 22:03:1815195// Ensure that a client certificate is removed from the SSL client auth
15196// cache when:
15197// 1) An HTTPS proxy is involved.
15198// 3) The HTTPS proxy requests a client certificate.
15199// 4) The client supplies an invalid/unacceptable certificate for the
15200// proxy.
15201// The test is repeated twice, first for connecting to an HTTPS endpoint,
15202// then for connecting to an HTTP endpoint.
bncd16676a2016-07-20 16:23:0115203TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
Ramin Halavatica8d5252018-03-12 05:33:4915204 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
15205 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5115206 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0715207 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1815208
15209 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4115210 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1815211
15212 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
15213 // [ssl_]data[1-3]. Rather than represending the endpoint
15214 // (www.example.com:443), they represent failures with the HTTPS proxy
15215 // (proxy:70).
ttuttle859dc7a2015-04-23 19:42:2915216 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1815217 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715218 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
Ryan Sleevib8d7ea02018-05-07 20:01:0115219 StaticSocketDataProvider data1;
[email protected]bb88e1d32013-05-03 23:11:0715220 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1815221
ttuttle859dc7a2015-04-23 19:42:2915222 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1815223 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715224 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
Ryan Sleevib8d7ea02018-05-07 20:01:0115225 StaticSocketDataProvider data2;
[email protected]bb88e1d32013-05-03 23:11:0715226 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1815227
[email protected]80c75f682012-05-26 16:22:1715228 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
15229#if 0
ttuttle859dc7a2015-04-23 19:42:2915230 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1815231 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715232 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
Ryan Sleevib8d7ea02018-05-07 20:01:0115233 StaticSocketDataProvider data3;
[email protected]bb88e1d32013-05-03 23:11:0715234 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1715235#endif
[email protected]8c405132011-01-11 22:03:1815236
ttuttle859dc7a2015-04-23 19:42:2915237 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1815238 requests[0].url = GURL("https://www.example.com/");
15239 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2915240 requests[0].load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:1015241 requests[0].traffic_annotation =
15242 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c405132011-01-11 22:03:1815243
15244 requests[1].url = GURL("http://www.example.com/");
15245 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2915246 requests[1].load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:1015247 requests[1].traffic_annotation =
15248 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c405132011-01-11 22:03:1815249
Avi Drissman4365a4782018-12-28 19:26:2415250 for (size_t i = 0; i < base::size(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0715251 session_deps_.socket_factory->ResetNextMockIndexes();
danakj1fd259a02016-04-16 03:17:0915252 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615253 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]8c405132011-01-11 22:03:1815254
15255 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4115256 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2015257 int rv = trans.Start(&requests[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115258 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1815259
15260 // Complete the SSL handshake, which should abort due to requiring a
15261 // client certificate.
15262 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115263 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]8c405132011-01-11 22:03:1815264
15265 // Indicate that no certificate should be supplied. From the perspective
15266 // of SSLClientCertCache, NULL is just as meaningful as a real
15267 // certificate, so this is the same as supply a
15268 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1615269 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0115270 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1815271
15272 // Ensure the certificate was added to the client auth cache before
15273 // allowing the connection to continue restarting.
15274 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5415275 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4115276 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415277 HostPortPair("proxy", 70), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5215278 ASSERT_FALSE(client_cert);
[email protected]8c405132011-01-11 22:03:1815279 // Ensure the certificate was NOT cached for the endpoint. This only
15280 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4115281 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415282 HostPortPair("www.example.com", 443), &client_cert,
15283 &client_private_key));
[email protected]8c405132011-01-11 22:03:1815284
15285 // Restart the handshake. This will consume ssl_data2, which fails, and
15286 // then consume ssl_data3, which should also fail. The result code is
15287 // checked against what ssl_data3 should return.
15288 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115289 ASSERT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]8c405132011-01-11 22:03:1815290
15291 // Now that the new handshake has failed, ensure that the client
15292 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4115293 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415294 HostPortPair("proxy", 70), &client_cert, &client_private_key));
[email protected]791879c2013-12-17 07:22:4115295 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415296 HostPortPair("www.example.com", 443), &client_cert,
15297 &client_private_key));
[email protected]8c405132011-01-11 22:03:1815298 }
15299}
15300
bncd16676a2016-07-20 16:23:0115301TEST_F(HttpNetworkTransactionTest, UseIPConnectionPooling) {
[email protected]e3ceb682011-06-28 23:55:4615302 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1915303 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0915304 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4615305
bnc032658ba2016-09-26 18:17:1515306 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4615307
Ryan Hamilton0239aac2018-05-19 00:03:1315308 spdy::SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4915309 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3815310 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1315311 spdy::SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3715312 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4615313 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115314 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4615315 };
Ryan Hamilton0239aac2018-05-19 00:03:1315316 spdy::SpdySerializedFrame host1_resp(
15317 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
15318 spdy::SpdySerializedFrame host1_resp_body(
bncdf80d44fd2016-07-15 20:27:4115319 spdy_util_.ConstructSpdyDataFrame(1, true));
Ryan Hamilton0239aac2018-05-19 00:03:1315320 spdy::SpdySerializedFrame host2_resp(
15321 spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
15322 spdy::SpdySerializedFrame host2_resp_body(
bncdf80d44fd2016-07-15 20:27:4115323 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4615324 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115325 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
15326 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1315327 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4615328 };
15329
eroman36d84e54432016-03-17 03:23:0215330 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0215331 MockConnect connect(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115332 SequencedSocketData spdy_data(connect, spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0715333 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4615334
[email protected]aa22b242011-11-16 18:58:2915335 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4615336 HttpRequestInfo request1;
15337 request1.method = "GET";
bncce36dca22015-04-21 22:11:2315338 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4615339 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015340 request1.traffic_annotation =
15341 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015342 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4615343
tfarina42834112016-09-22 13:38:2015344 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115345 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15346 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615347
15348 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5215349 ASSERT_TRUE(response);
15350 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215351 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4615352
15353 std::string response_data;
robpercival214763f2016-07-01 23:27:0115354 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615355 EXPECT_EQ("hello!", response_data);
15356
bnca4d611d2016-09-22 19:55:3715357 // Preload mail.example.com into HostCache.
15358 HostPortPair host_port("mail.example.com", 443);
[email protected]5109c1952013-08-20 18:44:1015359 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4615360 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1015361 std::unique_ptr<HostResolver::Request> request;
15362 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
15363 &ignored, callback.callback(),
tfarina42834112016-09-22 13:38:2015364 &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115365 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4715366 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115367 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4615368
15369 HttpRequestInfo request2;
15370 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3715371 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4615372 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015373 request2.traffic_annotation =
15374 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015375 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4615376
tfarina42834112016-09-22 13:38:2015377 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115378 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15379 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615380
15381 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215382 ASSERT_TRUE(response);
15383 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215384 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4615385 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215386 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115387 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615388 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4615389}
15390
bncd16676a2016-07-20 16:23:0115391TEST_F(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d2b5f092012-06-08 23:55:0215392 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1915393 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0915394 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0215395
bnc032658ba2016-09-26 18:17:1515396 AddSSLSocketData();
[email protected]d2b5f092012-06-08 23:55:0215397
Ryan Hamilton0239aac2018-05-19 00:03:1315398 spdy::SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4915399 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3815400 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1315401 spdy::SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3715402 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0215403 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115404 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0215405 };
Ryan Hamilton0239aac2018-05-19 00:03:1315406 spdy::SpdySerializedFrame host1_resp(
15407 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
15408 spdy::SpdySerializedFrame host1_resp_body(
bncdf80d44fd2016-07-15 20:27:4115409 spdy_util_.ConstructSpdyDataFrame(1, true));
Ryan Hamilton0239aac2018-05-19 00:03:1315410 spdy::SpdySerializedFrame host2_resp(
15411 spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
15412 spdy::SpdySerializedFrame host2_resp_body(
bncdf80d44fd2016-07-15 20:27:4115413 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0215414 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115415 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
15416 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1315417 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0215418 };
15419
eroman36d84e54432016-03-17 03:23:0215420 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0215421 MockConnect connect(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115422 SequencedSocketData spdy_data(connect, spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0715423 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0215424
15425 TestCompletionCallback callback;
15426 HttpRequestInfo request1;
15427 request1.method = "GET";
bncce36dca22015-04-21 22:11:2315428 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0215429 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015430 request1.traffic_annotation =
15431 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015432 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0215433
tfarina42834112016-09-22 13:38:2015434 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115435 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15436 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0215437
15438 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5215439 ASSERT_TRUE(response);
15440 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215441 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0215442
15443 std::string response_data;
robpercival214763f2016-07-01 23:27:0115444 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0215445 EXPECT_EQ("hello!", response_data);
15446
15447 HttpRequestInfo request2;
15448 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3715449 request2.url = GURL("https://mail.example.com/");
[email protected]d2b5f092012-06-08 23:55:0215450 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015451 request2.traffic_annotation =
15452 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015453 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0215454
tfarina42834112016-09-22 13:38:2015455 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115456 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15457 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0215458
15459 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215460 ASSERT_TRUE(response);
15461 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215462 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0215463 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215464 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115465 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0215466 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0215467}
15468
bnc8016c1f2017-03-31 02:11:2915469// Regression test for https://crbug.com/546991.
15470// The server might not be able to serve an IP pooled request, and might send a
15471// 421 Misdirected Request response status to indicate this.
15472// HttpNetworkTransaction should reset the request and retry without IP pooling.
15473TEST_F(HttpNetworkTransactionTest, RetryWithoutConnectionPooling) {
15474 // Two hosts resolve to the same IP address.
15475 const std::string ip_addr = "1.2.3.4";
15476 IPAddress ip;
15477 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
15478 IPEndPoint peer_addr = IPEndPoint(ip, 443);
15479
Jeremy Roman0579ed62017-08-29 15:56:1915480 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
bnc8016c1f2017-03-31 02:11:2915481 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
15482 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
15483
15484 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15485
15486 // Two requests on the first connection.
Ryan Hamilton0239aac2018-05-19 00:03:1315487 spdy::SpdySerializedFrame req1(
bnc8016c1f2017-03-31 02:11:2915488 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
15489 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1315490 spdy::SpdySerializedFrame req2(
bnc8016c1f2017-03-31 02:11:2915491 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1315492 spdy::SpdySerializedFrame rst(
15493 spdy_util_.ConstructSpdyRstStream(3, spdy::ERROR_CODE_CANCEL));
bnc8016c1f2017-03-31 02:11:2915494 MockWrite writes1[] = {
15495 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
15496 CreateMockWrite(rst, 6),
15497 };
15498
15499 // The first one succeeds, the second gets error 421 Misdirected Request.
Ryan Hamilton0239aac2018-05-19 00:03:1315500 spdy::SpdySerializedFrame resp1(
15501 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
15502 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
15503 spdy::SpdyHeaderBlock response_headers;
15504 response_headers[spdy::kHttp2StatusHeader] = "421";
15505 spdy::SpdySerializedFrame resp2(
bnc8016c1f2017-03-31 02:11:2915506 spdy_util_.ConstructSpdyReply(3, std::move(response_headers)));
15507 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
15508 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
15509
15510 MockConnect connect1(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115511 SequencedSocketData data1(connect1, reads1, writes1);
bnc8016c1f2017-03-31 02:11:2915512 session_deps_.socket_factory->AddSocketDataProvider(&data1);
15513
15514 AddSSLSocketData();
15515
15516 // Retry the second request on a second connection.
15517 SpdyTestUtil spdy_util2;
Ryan Hamilton0239aac2018-05-19 00:03:1315518 spdy::SpdySerializedFrame req3(
bnc8016c1f2017-03-31 02:11:2915519 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
15520 MockWrite writes2[] = {
15521 CreateMockWrite(req3, 0),
15522 };
15523
Ryan Hamilton0239aac2018-05-19 00:03:1315524 spdy::SpdySerializedFrame resp3(
15525 spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
15526 spdy::SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
bnc8016c1f2017-03-31 02:11:2915527 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
15528 MockRead(ASYNC, 0, 3)};
15529
15530 MockConnect connect2(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115531 SequencedSocketData data2(connect2, reads2, writes2);
bnc8016c1f2017-03-31 02:11:2915532 session_deps_.socket_factory->AddSocketDataProvider(&data2);
15533
15534 AddSSLSocketData();
15535
15536 // Preload mail.example.org into HostCache.
15537 HostPortPair host_port("mail.example.org", 443);
15538 HostResolver::RequestInfo resolve_info(host_port);
15539 AddressList ignored;
15540 std::unique_ptr<HostResolver::Request> request;
15541 TestCompletionCallback callback;
15542 int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
15543 &ignored, callback.callback(),
15544 &request, NetLogWithSource());
15545 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15546 rv = callback.WaitForResult();
15547 EXPECT_THAT(rv, IsOk());
15548
15549 HttpRequestInfo request1;
15550 request1.method = "GET";
15551 request1.url = GURL("https://www.example.org/");
15552 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015553 request1.traffic_annotation =
15554 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8016c1f2017-03-31 02:11:2915555 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
15556
15557 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
15558 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15559 rv = callback.WaitForResult();
15560 EXPECT_THAT(rv, IsOk());
15561
15562 const HttpResponseInfo* response = trans1.GetResponseInfo();
15563 ASSERT_TRUE(response);
15564 ASSERT_TRUE(response->headers);
15565 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
15566 EXPECT_TRUE(response->was_fetched_via_spdy);
15567 EXPECT_TRUE(response->was_alpn_negotiated);
15568 std::string response_data;
15569 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
15570 EXPECT_EQ("hello!", response_data);
15571
15572 HttpRequestInfo request2;
15573 request2.method = "GET";
15574 request2.url = GURL("https://mail.example.org/");
15575 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015576 request2.traffic_annotation =
15577 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8016c1f2017-03-31 02:11:2915578 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
15579
15580 BoundTestNetLog log;
15581 rv = trans2.Start(&request2, callback.callback(), log.bound());
15582 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15583 rv = callback.WaitForResult();
15584 EXPECT_THAT(rv, IsOk());
15585
15586 response = trans2.GetResponseInfo();
15587 ASSERT_TRUE(response);
15588 ASSERT_TRUE(response->headers);
15589 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
15590 EXPECT_TRUE(response->was_fetched_via_spdy);
15591 EXPECT_TRUE(response->was_alpn_negotiated);
15592 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
15593 EXPECT_EQ("hello!", response_data);
15594
15595 TestNetLogEntry::List entries;
15596 log.GetEntries(&entries);
davidbence688ae2017-05-04 15:12:5915597 ExpectLogContainsSomewhere(
15598 entries, 0, NetLogEventType::HTTP_TRANSACTION_RESTART_MISDIRECTED_REQUEST,
bnc8016c1f2017-03-31 02:11:2915599 NetLogEventPhase::NONE);
davidbence688ae2017-05-04 15:12:5915600}
15601
15602// Test that HTTP 421 responses are properly returned to the caller if received
15603// on the retry as well. HttpNetworkTransaction should not infinite loop or lose
15604// portions of the response.
15605TEST_F(HttpNetworkTransactionTest, ReturnHTTP421OnRetry) {
15606 // Two hosts resolve to the same IP address.
15607 const std::string ip_addr = "1.2.3.4";
15608 IPAddress ip;
15609 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
15610 IPEndPoint peer_addr = IPEndPoint(ip, 443);
15611
Jeremy Roman0579ed62017-08-29 15:56:1915612 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
davidbence688ae2017-05-04 15:12:5915613 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
15614 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
15615
15616 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15617
15618 // Two requests on the first connection.
Ryan Hamilton0239aac2018-05-19 00:03:1315619 spdy::SpdySerializedFrame req1(
davidbence688ae2017-05-04 15:12:5915620 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
15621 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1315622 spdy::SpdySerializedFrame req2(
davidbence688ae2017-05-04 15:12:5915623 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1315624 spdy::SpdySerializedFrame rst(
15625 spdy_util_.ConstructSpdyRstStream(3, spdy::ERROR_CODE_CANCEL));
davidbence688ae2017-05-04 15:12:5915626 MockWrite writes1[] = {
15627 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
15628 CreateMockWrite(rst, 6),
15629 };
15630
15631 // The first one succeeds, the second gets error 421 Misdirected Request.
Ryan Hamilton0239aac2018-05-19 00:03:1315632 spdy::SpdySerializedFrame resp1(
15633 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
15634 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
15635 spdy::SpdyHeaderBlock response_headers;
15636 response_headers[spdy::kHttp2StatusHeader] = "421";
15637 spdy::SpdySerializedFrame resp2(
davidbence688ae2017-05-04 15:12:5915638 spdy_util_.ConstructSpdyReply(3, response_headers.Clone()));
15639 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
15640 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
15641
15642 MockConnect connect1(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115643 SequencedSocketData data1(connect1, reads1, writes1);
davidbence688ae2017-05-04 15:12:5915644 session_deps_.socket_factory->AddSocketDataProvider(&data1);
15645
15646 AddSSLSocketData();
15647
15648 // Retry the second request on a second connection. It returns 421 Misdirected
15649 // Retry again.
15650 SpdyTestUtil spdy_util2;
Ryan Hamilton0239aac2018-05-19 00:03:1315651 spdy::SpdySerializedFrame req3(
davidbence688ae2017-05-04 15:12:5915652 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
15653 MockWrite writes2[] = {
15654 CreateMockWrite(req3, 0),
15655 };
15656
Ryan Hamilton0239aac2018-05-19 00:03:1315657 spdy::SpdySerializedFrame resp3(
davidbence688ae2017-05-04 15:12:5915658 spdy_util2.ConstructSpdyReply(1, std::move(response_headers)));
Ryan Hamilton0239aac2018-05-19 00:03:1315659 spdy::SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
davidbence688ae2017-05-04 15:12:5915660 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
15661 MockRead(ASYNC, 0, 3)};
15662
15663 MockConnect connect2(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115664 SequencedSocketData data2(connect2, reads2, writes2);
davidbence688ae2017-05-04 15:12:5915665 session_deps_.socket_factory->AddSocketDataProvider(&data2);
15666
15667 AddSSLSocketData();
15668
15669 // Preload mail.example.org into HostCache.
15670 HostPortPair host_port("mail.example.org", 443);
15671 HostResolver::RequestInfo resolve_info(host_port);
15672 AddressList ignored;
15673 std::unique_ptr<HostResolver::Request> request;
15674 TestCompletionCallback callback;
15675 int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
15676 &ignored, callback.callback(),
15677 &request, NetLogWithSource());
15678 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15679 rv = callback.WaitForResult();
15680 EXPECT_THAT(rv, IsOk());
15681
15682 HttpRequestInfo request1;
15683 request1.method = "GET";
15684 request1.url = GURL("https://www.example.org/");
15685 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015686 request1.traffic_annotation =
15687 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
davidbence688ae2017-05-04 15:12:5915688 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
15689
15690 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
15691 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15692 rv = callback.WaitForResult();
15693 EXPECT_THAT(rv, IsOk());
15694
15695 const HttpResponseInfo* response = trans1.GetResponseInfo();
15696 ASSERT_TRUE(response);
15697 ASSERT_TRUE(response->headers);
15698 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
15699 EXPECT_TRUE(response->was_fetched_via_spdy);
15700 EXPECT_TRUE(response->was_alpn_negotiated);
15701 std::string response_data;
15702 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
15703 EXPECT_EQ("hello!", response_data);
15704
15705 HttpRequestInfo request2;
15706 request2.method = "GET";
15707 request2.url = GURL("https://mail.example.org/");
15708 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015709 request2.traffic_annotation =
15710 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
davidbence688ae2017-05-04 15:12:5915711 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
15712
15713 BoundTestNetLog log;
15714 rv = trans2.Start(&request2, callback.callback(), log.bound());
15715 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15716 rv = callback.WaitForResult();
15717 EXPECT_THAT(rv, IsOk());
15718
15719 // After a retry, the 421 Misdirected Request is reported back up to the
15720 // caller.
15721 response = trans2.GetResponseInfo();
15722 ASSERT_TRUE(response);
15723 ASSERT_TRUE(response->headers);
15724 EXPECT_EQ("HTTP/1.1 421", response->headers->GetStatusLine());
15725 EXPECT_TRUE(response->was_fetched_via_spdy);
15726 EXPECT_TRUE(response->was_alpn_negotiated);
15727 EXPECT_TRUE(response->ssl_info.cert);
15728 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
15729 EXPECT_EQ("hello!", response_data);
bnc8016c1f2017-03-31 02:11:2915730}
15731
bnc6dcd8192017-05-25 20:11:5015732class OneTimeCachingHostResolver : public MockHostResolverBase {
[email protected]e3ceb682011-06-28 23:55:4615733 public:
15734 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
bnc6dcd8192017-05-25 20:11:5015735 : MockHostResolverBase(/* use_caching = */ true), host_port_(host_port) {}
Chris Watkins7a41d3552017-12-01 02:13:2715736 ~OneTimeCachingHostResolver() override = default;
[email protected]e3ceb682011-06-28 23:55:4615737
dchengb03027d2014-10-21 12:00:2015738 int ResolveFromCache(const RequestInfo& info,
15739 AddressList* addresses,
tfarina42834112016-09-22 13:38:2015740 const NetLogWithSource& net_log) override {
bnc6dcd8192017-05-25 20:11:5015741 int rv = MockHostResolverBase::ResolveFromCache(info, addresses, net_log);
[email protected]95a214c2011-08-04 21:50:4015742 if (rv == OK && info.host_port_pair().Equals(host_port_))
bnc6dcd8192017-05-25 20:11:5015743 GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4615744 return rv;
15745 }
15746
[email protected]e3ceb682011-06-28 23:55:4615747 private:
[email protected]e3ceb682011-06-28 23:55:4615748 const HostPortPair host_port_;
15749};
15750
bncd16676a2016-07-20 16:23:0115751TEST_F(HttpNetworkTransactionTest,
mmenke5c642132015-06-02 16:05:1315752 UseIPConnectionPoolingWithHostCacheExpiration) {
[email protected]e3ceb682011-06-28 23:55:4615753 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1915754 session_deps_.host_resolver = std::make_unique<OneTimeCachingHostResolver>(
bnca4d611d2016-09-22 19:55:3715755 HostPortPair("mail.example.com", 443));
danakj1fd259a02016-04-16 03:17:0915756 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4615757
bnc032658ba2016-09-26 18:17:1515758 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4615759
Ryan Hamilton0239aac2018-05-19 00:03:1315760 spdy::SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4915761 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3815762 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1315763 spdy::SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3715764 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4615765 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115766 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4615767 };
Ryan Hamilton0239aac2018-05-19 00:03:1315768 spdy::SpdySerializedFrame host1_resp(
15769 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
15770 spdy::SpdySerializedFrame host1_resp_body(
bncdf80d44fd2016-07-15 20:27:4115771 spdy_util_.ConstructSpdyDataFrame(1, true));
Ryan Hamilton0239aac2018-05-19 00:03:1315772 spdy::SpdySerializedFrame host2_resp(
15773 spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
15774 spdy::SpdySerializedFrame host2_resp_body(
bncdf80d44fd2016-07-15 20:27:4115775 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4615776 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115777 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
15778 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1315779 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4615780 };
15781
eroman36d84e54432016-03-17 03:23:0215782 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0215783 MockConnect connect(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115784 SequencedSocketData spdy_data(connect, spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0715785 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4615786
[email protected]aa22b242011-11-16 18:58:2915787 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4615788 HttpRequestInfo request1;
15789 request1.method = "GET";
bncce36dca22015-04-21 22:11:2315790 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4615791 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015792 request1.traffic_annotation =
15793 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015794 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4615795
tfarina42834112016-09-22 13:38:2015796 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115797 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15798 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615799
15800 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5215801 ASSERT_TRUE(response);
15802 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215803 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4615804
15805 std::string response_data;
robpercival214763f2016-07-01 23:27:0115806 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615807 EXPECT_EQ("hello!", response_data);
15808
15809 // Preload cache entries into HostCache.
bnca4d611d2016-09-22 19:55:3715810 HostResolver::RequestInfo resolve_info(HostPortPair("mail.example.com", 443));
[email protected]e3ceb682011-06-28 23:55:4615811 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1015812 std::unique_ptr<HostResolver::Request> request;
bnc6dcd8192017-05-25 20:11:5015813 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
15814 &ignored, callback.callback(),
15815 &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115816 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4715817 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115818 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4615819
15820 HttpRequestInfo request2;
15821 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3715822 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4615823 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015824 request2.traffic_annotation =
15825 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015826 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4615827
tfarina42834112016-09-22 13:38:2015828 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115829 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15830 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615831
15832 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215833 ASSERT_TRUE(response);
15834 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215835 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4615836 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215837 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115838 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615839 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4615840}
15841
bncd16676a2016-07-20 16:23:0115842TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2315843 const std::string https_url = "https://www.example.org:8080/";
15844 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0415845
15846 // SPDY GET for HTTPS URL
Ryan Hamilton0239aac2018-05-19 00:03:1315847 spdy::SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4915848 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0415849
15850 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4115851 CreateMockWrite(req1, 0),
[email protected]8450d722012-07-02 19:14:0415852 };
15853
Ryan Hamilton0239aac2018-05-19 00:03:1315854 spdy::SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
15855 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
bncdf80d44fd2016-07-15 20:27:4115856 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
mmenkee24011922015-12-17 22:12:5915857 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)};
[email protected]8450d722012-07-02 19:14:0415858
Ryan Sleevib8d7ea02018-05-07 20:01:0115859 SequencedSocketData data1(reads1, writes1);
[email protected]8450d722012-07-02 19:14:0415860 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5715861 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0415862
15863 // HTTP GET for the HTTP URL
15864 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1315865 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3415866 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2315867 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3415868 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0415869 };
15870
15871 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1315872 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
15873 MockRead(ASYNC, 2, "hello"),
15874 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0415875 };
15876
Ryan Sleevib8d7ea02018-05-07 20:01:0115877 SequencedSocketData data2(reads2, writes2);
[email protected]8450d722012-07-02 19:14:0415878
[email protected]8450d722012-07-02 19:14:0415879 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615880 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0715881 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15882 session_deps_.socket_factory->AddSocketDataProvider(&data1);
15883 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0415884
danakj1fd259a02016-04-16 03:17:0915885 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0415886
15887 // Start the first transaction to set up the SpdySession
15888 HttpRequestInfo request1;
15889 request1.method = "GET";
15890 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0415891 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015892 request1.traffic_annotation =
15893 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015894 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0415895 TestCompletionCallback callback1;
15896 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015897 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5515898 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0415899
robpercival214763f2016-07-01 23:27:0115900 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0415901 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
15902
15903 // Now, start the HTTP request
15904 HttpRequestInfo request2;
15905 request2.method = "GET";
15906 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0415907 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015908 request2.traffic_annotation =
15909 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015910 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0415911 TestCompletionCallback callback2;
15912 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015913 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5515914 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0415915
robpercival214763f2016-07-01 23:27:0115916 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0415917 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
15918}
15919
bnc5452e2a2015-05-08 16:27:4215920// Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
15921// with the alternative server. That connection should not be used.
bncd16676a2016-07-20 16:23:0115922TEST_F(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
bnc8bef8da22016-05-30 01:28:2515923 url::SchemeHostPort server("https", "www.example.org", 443);
15924 HostPortPair alternative("www.example.org", 444);
bnc5452e2a2015-05-08 16:27:4215925
bnc8bef8da22016-05-30 01:28:2515926 // Negotiate HTTP/1.1 with alternative.
bnc5452e2a2015-05-08 16:27:4215927 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615928 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4215929 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15930
15931 // No data should be read from the alternative, because HTTP/1.1 is
15932 // negotiated.
15933 StaticSocketDataProvider data;
15934 session_deps_.socket_factory->AddSocketDataProvider(&data);
15935
15936 // This test documents that an alternate Job should not be used if HTTP/1.1 is
zhongyi3d4a55e72016-04-22 20:36:4615937 // negotiated. In order to test this, a failed connection to the server is
bnc5452e2a2015-05-08 16:27:4215938 // mocked. This way the request relies on the alternate Job.
15939 StaticSocketDataProvider data_refused;
15940 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
15941 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
15942
zhongyi3d4a55e72016-04-22 20:36:4615943 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0915944 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4015945 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4215946 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2115947 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1215948 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2115949 http_server_properties->SetHttp2AlternativeService(
15950 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4215951
bnc5452e2a2015-05-08 16:27:4215952 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4615953 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4215954 request.method = "GET";
bnc8bef8da22016-05-30 01:28:2515955 request.url = GURL("https://www.example.org:443");
Ramin Halavatib5e433e2018-02-07 07:41:1015956 request.traffic_annotation =
15957 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4215958 TestCompletionCallback callback;
15959
15960 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
bnc94c92842016-09-21 15:22:5215961 // negotiated, the alternate Job should fail with ERR_ALPN_NEGOTIATION_FAILED.
tfarina42834112016-09-22 13:38:2015962 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc94c92842016-09-21 15:22:5215963 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_ALPN_NEGOTIATION_FAILED));
bnc5452e2a2015-05-08 16:27:4215964}
15965
bnc40448a532015-05-11 19:13:1415966// A request to a server with an alternative service fires two Jobs: one to the
zhongyi3d4a55e72016-04-22 20:36:4615967// server, and an alternate one to the alternative server. If the former
bnc40448a532015-05-11 19:13:1415968// succeeds, the request should succeed, even if the latter fails because
15969// HTTP/1.1 is negotiated which is insufficient for alternative service.
bncd16676a2016-07-20 16:23:0115970TEST_F(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
bnc8bef8da22016-05-30 01:28:2515971 url::SchemeHostPort server("https", "www.example.org", 443);
15972 HostPortPair alternative("www.example.org", 444);
bnc40448a532015-05-11 19:13:1415973
15974 // Negotiate HTTP/1.1 with alternative.
15975 SSLSocketDataProvider alternative_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615976 alternative_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1415977 session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
15978
15979 // No data should be read from the alternative, because HTTP/1.1 is
15980 // negotiated.
15981 StaticSocketDataProvider data;
15982 session_deps_.socket_factory->AddSocketDataProvider(&data);
15983
zhongyi3d4a55e72016-04-22 20:36:4615984 // Negotiate HTTP/1.1 with server.
bnc40448a532015-05-11 19:13:1415985 SSLSocketDataProvider origin_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615986 origin_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1415987 session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
15988
15989 MockWrite http_writes[] = {
bnc8bef8da22016-05-30 01:28:2515990 MockWrite("GET / HTTP/1.1\r\n"
15991 "Host: www.example.org\r\n"
15992 "Connection: keep-alive\r\n\r\n"),
15993 MockWrite("GET /second HTTP/1.1\r\n"
15994 "Host: www.example.org\r\n"
15995 "Connection: keep-alive\r\n\r\n"),
bnc40448a532015-05-11 19:13:1415996 };
15997
15998 MockRead http_reads[] = {
15999 MockRead("HTTP/1.1 200 OK\r\n"),
16000 MockRead("Content-Type: text/html\r\n"),
16001 MockRead("Content-Length: 6\r\n\r\n"),
16002 MockRead("foobar"),
16003 MockRead("HTTP/1.1 200 OK\r\n"),
16004 MockRead("Content-Type: text/html\r\n"),
16005 MockRead("Content-Length: 7\r\n\r\n"),
16006 MockRead("another"),
16007 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116008 StaticSocketDataProvider http_data(http_reads, http_writes);
bnc40448a532015-05-11 19:13:1416009 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16010
zhongyi3d4a55e72016-04-22 20:36:4616011 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0916012 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4016013 HttpServerProperties* http_server_properties =
bnc40448a532015-05-11 19:13:1416014 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2116015 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1216016 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2116017 http_server_properties->SetHttp2AlternativeService(
16018 server, alternative_service, expiration);
bnc40448a532015-05-11 19:13:1416019
16020 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
16021 HttpRequestInfo request1;
16022 request1.method = "GET";
bnc8bef8da22016-05-30 01:28:2516023 request1.url = GURL("https://www.example.org:443");
bnc40448a532015-05-11 19:13:1416024 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016025 request1.traffic_annotation =
16026 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc40448a532015-05-11 19:13:1416027 TestCompletionCallback callback1;
16028
tfarina42834112016-09-22 13:38:2016029 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1416030 rv = callback1.GetResult(rv);
robpercival214763f2016-07-01 23:27:0116031 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1416032
16033 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5216034 ASSERT_TRUE(response1);
16035 ASSERT_TRUE(response1->headers);
bnc40448a532015-05-11 19:13:1416036 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
16037
16038 std::string response_data1;
robpercival214763f2016-07-01 23:27:0116039 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc40448a532015-05-11 19:13:1416040 EXPECT_EQ("foobar", response_data1);
16041
16042 // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
16043 // for alternative service.
16044 EXPECT_TRUE(
16045 http_server_properties->IsAlternativeServiceBroken(alternative_service));
16046
zhongyi3d4a55e72016-04-22 20:36:4616047 // Since |alternative_service| is broken, a second transaction to server
bnc40448a532015-05-11 19:13:1416048 // should not start an alternate Job. It should pool to existing connection
zhongyi3d4a55e72016-04-22 20:36:4616049 // to server.
bnc40448a532015-05-11 19:13:1416050 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
16051 HttpRequestInfo request2;
16052 request2.method = "GET";
bnc8bef8da22016-05-30 01:28:2516053 request2.url = GURL("https://www.example.org:443/second");
bnc40448a532015-05-11 19:13:1416054 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016055 request2.traffic_annotation =
16056 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc40448a532015-05-11 19:13:1416057 TestCompletionCallback callback2;
16058
tfarina42834112016-09-22 13:38:2016059 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1416060 rv = callback2.GetResult(rv);
robpercival214763f2016-07-01 23:27:0116061 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1416062
16063 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5216064 ASSERT_TRUE(response2);
16065 ASSERT_TRUE(response2->headers);
bnc40448a532015-05-11 19:13:1416066 EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
16067
16068 std::string response_data2;
robpercival214763f2016-07-01 23:27:0116069 ASSERT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
bnc40448a532015-05-11 19:13:1416070 EXPECT_EQ("another", response_data2);
16071}
16072
bnc5452e2a2015-05-08 16:27:4216073// Alternative service requires HTTP/2 (or SPDY), but there is already a
16074// HTTP/1.1 socket open to the alternative server. That socket should not be
16075// used.
bncd16676a2016-07-20 16:23:0116076TEST_F(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
zhongyi3d4a55e72016-04-22 20:36:4616077 url::SchemeHostPort server("https", "origin.example.org", 443);
bnc5452e2a2015-05-08 16:27:4216078 HostPortPair alternative("alternative.example.org", 443);
16079 std::string origin_url = "https://origin.example.org:443";
16080 std::string alternative_url = "https://alternative.example.org:443";
16081
16082 // Negotiate HTTP/1.1 with alternative.example.org.
16083 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616084 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4216085 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16086
16087 // HTTP/1.1 data for |request1| and |request2|.
16088 MockWrite http_writes[] = {
16089 MockWrite(
16090 "GET / HTTP/1.1\r\n"
16091 "Host: alternative.example.org\r\n"
16092 "Connection: keep-alive\r\n\r\n"),
16093 MockWrite(
16094 "GET / HTTP/1.1\r\n"
16095 "Host: alternative.example.org\r\n"
16096 "Connection: keep-alive\r\n\r\n"),
16097 };
16098
16099 MockRead http_reads[] = {
16100 MockRead(
16101 "HTTP/1.1 200 OK\r\n"
16102 "Content-Type: text/html; charset=iso-8859-1\r\n"
16103 "Content-Length: 40\r\n\r\n"
16104 "first HTTP/1.1 response from alternative"),
16105 MockRead(
16106 "HTTP/1.1 200 OK\r\n"
16107 "Content-Type: text/html; charset=iso-8859-1\r\n"
16108 "Content-Length: 41\r\n\r\n"
16109 "second HTTP/1.1 response from alternative"),
16110 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116111 StaticSocketDataProvider http_data(http_reads, http_writes);
bnc5452e2a2015-05-08 16:27:4216112 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16113
16114 // This test documents that an alternate Job should not pool to an already
16115 // existing HTTP/1.1 connection. In order to test this, a failed connection
zhongyi3d4a55e72016-04-22 20:36:4616116 // to the server is mocked. This way |request2| relies on the alternate Job.
bnc5452e2a2015-05-08 16:27:4216117 StaticSocketDataProvider data_refused;
16118 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
16119 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
16120
zhongyi3d4a55e72016-04-22 20:36:4616121 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0916122 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4016123 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4216124 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2116125 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1216126 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2116127 http_server_properties->SetHttp2AlternativeService(
16128 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4216129
16130 // First transaction to alternative to open an HTTP/1.1 socket.
bnc5452e2a2015-05-08 16:27:4216131 HttpRequestInfo request1;
krasinc06a72a2016-12-21 03:42:4616132 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4216133 request1.method = "GET";
16134 request1.url = GURL(alternative_url);
16135 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016136 request1.traffic_annotation =
16137 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4216138 TestCompletionCallback callback1;
16139
tfarina42834112016-09-22 13:38:2016140 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116141 EXPECT_THAT(callback1.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1616142 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4216143 ASSERT_TRUE(response1);
wezca1070932016-05-26 20:30:5216144 ASSERT_TRUE(response1->headers);
bnc5452e2a2015-05-08 16:27:4216145 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5216146 EXPECT_TRUE(response1->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4216147 EXPECT_FALSE(response1->was_fetched_via_spdy);
16148 std::string response_data1;
bnc691fda62016-08-12 00:43:1616149 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc5452e2a2015-05-08 16:27:4216150 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
16151
16152 // Request for origin.example.org, which has an alternative service. This
16153 // will start two Jobs: the alternative looks for connections to pool to,
16154 // finds one which is HTTP/1.1, and should ignore it, and should not try to
zhongyi3d4a55e72016-04-22 20:36:4616155 // open other connections to alternative server. The Job to server fails, so
bnc5452e2a2015-05-08 16:27:4216156 // this request fails.
bnc5452e2a2015-05-08 16:27:4216157 HttpRequestInfo request2;
krasinc06a72a2016-12-21 03:42:4616158 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4216159 request2.method = "GET";
16160 request2.url = GURL(origin_url);
16161 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016162 request2.traffic_annotation =
16163 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4216164 TestCompletionCallback callback2;
16165
tfarina42834112016-09-22 13:38:2016166 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116167 EXPECT_THAT(callback2.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc5452e2a2015-05-08 16:27:4216168
16169 // Another transaction to alternative. This is to test that the HTTP/1.1
16170 // socket is still open and in the pool.
bnc5452e2a2015-05-08 16:27:4216171 HttpRequestInfo request3;
krasinc06a72a2016-12-21 03:42:4616172 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4216173 request3.method = "GET";
16174 request3.url = GURL(alternative_url);
16175 request3.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016176 request3.traffic_annotation =
16177 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4216178 TestCompletionCallback callback3;
16179
tfarina42834112016-09-22 13:38:2016180 rv = trans3.Start(&request3, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116181 EXPECT_THAT(callback3.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1616182 const HttpResponseInfo* response3 = trans3.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4216183 ASSERT_TRUE(response3);
wezca1070932016-05-26 20:30:5216184 ASSERT_TRUE(response3->headers);
bnc5452e2a2015-05-08 16:27:4216185 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5216186 EXPECT_TRUE(response3->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4216187 EXPECT_FALSE(response3->was_fetched_via_spdy);
16188 std::string response_data3;
bnc691fda62016-08-12 00:43:1616189 ASSERT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
bnc5452e2a2015-05-08 16:27:4216190 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
16191}
16192
bncd16676a2016-07-20 16:23:0116193TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2316194 const std::string https_url = "https://www.example.org:8080/";
16195 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0416196
rdsmithebb50aa2015-11-12 03:44:3816197 // Separate SPDY util instance for naked and wrapped requests.
bncd16676a2016-07-20 16:23:0116198 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:3816199
[email protected]8450d722012-07-02 19:14:0416200 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2316201 const HostPortPair host_port_pair("www.example.org", 8080);
Ryan Hamilton0239aac2018-05-19 00:03:1316202 spdy::SpdySerializedFrame connect(
lgarrona91df87f2014-12-05 00:51:3416203 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
Ryan Hamilton0239aac2018-05-19 00:03:1316204 spdy::SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4916205 spdy_util_wrapped.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1316206 spdy::SpdySerializedFrame wrapped_req1(
[email protected]23e482282013-06-14 16:08:0216207 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3916208
16209 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
Ryan Hamilton0239aac2018-05-19 00:03:1316210 spdy::SpdyHeaderBlock req2_block;
16211 req2_block[spdy::kHttp2MethodHeader] = "GET";
16212 req2_block[spdy::kHttp2AuthorityHeader] = "www.example.org:8080";
16213 req2_block[spdy::kHttp2SchemeHeader] = "http";
16214 req2_block[spdy::kHttp2PathHeader] = "/";
16215 spdy::SpdySerializedFrame req2(
bnc42331402016-07-25 13:36:1516216 spdy_util_.ConstructSpdyHeaders(3, std::move(req2_block), MEDIUM, true));
[email protected]8450d722012-07-02 19:14:0416217
16218 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4116219 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_req1, 2),
16220 CreateMockWrite(req2, 6),
[email protected]8450d722012-07-02 19:14:0416221 };
16222
Ryan Hamilton0239aac2018-05-19 00:03:1316223 spdy::SpdySerializedFrame conn_resp(
bnc42331402016-07-25 13:36:1516224 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316225 spdy::SpdySerializedFrame resp1(
bnc42331402016-07-25 13:36:1516226 spdy_util_wrapped.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316227 spdy::SpdySerializedFrame body1(
16228 spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
16229 spdy::SpdySerializedFrame wrapped_resp1(
rdsmithebb50aa2015-11-12 03:44:3816230 spdy_util_wrapped.ConstructWrappedSpdyFrame(resp1, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316231 spdy::SpdySerializedFrame wrapped_body1(
rdsmithebb50aa2015-11-12 03:44:3816232 spdy_util_wrapped.ConstructWrappedSpdyFrame(body1, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316233 spdy::SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
16234 spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
mmenke666a6fea2015-12-19 04:16:3316235 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4116236 CreateMockRead(conn_resp, 1),
mmenke666a6fea2015-12-19 04:16:3316237 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:4116238 CreateMockRead(wrapped_resp1, 4),
16239 CreateMockRead(wrapped_body1, 5),
mmenke666a6fea2015-12-19 04:16:3316240 MockRead(ASYNC, ERR_IO_PENDING, 7),
bncdf80d44fd2016-07-15 20:27:4116241 CreateMockRead(resp2, 8),
16242 CreateMockRead(body2, 9),
mmenke666a6fea2015-12-19 04:16:3316243 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 10),
16244 };
[email protected]8450d722012-07-02 19:14:0416245
Ryan Sleevib8d7ea02018-05-07 20:01:0116246 SequencedSocketData data1(reads1, writes1);
[email protected]8450d722012-07-02 19:14:0416247 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5716248 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0416249
Lily Houghton8c2f97d2018-01-22 05:06:5916250 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4916251 ProxyResolutionService::CreateFixedFromPacResult(
16252 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5116253 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0716254 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0416255 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3616256 ssl1.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3316257 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0416258 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3616259 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3316260 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
16261 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0416262
danakj1fd259a02016-04-16 03:17:0916263 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]8450d722012-07-02 19:14:0416264
16265 // Start the first transaction to set up the SpdySession
16266 HttpRequestInfo request1;
16267 request1.method = "GET";
16268 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0416269 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016270 request1.traffic_annotation =
16271 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016272 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0416273 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:2016274 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0416275
mmenke666a6fea2015-12-19 04:16:3316276 // This pause is a hack to avoid running into https://crbug.com/497228.
16277 data1.RunUntilPaused();
16278 base::RunLoop().RunUntilIdle();
16279 data1.Resume();
robpercival214763f2016-07-01 23:27:0116280 EXPECT_THAT(callback1.GetResult(rv), IsOk());
[email protected]8450d722012-07-02 19:14:0416281 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
16282
[email protected]f6c63db52013-02-02 00:35:2216283 LoadTimingInfo load_timing_info1;
16284 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
16285 TestLoadTimingNotReusedWithPac(load_timing_info1,
16286 CONNECT_TIMING_HAS_SSL_TIMES);
16287
mmenke666a6fea2015-12-19 04:16:3316288 // Now, start the HTTP request.
[email protected]8450d722012-07-02 19:14:0416289 HttpRequestInfo request2;
16290 request2.method = "GET";
16291 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0416292 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016293 request2.traffic_annotation =
16294 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016295 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0416296 TestCompletionCallback callback2;
tfarina42834112016-09-22 13:38:2016297 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0416298
mmenke666a6fea2015-12-19 04:16:3316299 // This pause is a hack to avoid running into https://crbug.com/497228.
16300 data1.RunUntilPaused();
16301 base::RunLoop().RunUntilIdle();
16302 data1.Resume();
robpercival214763f2016-07-01 23:27:0116303 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenke666a6fea2015-12-19 04:16:3316304
[email protected]8450d722012-07-02 19:14:0416305 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2216306
16307 LoadTimingInfo load_timing_info2;
16308 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
16309 // The established SPDY sessions is considered reused by the HTTP request.
16310 TestLoadTimingReusedWithPac(load_timing_info2);
16311 // HTTP requests over a SPDY session should have a different connection
16312 // socket_log_id than requests over a tunnel.
16313 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0416314}
16315
[email protected]2d88e7d2012-07-19 17:55:1716316// Test that in the case where we have a SPDY session to a SPDY proxy
16317// that we do not pool other origins that resolve to the same IP when
16318// the certificate does not match the new origin.
16319// http://crbug.com/134690
bncd16676a2016-07-20 16:23:0116320TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2316321 const std::string url1 = "http://www.example.org/";
16322 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1716323 const std::string ip_addr = "1.2.3.4";
16324
rdsmithebb50aa2015-11-12 03:44:3816325 // Second SpdyTestUtil instance for the second socket.
bncd16676a2016-07-20 16:23:0116326 SpdyTestUtil spdy_util_secure;
rdsmithebb50aa2015-11-12 03:44:3816327
[email protected]2d88e7d2012-07-19 17:55:1716328 // SPDY GET for HTTP URL (through SPDY proxy)
Ryan Hamilton0239aac2018-05-19 00:03:1316329 spdy::SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:2316330 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
Ryan Hamilton0239aac2018-05-19 00:03:1316331 spdy::SpdySerializedFrame req1(
bnc42331402016-07-25 13:36:1516332 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
[email protected]2d88e7d2012-07-19 17:55:1716333
16334 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4116335 CreateMockWrite(req1, 0),
[email protected]2d88e7d2012-07-19 17:55:1716336 };
16337
Ryan Hamilton0239aac2018-05-19 00:03:1316338 spdy::SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
16339 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1716340 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4116341 MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(resp1, 2),
16342 CreateMockRead(body1, 3), MockRead(ASYNC, OK, 4), // EOF
[email protected]2d88e7d2012-07-19 17:55:1716343 };
16344
Ryan Sleevib8d7ea02018-05-07 20:01:0116345 SequencedSocketData data1(reads1, writes1);
martijnfe9636e2016-02-06 14:33:3216346 IPAddress ip;
martijn654c8c42016-02-10 22:10:5916347 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
[email protected]2d88e7d2012-07-19 17:55:1716348 IPEndPoint peer_addr = IPEndPoint(ip, 443);
16349 MockConnect connect_data1(ASYNC, OK, peer_addr);
mmenke666a6fea2015-12-19 04:16:3316350 data1.set_connect_data(connect_data1);
[email protected]2d88e7d2012-07-19 17:55:1716351
16352 // SPDY GET for HTTPS URL (direct)
Ryan Hamilton0239aac2018-05-19 00:03:1316353 spdy::SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4916354 spdy_util_secure.ConstructSpdyGet(url2.c_str(), 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1716355
16356 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4116357 CreateMockWrite(req2, 0),
[email protected]2d88e7d2012-07-19 17:55:1716358 };
16359
Ryan Hamilton0239aac2018-05-19 00:03:1316360 spdy::SpdySerializedFrame resp2(
16361 spdy_util_secure.ConstructSpdyGetReply(NULL, 0, 1));
16362 spdy::SpdySerializedFrame body2(
16363 spdy_util_secure.ConstructSpdyDataFrame(1, true));
bncdf80d44fd2016-07-15 20:27:4116364 MockRead reads2[] = {CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
mmenke666a6fea2015-12-19 04:16:3316365 MockRead(ASYNC, OK, 3)};
[email protected]2d88e7d2012-07-19 17:55:1716366
Ryan Sleevib8d7ea02018-05-07 20:01:0116367 SequencedSocketData data2(reads2, writes2);
[email protected]2d88e7d2012-07-19 17:55:1716368 MockConnect connect_data2(ASYNC, OK);
mmenke666a6fea2015-12-19 04:16:3316369 data2.set_connect_data(connect_data2);
[email protected]2d88e7d2012-07-19 17:55:1716370
16371 // Set up a proxy config that sends HTTP requests to a proxy, and
16372 // all others direct.
16373 ProxyConfig proxy_config;
16374 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
Ramin Halavatica8d5252018-03-12 05:33:4916375 session_deps_.proxy_resolution_service =
16376 std::make_unique<ProxyResolutionService>(
16377 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
16378 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
16379 nullptr, nullptr);
[email protected]2d88e7d2012-07-19 17:55:1716380
bncce36dca22015-04-21 22:11:2316381 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3616382 ssl1.next_proto = kProtoHTTP2;
[email protected]2d88e7d2012-07-19 17:55:1716383 // Load a valid cert. Note, that this does not need to
16384 // be valid for proxy because the MockSSLClientSocket does
16385 // not actually verify it. But SpdySession will use this
16386 // to see if it is valid for the new origin
Ryan Sleevi4f832092017-11-21 23:25:4916387 ssl1.ssl_info.cert =
16388 ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
16389 ASSERT_TRUE(ssl1.ssl_info.cert);
mmenke666a6fea2015-12-19 04:16:3316390 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
16391 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d88e7d2012-07-19 17:55:1716392
16393 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3616394 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3316395 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
16396 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d88e7d2012-07-19 17:55:1716397
Jeremy Roman0579ed62017-08-29 15:56:1916398 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
bncce36dca22015-04-21 22:11:2316399 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0716400 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1716401
danakj1fd259a02016-04-16 03:17:0916402 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]2d88e7d2012-07-19 17:55:1716403
16404 // Start the first transaction to set up the SpdySession
16405 HttpRequestInfo request1;
16406 request1.method = "GET";
16407 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1716408 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016409 request1.traffic_annotation =
16410 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016411 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1716412 TestCompletionCallback callback1;
16413 ASSERT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016414 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
mmenke666a6fea2015-12-19 04:16:3316415 // This pause is a hack to avoid running into https://crbug.com/497228.
16416 data1.RunUntilPaused();
16417 base::RunLoop().RunUntilIdle();
16418 data1.Resume();
[email protected]2d88e7d2012-07-19 17:55:1716419
robpercival214763f2016-07-01 23:27:0116420 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1716421 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
16422
16423 // Now, start the HTTP request
16424 HttpRequestInfo request2;
16425 request2.method = "GET";
16426 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1716427 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016428 request2.traffic_annotation =
16429 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016430 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1716431 TestCompletionCallback callback2;
16432 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016433 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5516434 base::RunLoop().RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1716435
16436 ASSERT_TRUE(callback2.have_result());
robpercival214763f2016-07-01 23:27:0116437 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1716438 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
16439}
16440
[email protected]85f97342013-04-17 06:12:2416441// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
16442// error) in SPDY session, removes the socket from pool and closes the SPDY
16443// session. Verify that new url's from the same HttpNetworkSession (and a new
16444// SpdySession) do work. http://crbug.com/224701
bncd16676a2016-07-20 16:23:0116445TEST_F(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2316446 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2416447
16448 MockRead reads1[] = {
16449 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
16450 };
16451
Ryan Sleevib8d7ea02018-05-07 20:01:0116452 SequencedSocketData data1(reads1, base::span<MockWrite>());
[email protected]85f97342013-04-17 06:12:2416453
Ryan Hamilton0239aac2018-05-19 00:03:1316454 spdy::SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4916455 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2416456 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4116457 CreateMockWrite(req2, 0),
[email protected]85f97342013-04-17 06:12:2416458 };
16459
Ryan Hamilton0239aac2018-05-19 00:03:1316460 spdy::SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
16461 spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]85f97342013-04-17 06:12:2416462 MockRead reads2[] = {
bncdf80d44fd2016-07-15 20:27:4116463 CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
16464 MockRead(ASYNC, OK, 3) // EOF
[email protected]85f97342013-04-17 06:12:2416465 };
16466
Ryan Sleevib8d7ea02018-05-07 20:01:0116467 SequencedSocketData data2(reads2, writes2);
[email protected]85f97342013-04-17 06:12:2416468
[email protected]85f97342013-04-17 06:12:2416469 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616470 ssl1.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5016471 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
16472 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]85f97342013-04-17 06:12:2416473
16474 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616475 ssl2.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5016476 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
16477 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]85f97342013-04-17 06:12:2416478
danakj1fd259a02016-04-16 03:17:0916479 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:5016480 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]85f97342013-04-17 06:12:2416481
16482 // Start the first transaction to set up the SpdySession and verify that
16483 // connection was closed.
16484 HttpRequestInfo request1;
16485 request1.method = "GET";
16486 request1.url = GURL(https_url);
16487 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016488 request1.traffic_annotation =
16489 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016490 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2416491 TestCompletionCallback callback1;
16492 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016493 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0116494 EXPECT_THAT(callback1.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]85f97342013-04-17 06:12:2416495
16496 // Now, start the second request and make sure it succeeds.
16497 HttpRequestInfo request2;
16498 request2.method = "GET";
16499 request2.url = GURL(https_url);
16500 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016501 request2.traffic_annotation =
16502 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016503 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2416504 TestCompletionCallback callback2;
16505 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016506 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
[email protected]85f97342013-04-17 06:12:2416507
robpercival214763f2016-07-01 23:27:0116508 ASSERT_THAT(callback2.WaitForResult(), IsOk());
[email protected]85f97342013-04-17 06:12:2416509 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
16510}
16511
bncd16676a2016-07-20 16:23:0116512TEST_F(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]483fa202013-05-14 01:07:0316513 ClientSocketPoolManager::set_max_sockets_per_group(
16514 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16515 ClientSocketPoolManager::set_max_sockets_per_pool(
16516 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16517
16518 // Use two different hosts with different IPs so they don't get pooled.
16519 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
16520 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
danakj1fd259a02016-04-16 03:17:0916521 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]483fa202013-05-14 01:07:0316522
16523 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616524 ssl1.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0316525 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616526 ssl2.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0316527 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
16528 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
16529
Ryan Hamilton0239aac2018-05-19 00:03:1316530 spdy::SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4916531 spdy_util_.ConstructSpdyGet("https://www.a.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0316532 MockWrite spdy1_writes[] = {
bncdf80d44fd2016-07-15 20:27:4116533 CreateMockWrite(host1_req, 0),
[email protected]483fa202013-05-14 01:07:0316534 };
Ryan Hamilton0239aac2018-05-19 00:03:1316535 spdy::SpdySerializedFrame host1_resp(
16536 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
16537 spdy::SpdySerializedFrame host1_resp_body(
bncdf80d44fd2016-07-15 20:27:4116538 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0316539 MockRead spdy1_reads[] = {
bncdf80d44fd2016-07-15 20:27:4116540 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
mmenkee24011922015-12-17 22:12:5916541 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0316542 };
16543
rdsmithebb50aa2015-11-12 03:44:3816544 // Use a separate test instance for the separate SpdySession that will be
16545 // created.
bncd16676a2016-07-20 16:23:0116546 SpdyTestUtil spdy_util_2;
Ryan Sleevib8d7ea02018-05-07 20:01:0116547 SequencedSocketData spdy1_data(spdy1_reads, spdy1_writes);
Bence Béky53a5aef2018-03-29 21:54:1216548 session_deps_.socket_factory->AddSocketDataProvider(&spdy1_data);
[email protected]483fa202013-05-14 01:07:0316549
Ryan Hamilton0239aac2018-05-19 00:03:1316550 spdy::SpdySerializedFrame host2_req(
bnc38dcd392016-02-09 23:19:4916551 spdy_util_2.ConstructSpdyGet("https://www.b.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0316552 MockWrite spdy2_writes[] = {
bncdf80d44fd2016-07-15 20:27:4116553 CreateMockWrite(host2_req, 0),
[email protected]483fa202013-05-14 01:07:0316554 };
Ryan Hamilton0239aac2018-05-19 00:03:1316555 spdy::SpdySerializedFrame host2_resp(
16556 spdy_util_2.ConstructSpdyGetReply(NULL, 0, 1));
16557 spdy::SpdySerializedFrame host2_resp_body(
bncdf80d44fd2016-07-15 20:27:4116558 spdy_util_2.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0316559 MockRead spdy2_reads[] = {
bncdf80d44fd2016-07-15 20:27:4116560 CreateMockRead(host2_resp, 1), CreateMockRead(host2_resp_body, 2),
mmenkee24011922015-12-17 22:12:5916561 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0316562 };
16563
Ryan Sleevib8d7ea02018-05-07 20:01:0116564 SequencedSocketData spdy2_data(spdy2_reads, spdy2_writes);
Bence Béky53a5aef2018-03-29 21:54:1216565 session_deps_.socket_factory->AddSocketDataProvider(&spdy2_data);
[email protected]483fa202013-05-14 01:07:0316566
16567 MockWrite http_write[] = {
16568 MockWrite("GET / HTTP/1.1\r\n"
16569 "Host: www.a.com\r\n"
16570 "Connection: keep-alive\r\n\r\n"),
16571 };
16572
16573 MockRead http_read[] = {
16574 MockRead("HTTP/1.1 200 OK\r\n"),
16575 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
16576 MockRead("Content-Length: 6\r\n\r\n"),
16577 MockRead("hello!"),
16578 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116579 StaticSocketDataProvider http_data(http_read, http_write);
[email protected]483fa202013-05-14 01:07:0316580 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16581
16582 HostPortPair host_port_pair_a("www.a.com", 443);
Matt Menke2436b2f2018-12-11 18:07:1116583 SpdySessionKey spdy_session_key_a(
16584 host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
16585 SpdySessionKey::IsProxySession::kFalse, SocketTag());
[email protected]483fa202013-05-14 01:07:0316586 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616587 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0316588
16589 TestCompletionCallback callback;
16590 HttpRequestInfo request1;
16591 request1.method = "GET";
16592 request1.url = GURL("https://www.a.com/");
16593 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016594 request1.traffic_annotation =
16595 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5816596 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1916597 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0316598
tfarina42834112016-09-22 13:38:2016599 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116600 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16601 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0316602
16603 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5216604 ASSERT_TRUE(response);
16605 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0216606 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0316607 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5216608 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]483fa202013-05-14 01:07:0316609
16610 std::string response_data;
robpercival214763f2016-07-01 23:27:0116611 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0316612 EXPECT_EQ("hello!", response_data);
16613 trans.reset();
16614 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2616615 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0316616
16617 HostPortPair host_port_pair_b("www.b.com", 443);
Matt Menke2436b2f2018-12-11 18:07:1116618 SpdySessionKey spdy_session_key_b(
16619 host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
16620 SpdySessionKey::IsProxySession::kFalse, SocketTag());
[email protected]483fa202013-05-14 01:07:0316621 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616622 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0316623 HttpRequestInfo request2;
16624 request2.method = "GET";
16625 request2.url = GURL("https://www.b.com/");
16626 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016627 request2.traffic_annotation =
16628 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5816629 trans =
Jeremy Roman0579ed62017-08-29 15:56:1916630 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0316631
tfarina42834112016-09-22 13:38:2016632 rv = trans->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116633 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16634 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0316635
16636 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5216637 ASSERT_TRUE(response);
16638 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0216639 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0316640 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5216641 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0116642 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0316643 EXPECT_EQ("hello!", response_data);
16644 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616645 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0316646 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2616647 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0316648
16649 HostPortPair host_port_pair_a1("www.a.com", 80);
Matt Menke2436b2f2018-12-11 18:07:1116650 SpdySessionKey spdy_session_key_a1(
16651 host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
16652 SpdySessionKey::IsProxySession::kFalse, SocketTag());
[email protected]483fa202013-05-14 01:07:0316653 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616654 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0316655 HttpRequestInfo request3;
16656 request3.method = "GET";
16657 request3.url = GURL("http://www.a.com/");
16658 request3.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016659 request3.traffic_annotation =
16660 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5816661 trans =
Jeremy Roman0579ed62017-08-29 15:56:1916662 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0316663
tfarina42834112016-09-22 13:38:2016664 rv = trans->Start(&request3, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116665 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16666 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0316667
16668 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5216669 ASSERT_TRUE(response);
16670 ASSERT_TRUE(response->headers);
[email protected]483fa202013-05-14 01:07:0316671 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
16672 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5216673 EXPECT_FALSE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0116674 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0316675 EXPECT_EQ("hello!", response_data);
16676 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616677 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0316678 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616679 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0316680}
16681
bncd16676a2016-07-20 16:23:0116682TEST_F(HttpNetworkTransactionTest, HttpSyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0416683 HttpRequestInfo request;
16684 request.method = "GET";
bncce36dca22015-04-21 22:11:2316685 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016686 request.traffic_annotation =
16687 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416688
danakj1fd259a02016-04-16 03:17:0916689 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616690 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416691
ttuttled9dbc652015-09-29 20:00:5916692 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0416693 StaticSocketDataProvider data;
16694 data.set_connect_data(mock_connect);
16695 session_deps_.socket_factory->AddSocketDataProvider(&data);
16696
16697 TestCompletionCallback callback;
16698
tfarina42834112016-09-22 13:38:2016699 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116700 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416701
16702 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116703 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0416704
[email protected]79e1fd62013-06-20 06:50:0416705 // We don't care whether this succeeds or fails, but it shouldn't crash.
16706 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616707 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4716708
16709 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1616710 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4716711 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0116712 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5916713
16714 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1616715 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5916716 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0416717}
16718
bncd16676a2016-07-20 16:23:0116719TEST_F(HttpNetworkTransactionTest, HttpAsyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0416720 HttpRequestInfo request;
16721 request.method = "GET";
bncce36dca22015-04-21 22:11:2316722 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016723 request.traffic_annotation =
16724 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416725
danakj1fd259a02016-04-16 03:17:0916726 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616727 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416728
ttuttled9dbc652015-09-29 20:00:5916729 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0416730 StaticSocketDataProvider data;
16731 data.set_connect_data(mock_connect);
16732 session_deps_.socket_factory->AddSocketDataProvider(&data);
16733
16734 TestCompletionCallback callback;
16735
tfarina42834112016-09-22 13:38:2016736 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116737 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416738
16739 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116740 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0416741
[email protected]79e1fd62013-06-20 06:50:0416742 // We don't care whether this succeeds or fails, but it shouldn't crash.
16743 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616744 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4716745
16746 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1616747 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4716748 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0116749 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5916750
16751 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1616752 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5916753 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0416754}
16755
bncd16676a2016-07-20 16:23:0116756TEST_F(HttpNetworkTransactionTest, HttpSyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0416757 HttpRequestInfo request;
16758 request.method = "GET";
bncce36dca22015-04-21 22:11:2316759 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016760 request.traffic_annotation =
16761 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416762
danakj1fd259a02016-04-16 03:17:0916763 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616764 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416765
16766 MockWrite data_writes[] = {
16767 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16768 };
16769 MockRead data_reads[] = {
16770 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
16771 };
16772
Ryan Sleevib8d7ea02018-05-07 20:01:0116773 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0416774 session_deps_.socket_factory->AddSocketDataProvider(&data);
16775
16776 TestCompletionCallback callback;
16777
tfarina42834112016-09-22 13:38:2016778 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116779 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416780
16781 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116782 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416783
[email protected]79e1fd62013-06-20 06:50:0416784 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616785 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416786 EXPECT_TRUE(request_headers.HasHeader("Host"));
16787}
16788
bncd16676a2016-07-20 16:23:0116789TEST_F(HttpNetworkTransactionTest, HttpAsyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0416790 HttpRequestInfo request;
16791 request.method = "GET";
bncce36dca22015-04-21 22:11:2316792 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016793 request.traffic_annotation =
16794 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416795
danakj1fd259a02016-04-16 03:17:0916796 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616797 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416798
16799 MockWrite data_writes[] = {
16800 MockWrite(ASYNC, ERR_CONNECTION_RESET),
16801 };
16802 MockRead data_reads[] = {
16803 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
16804 };
16805
Ryan Sleevib8d7ea02018-05-07 20:01:0116806 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0416807 session_deps_.socket_factory->AddSocketDataProvider(&data);
16808
16809 TestCompletionCallback callback;
16810
tfarina42834112016-09-22 13:38:2016811 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116812 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416813
16814 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116815 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416816
[email protected]79e1fd62013-06-20 06:50:0416817 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616818 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416819 EXPECT_TRUE(request_headers.HasHeader("Host"));
16820}
16821
bncd16676a2016-07-20 16:23:0116822TEST_F(HttpNetworkTransactionTest, HttpSyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0416823 HttpRequestInfo request;
16824 request.method = "GET";
bncce36dca22015-04-21 22:11:2316825 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016826 request.traffic_annotation =
16827 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416828
danakj1fd259a02016-04-16 03:17:0916829 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616830 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416831
16832 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2316833 MockWrite(
16834 "GET / HTTP/1.1\r\n"
16835 "Host: www.example.org\r\n"
16836 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0416837 };
16838 MockRead data_reads[] = {
16839 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
16840 };
16841
Ryan Sleevib8d7ea02018-05-07 20:01:0116842 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0416843 session_deps_.socket_factory->AddSocketDataProvider(&data);
16844
16845 TestCompletionCallback callback;
16846
tfarina42834112016-09-22 13:38:2016847 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116848 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416849
16850 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116851 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416852
[email protected]79e1fd62013-06-20 06:50:0416853 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616854 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416855 EXPECT_TRUE(request_headers.HasHeader("Host"));
16856}
16857
bncd16676a2016-07-20 16:23:0116858TEST_F(HttpNetworkTransactionTest, HttpAsyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0416859 HttpRequestInfo request;
16860 request.method = "GET";
bncce36dca22015-04-21 22:11:2316861 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016862 request.traffic_annotation =
16863 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416864
danakj1fd259a02016-04-16 03:17:0916865 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616866 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416867
16868 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2316869 MockWrite(
16870 "GET / HTTP/1.1\r\n"
16871 "Host: www.example.org\r\n"
16872 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0416873 };
16874 MockRead data_reads[] = {
16875 MockRead(ASYNC, ERR_CONNECTION_RESET),
16876 };
16877
Ryan Sleevib8d7ea02018-05-07 20:01:0116878 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0416879 session_deps_.socket_factory->AddSocketDataProvider(&data);
16880
16881 TestCompletionCallback callback;
16882
tfarina42834112016-09-22 13:38:2016883 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116884 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416885
16886 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116887 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416888
[email protected]79e1fd62013-06-20 06:50:0416889 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616890 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416891 EXPECT_TRUE(request_headers.HasHeader("Host"));
16892}
16893
bncd16676a2016-07-20 16:23:0116894TEST_F(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
[email protected]79e1fd62013-06-20 06:50:0416895 HttpRequestInfo request;
16896 request.method = "GET";
bncce36dca22015-04-21 22:11:2316897 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0416898 request.extra_headers.SetHeader("X-Foo", "bar");
Ramin Halavatib5e433e2018-02-07 07:41:1016899 request.traffic_annotation =
16900 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416901
danakj1fd259a02016-04-16 03:17:0916902 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616903 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416904
16905 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2316906 MockWrite(
16907 "GET / HTTP/1.1\r\n"
16908 "Host: www.example.org\r\n"
16909 "Connection: keep-alive\r\n"
16910 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0416911 };
16912 MockRead data_reads[] = {
16913 MockRead("HTTP/1.1 200 OK\r\n"
16914 "Content-Length: 5\r\n\r\n"
16915 "hello"),
16916 MockRead(ASYNC, ERR_UNEXPECTED),
16917 };
16918
Ryan Sleevib8d7ea02018-05-07 20:01:0116919 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0416920 session_deps_.socket_factory->AddSocketDataProvider(&data);
16921
16922 TestCompletionCallback callback;
16923
tfarina42834112016-09-22 13:38:2016924 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116925 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416926
16927 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116928 EXPECT_THAT(rv, IsOk());
[email protected]79e1fd62013-06-20 06:50:0416929
16930 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616931 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416932 std::string foo;
16933 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
16934 EXPECT_EQ("bar", foo);
16935}
16936
[email protected]043b68c82013-08-22 23:41:5216937// Tests that when a used socket is returned to the SSL socket pool, it's closed
16938// if the transport socket pool is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0116939TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
[email protected]043b68c82013-08-22 23:41:5216940 ClientSocketPoolManager::set_max_sockets_per_group(
16941 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16942 ClientSocketPoolManager::set_max_sockets_per_pool(
16943 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16944
16945 // Set up SSL request.
16946
16947 HttpRequestInfo ssl_request;
16948 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2316949 ssl_request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016950 ssl_request.traffic_annotation =
16951 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5216952
16953 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2316954 MockWrite(
16955 "GET / HTTP/1.1\r\n"
16956 "Host: www.example.org\r\n"
16957 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5216958 };
16959 MockRead ssl_reads[] = {
16960 MockRead("HTTP/1.1 200 OK\r\n"),
16961 MockRead("Content-Length: 11\r\n\r\n"),
16962 MockRead("hello world"),
16963 MockRead(SYNCHRONOUS, OK),
16964 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116965 StaticSocketDataProvider ssl_data(ssl_reads, ssl_writes);
[email protected]043b68c82013-08-22 23:41:5216966 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
16967
16968 SSLSocketDataProvider ssl(ASYNC, OK);
16969 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16970
16971 // Set up HTTP request.
16972
16973 HttpRequestInfo http_request;
16974 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2316975 http_request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016976 http_request.traffic_annotation =
16977 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5216978
16979 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2316980 MockWrite(
16981 "GET / HTTP/1.1\r\n"
16982 "Host: www.example.org\r\n"
16983 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5216984 };
16985 MockRead http_reads[] = {
16986 MockRead("HTTP/1.1 200 OK\r\n"),
16987 MockRead("Content-Length: 7\r\n\r\n"),
16988 MockRead("falafel"),
16989 MockRead(SYNCHRONOUS, OK),
16990 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116991 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]043b68c82013-08-22 23:41:5216992 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16993
danakj1fd259a02016-04-16 03:17:0916994 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5216995
16996 // Start the SSL request.
16997 TestCompletionCallback ssl_callback;
bnc691fda62016-08-12 00:43:1616998 HttpNetworkTransaction ssl_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016999 ASSERT_EQ(ERR_IO_PENDING,
17000 ssl_trans.Start(&ssl_request, ssl_callback.callback(),
17001 NetLogWithSource()));
[email protected]043b68c82013-08-22 23:41:5217002
17003 // Start the HTTP request. Pool should stall.
17004 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1617005 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2017006 ASSERT_EQ(ERR_IO_PENDING,
17007 http_trans.Start(&http_request, http_callback.callback(),
17008 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4117009 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5217010
17011 // Wait for response from SSL request.
robpercival214763f2016-07-01 23:27:0117012 ASSERT_THAT(ssl_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5217013 std::string response_data;
bnc691fda62016-08-12 00:43:1617014 ASSERT_THAT(ReadTransaction(&ssl_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5217015 EXPECT_EQ("hello world", response_data);
17016
17017 // The SSL socket should automatically be closed, so the HTTP request can
17018 // start.
dcheng48459ac22014-08-26 00:46:4117019 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
17020 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5217021
17022 // The HTTP request can now complete.
robpercival214763f2016-07-01 23:27:0117023 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
bnc691fda62016-08-12 00:43:1617024 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5217025 EXPECT_EQ("falafel", response_data);
17026
dcheng48459ac22014-08-26 00:46:4117027 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5217028}
17029
17030// Tests that when a SSL connection is established but there's no corresponding
17031// request that needs it, the new socket is closed if the transport socket pool
17032// is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0117033TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
[email protected]043b68c82013-08-22 23:41:5217034 ClientSocketPoolManager::set_max_sockets_per_group(
17035 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
17036 ClientSocketPoolManager::set_max_sockets_per_pool(
17037 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
17038
17039 // Set up an ssl request.
17040
17041 HttpRequestInfo ssl_request;
17042 ssl_request.method = "GET";
17043 ssl_request.url = GURL("https://www.foopy.com/");
Ramin Halavatib5e433e2018-02-07 07:41:1017044 ssl_request.traffic_annotation =
17045 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5217046
17047 // No data will be sent on the SSL socket.
17048 StaticSocketDataProvider ssl_data;
17049 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
17050
17051 SSLSocketDataProvider ssl(ASYNC, OK);
17052 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
17053
17054 // Set up HTTP request.
17055
17056 HttpRequestInfo http_request;
17057 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2317058 http_request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017059 http_request.traffic_annotation =
17060 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5217061
17062 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2317063 MockWrite(
17064 "GET / HTTP/1.1\r\n"
17065 "Host: www.example.org\r\n"
17066 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5217067 };
17068 MockRead http_reads[] = {
17069 MockRead("HTTP/1.1 200 OK\r\n"),
17070 MockRead("Content-Length: 7\r\n\r\n"),
17071 MockRead("falafel"),
17072 MockRead(SYNCHRONOUS, OK),
17073 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117074 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]043b68c82013-08-22 23:41:5217075 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
17076
danakj1fd259a02016-04-16 03:17:0917077 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5217078
17079 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
17080 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2917081 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
nharper8cdb0fb2016-04-22 21:34:5917082 http_stream_factory->PreconnectStreams(1, ssl_request);
dcheng48459ac22014-08-26 00:46:4117083 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5217084
17085 // Start the HTTP request. Pool should stall.
17086 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1617087 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2017088 ASSERT_EQ(ERR_IO_PENDING,
17089 http_trans.Start(&http_request, http_callback.callback(),
17090 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4117091 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5217092
17093 // The SSL connection will automatically be closed once the connection is
17094 // established, to let the HTTP request start.
robpercival214763f2016-07-01 23:27:0117095 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5217096 std::string response_data;
bnc691fda62016-08-12 00:43:1617097 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5217098 EXPECT_EQ("falafel", response_data);
17099
dcheng48459ac22014-08-26 00:46:4117100 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5217101}
17102
bncd16676a2016-07-20 16:23:0117103TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0917104 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217105 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917106 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217107 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417108
17109 HttpRequestInfo request;
17110 request.method = "POST";
17111 request.url = GURL("http://www.foo.com/");
17112 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017113 request.traffic_annotation =
17114 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417115
danakj1fd259a02016-04-16 03:17:0917116 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617117 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417118 // Send headers successfully, but get an error while sending the body.
17119 MockWrite data_writes[] = {
17120 MockWrite("POST / HTTP/1.1\r\n"
17121 "Host: www.foo.com\r\n"
17122 "Connection: keep-alive\r\n"
17123 "Content-Length: 3\r\n\r\n"),
17124 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17125 };
17126
17127 MockRead data_reads[] = {
17128 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
17129 MockRead("hello world"),
17130 MockRead(SYNCHRONOUS, OK),
17131 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117132 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417133 session_deps_.socket_factory->AddSocketDataProvider(&data);
17134
17135 TestCompletionCallback callback;
17136
tfarina42834112016-09-22 13:38:2017137 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117138 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417139
17140 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117141 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417142
bnc691fda62016-08-12 00:43:1617143 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5217144 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5417145
wezca1070932016-05-26 20:30:5217146 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5417147 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
17148
17149 std::string response_data;
bnc691fda62016-08-12 00:43:1617150 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0117151 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417152 EXPECT_EQ("hello world", response_data);
17153}
17154
17155// This test makes sure the retry logic doesn't trigger when reading an error
17156// response from a server that rejected a POST with a CONNECTION_RESET.
bncd16676a2016-07-20 16:23:0117157TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5417158 PostReadsErrorResponseAfterResetOnReusedSocket) {
danakj1fd259a02016-04-16 03:17:0917159 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5417160 MockWrite data_writes[] = {
17161 MockWrite("GET / HTTP/1.1\r\n"
17162 "Host: www.foo.com\r\n"
17163 "Connection: keep-alive\r\n\r\n"),
17164 MockWrite("POST / HTTP/1.1\r\n"
17165 "Host: www.foo.com\r\n"
17166 "Connection: keep-alive\r\n"
17167 "Content-Length: 3\r\n\r\n"),
17168 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17169 };
17170
17171 MockRead data_reads[] = {
17172 MockRead("HTTP/1.1 200 Peachy\r\n"
17173 "Content-Length: 14\r\n\r\n"),
17174 MockRead("first response"),
17175 MockRead("HTTP/1.1 400 Not OK\r\n"
17176 "Content-Length: 15\r\n\r\n"),
17177 MockRead("second response"),
17178 MockRead(SYNCHRONOUS, OK),
17179 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117180 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417181 session_deps_.socket_factory->AddSocketDataProvider(&data);
17182
17183 TestCompletionCallback callback;
17184 HttpRequestInfo request1;
17185 request1.method = "GET";
17186 request1.url = GURL("http://www.foo.com/");
17187 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1017188 request1.traffic_annotation =
17189 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417190
bnc87dcefc2017-05-25 12:47:5817191 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:1917192 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2017193 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117194 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417195
17196 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117197 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417198
17199 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:5217200 ASSERT_TRUE(response1);
[email protected]02d74a02014-04-23 18:10:5417201
wezca1070932016-05-26 20:30:5217202 EXPECT_TRUE(response1->headers);
[email protected]02d74a02014-04-23 18:10:5417203 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
17204
17205 std::string response_data1;
17206 rv = ReadTransaction(trans1.get(), &response_data1);
robpercival214763f2016-07-01 23:27:0117207 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417208 EXPECT_EQ("first response", response_data1);
17209 // Delete the transaction to release the socket back into the socket pool.
17210 trans1.reset();
17211
danakj1fd259a02016-04-16 03:17:0917212 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217213 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917214 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217215 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417216
17217 HttpRequestInfo request2;
17218 request2.method = "POST";
17219 request2.url = GURL("http://www.foo.com/");
17220 request2.upload_data_stream = &upload_data_stream;
17221 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1017222 request2.traffic_annotation =
17223 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417224
bnc691fda62016-08-12 00:43:1617225 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2017226 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117227 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417228
17229 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117230 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417231
bnc691fda62016-08-12 00:43:1617232 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5217233 ASSERT_TRUE(response2);
[email protected]02d74a02014-04-23 18:10:5417234
wezca1070932016-05-26 20:30:5217235 EXPECT_TRUE(response2->headers);
[email protected]02d74a02014-04-23 18:10:5417236 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
17237
17238 std::string response_data2;
bnc691fda62016-08-12 00:43:1617239 rv = ReadTransaction(&trans2, &response_data2);
robpercival214763f2016-07-01 23:27:0117240 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417241 EXPECT_EQ("second response", response_data2);
17242}
17243
bncd16676a2016-07-20 16:23:0117244TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5417245 PostReadsErrorResponseAfterResetPartialBodySent) {
danakj1fd259a02016-04-16 03:17:0917246 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217247 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917248 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217249 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417250
17251 HttpRequestInfo request;
17252 request.method = "POST";
17253 request.url = GURL("http://www.foo.com/");
17254 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017255 request.traffic_annotation =
17256 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417257
danakj1fd259a02016-04-16 03:17:0917258 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617259 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417260 // Send headers successfully, but get an error while sending the body.
17261 MockWrite data_writes[] = {
17262 MockWrite("POST / HTTP/1.1\r\n"
17263 "Host: www.foo.com\r\n"
17264 "Connection: keep-alive\r\n"
17265 "Content-Length: 3\r\n\r\n"
17266 "fo"),
17267 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17268 };
17269
17270 MockRead data_reads[] = {
17271 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
17272 MockRead("hello world"),
17273 MockRead(SYNCHRONOUS, OK),
17274 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117275 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417276 session_deps_.socket_factory->AddSocketDataProvider(&data);
17277
17278 TestCompletionCallback callback;
17279
tfarina42834112016-09-22 13:38:2017280 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117281 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417282
17283 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117284 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417285
bnc691fda62016-08-12 00:43:1617286 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5217287 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5417288
wezca1070932016-05-26 20:30:5217289 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5417290 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
17291
17292 std::string response_data;
bnc691fda62016-08-12 00:43:1617293 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0117294 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417295 EXPECT_EQ("hello world", response_data);
17296}
17297
17298// This tests the more common case than the previous test, where headers and
17299// body are not merged into a single request.
bncd16676a2016-07-20 16:23:0117300TEST_F(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
mmenkecbc2b712014-10-09 20:29:0717301 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5417302
17303 HttpRequestInfo request;
17304 request.method = "POST";
17305 request.url = GURL("http://www.foo.com/");
17306 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017307 request.traffic_annotation =
17308 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417309
danakj1fd259a02016-04-16 03:17:0917310 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617311 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417312 // Send headers successfully, but get an error while sending the body.
17313 MockWrite data_writes[] = {
17314 MockWrite("POST / HTTP/1.1\r\n"
17315 "Host: www.foo.com\r\n"
17316 "Connection: keep-alive\r\n"
17317 "Transfer-Encoding: chunked\r\n\r\n"),
17318 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17319 };
17320
17321 MockRead data_reads[] = {
17322 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
17323 MockRead("hello world"),
17324 MockRead(SYNCHRONOUS, OK),
17325 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117326 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417327 session_deps_.socket_factory->AddSocketDataProvider(&data);
17328
17329 TestCompletionCallback callback;
17330
tfarina42834112016-09-22 13:38:2017331 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117332 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417333 // Make sure the headers are sent before adding a chunk. This ensures that
17334 // they can't be merged with the body in a single send. Not currently
17335 // necessary since a chunked body is never merged with headers, but this makes
17336 // the test more future proof.
17337 base::RunLoop().RunUntilIdle();
17338
mmenkecbc2b712014-10-09 20:29:0717339 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5417340
17341 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117342 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417343
bnc691fda62016-08-12 00:43:1617344 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5217345 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5417346
wezca1070932016-05-26 20:30:5217347 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5417348 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
17349
17350 std::string response_data;
bnc691fda62016-08-12 00:43:1617351 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0117352 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417353 EXPECT_EQ("hello world", response_data);
17354}
17355
bncd16676a2016-07-20 16:23:0117356TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0917357 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217358 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917359 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217360 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417361
17362 HttpRequestInfo request;
17363 request.method = "POST";
17364 request.url = GURL("http://www.foo.com/");
17365 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017366 request.traffic_annotation =
17367 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417368
danakj1fd259a02016-04-16 03:17:0917369 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617370 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417371
17372 MockWrite data_writes[] = {
17373 MockWrite("POST / HTTP/1.1\r\n"
17374 "Host: www.foo.com\r\n"
17375 "Connection: keep-alive\r\n"
17376 "Content-Length: 3\r\n\r\n"),
17377 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17378 };
17379
17380 MockRead data_reads[] = {
17381 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
17382 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
17383 MockRead("hello world"),
17384 MockRead(SYNCHRONOUS, OK),
17385 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117386 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417387 session_deps_.socket_factory->AddSocketDataProvider(&data);
17388
17389 TestCompletionCallback callback;
17390
tfarina42834112016-09-22 13:38:2017391 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117392 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417393
17394 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117395 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417396
bnc691fda62016-08-12 00:43:1617397 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5217398 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5417399
wezca1070932016-05-26 20:30:5217400 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5417401 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
17402
17403 std::string response_data;
bnc691fda62016-08-12 00:43:1617404 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0117405 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417406 EXPECT_EQ("hello world", response_data);
17407}
17408
bncd16676a2016-07-20 16:23:0117409TEST_F(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0917410 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217411 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917412 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217413 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417414
17415 HttpRequestInfo request;
17416 request.method = "POST";
17417 request.url = GURL("http://www.foo.com/");
17418 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017419 request.traffic_annotation =
17420 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417421
danakj1fd259a02016-04-16 03:17:0917422 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617423 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417424 // Send headers successfully, but get an error while sending the body.
17425 MockWrite data_writes[] = {
17426 MockWrite("POST / HTTP/1.1\r\n"
17427 "Host: www.foo.com\r\n"
17428 "Connection: keep-alive\r\n"
17429 "Content-Length: 3\r\n\r\n"),
17430 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17431 };
17432
17433 MockRead data_reads[] = {
17434 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
17435 MockRead("hello world"),
17436 MockRead(SYNCHRONOUS, OK),
17437 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117438 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417439 session_deps_.socket_factory->AddSocketDataProvider(&data);
17440
17441 TestCompletionCallback callback;
17442
tfarina42834112016-09-22 13:38:2017443 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117444 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417445
17446 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117447 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417448}
17449
bncd16676a2016-07-20 16:23:0117450TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5417451 PostIgnoresNonErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0917452 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217453 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917454 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217455 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417456
17457 HttpRequestInfo request;
17458 request.method = "POST";
17459 request.url = GURL("http://www.foo.com/");
17460 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017461 request.traffic_annotation =
17462 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417463
danakj1fd259a02016-04-16 03:17:0917464 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617465 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417466 // Send headers successfully, but get an error while sending the body.
17467 MockWrite data_writes[] = {
17468 MockWrite("POST / HTTP/1.1\r\n"
17469 "Host: www.foo.com\r\n"
17470 "Connection: keep-alive\r\n"
17471 "Content-Length: 3\r\n\r\n"),
17472 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17473 };
17474
17475 MockRead data_reads[] = {
17476 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
17477 MockRead("HTTP/1.0 302 Redirect\r\n"),
17478 MockRead("Location: http://somewhere-else.com/\r\n"),
17479 MockRead("Content-Length: 0\r\n\r\n"),
17480 MockRead(SYNCHRONOUS, OK),
17481 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117482 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417483 session_deps_.socket_factory->AddSocketDataProvider(&data);
17484
17485 TestCompletionCallback callback;
17486
tfarina42834112016-09-22 13:38:2017487 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117488 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417489
17490 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117491 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417492}
17493
bncd16676a2016-07-20 16:23:0117494TEST_F(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0917495 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217496 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917497 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217498 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417499
17500 HttpRequestInfo request;
17501 request.method = "POST";
17502 request.url = GURL("http://www.foo.com/");
17503 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017504 request.traffic_annotation =
17505 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417506
danakj1fd259a02016-04-16 03:17:0917507 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617508 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417509 // Send headers successfully, but get an error while sending the body.
17510 MockWrite data_writes[] = {
17511 MockWrite("POST / HTTP/1.1\r\n"
17512 "Host: www.foo.com\r\n"
17513 "Connection: keep-alive\r\n"
17514 "Content-Length: 3\r\n\r\n"),
17515 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17516 };
17517
17518 MockRead data_reads[] = {
17519 MockRead("HTTP 0.9 rocks!"),
17520 MockRead(SYNCHRONOUS, OK),
17521 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117522 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417523 session_deps_.socket_factory->AddSocketDataProvider(&data);
17524
17525 TestCompletionCallback callback;
17526
tfarina42834112016-09-22 13:38:2017527 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117528 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417529
17530 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117531 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417532}
17533
bncd16676a2016-07-20 16:23:0117534TEST_F(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
danakj1fd259a02016-04-16 03:17:0917535 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217536 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917537 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217538 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417539
17540 HttpRequestInfo request;
17541 request.method = "POST";
17542 request.url = GURL("http://www.foo.com/");
17543 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017544 request.traffic_annotation =
17545 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417546
danakj1fd259a02016-04-16 03:17:0917547 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617548 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417549 // Send headers successfully, but get an error while sending the body.
17550 MockWrite data_writes[] = {
17551 MockWrite("POST / HTTP/1.1\r\n"
17552 "Host: www.foo.com\r\n"
17553 "Connection: keep-alive\r\n"
17554 "Content-Length: 3\r\n\r\n"),
17555 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17556 };
17557
17558 MockRead data_reads[] = {
17559 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
17560 MockRead(SYNCHRONOUS, OK),
17561 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117562 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417563 session_deps_.socket_factory->AddSocketDataProvider(&data);
17564
17565 TestCompletionCallback callback;
17566
tfarina42834112016-09-22 13:38:2017567 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117568 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417569
17570 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117571 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417572}
17573
Bence Békydca6bd92018-01-30 13:43:0617574#if BUILDFLAG(ENABLE_WEBSOCKETS)
17575
17576namespace {
17577
17578void AddWebSocketHeaders(HttpRequestHeaders* headers) {
17579 headers->SetHeader("Connection", "Upgrade");
17580 headers->SetHeader("Upgrade", "websocket");
17581 headers->SetHeader("Origin", "http://www.example.org");
17582 headers->SetHeader("Sec-WebSocket-Version", "13");
Bence Békydca6bd92018-01-30 13:43:0617583}
17584
17585} // namespace
17586
17587TEST_F(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
Bence Béky2fcf4fa2018-04-06 20:06:0117588 for (bool secure : {true, false}) {
17589 MockWrite data_writes[] = {
17590 MockWrite("GET / HTTP/1.1\r\n"
17591 "Host: www.example.org\r\n"
17592 "Connection: Upgrade\r\n"
17593 "Upgrade: websocket\r\n"
17594 "Origin: http://www.example.org\r\n"
17595 "Sec-WebSocket-Version: 13\r\n"
17596 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
17597 "Sec-WebSocket-Extensions: permessage-deflate; "
17598 "client_max_window_bits\r\n\r\n")};
17599
17600 MockRead data_reads[] = {
17601 MockRead("HTTP/1.1 101 Switching Protocols\r\n"
17602 "Upgrade: websocket\r\n"
17603 "Connection: Upgrade\r\n"
17604 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
17605
Ryan Sleevib8d7ea02018-05-07 20:01:0117606 StaticSocketDataProvider data(data_reads, data_writes);
Bence Béky2fcf4fa2018-04-06 20:06:0117607 session_deps_.socket_factory->AddSocketDataProvider(&data);
17608 SSLSocketDataProvider ssl(ASYNC, OK);
17609 if (secure)
17610 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
Bence Békydca6bd92018-01-30 13:43:0617611
17612 HttpRequestInfo request;
17613 request.method = "GET";
Bence Béky2fcf4fa2018-04-06 20:06:0117614 request.url =
17615 GURL(secure ? "ws://www.example.org/" : "wss://www.example.org/");
17616 AddWebSocketHeaders(&request.extra_headers);
Ramin Halavatib5e433e2018-02-07 07:41:1017617 request.traffic_annotation =
17618 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Békydca6bd92018-01-30 13:43:0617619
Bence Béky2fcf4fa2018-04-06 20:06:0117620 TestWebSocketHandshakeStreamCreateHelper
17621 websocket_handshake_stream_create_helper;
Bence Béky8d1c6052018-02-07 12:48:1517622
Bence Béky2fcf4fa2018-04-06 20:06:0117623 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Bence Békydca6bd92018-01-30 13:43:0617624 HttpNetworkTransaction trans(LOW, session.get());
17625 trans.SetWebSocketHandshakeStreamCreateHelper(
Bence Béky2fcf4fa2018-04-06 20:06:0117626 &websocket_handshake_stream_create_helper);
Bence Békydca6bd92018-01-30 13:43:0617627
17628 TestCompletionCallback callback;
Bence Béky2fcf4fa2018-04-06 20:06:0117629 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17630 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Bence Békydca6bd92018-01-30 13:43:0617631
Bence Béky2fcf4fa2018-04-06 20:06:0117632 const HttpStreamRequest* stream_request = trans.stream_request_.get();
17633 ASSERT_TRUE(stream_request);
17634 EXPECT_EQ(&websocket_handshake_stream_create_helper,
17635 stream_request->websocket_handshake_stream_create_helper());
17636
17637 rv = callback.WaitForResult();
17638 EXPECT_THAT(rv, IsOk());
17639
17640 EXPECT_TRUE(data.AllReadDataConsumed());
17641 EXPECT_TRUE(data.AllWriteDataConsumed());
Bence Békydca6bd92018-01-30 13:43:0617642 }
17643}
17644
Adam Rice425cf122015-01-19 06:18:2417645// Verify that proxy headers are not sent to the destination server when
17646// establishing a tunnel for a secure WebSocket connection.
bncd16676a2016-07-20 16:23:0117647TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
Adam Rice425cf122015-01-19 06:18:2417648 HttpRequestInfo request;
17649 request.method = "GET";
bncce36dca22015-04-21 22:11:2317650 request.url = GURL("wss://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017651 request.traffic_annotation =
17652 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417653 AddWebSocketHeaders(&request.extra_headers);
17654
17655 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:5917656 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4917657 ProxyResolutionService::CreateFixedFromPacResult(
17658 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417659
danakj1fd259a02016-04-16 03:17:0917660 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2417661
17662 // Since a proxy is configured, try to establish a tunnel.
17663 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1717664 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
17665 "Host: www.example.org:443\r\n"
17666 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417667
17668 // After calling trans->RestartWithAuth(), this is the request we should
17669 // be issuing -- the final header line contains the credentials.
rsleevidb16bb02015-11-12 23:47:1717670 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
17671 "Host: www.example.org:443\r\n"
17672 "Proxy-Connection: keep-alive\r\n"
17673 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417674
rsleevidb16bb02015-11-12 23:47:1717675 MockWrite("GET / HTTP/1.1\r\n"
17676 "Host: www.example.org\r\n"
17677 "Connection: Upgrade\r\n"
17678 "Upgrade: websocket\r\n"
17679 "Origin: http://www.example.org\r\n"
17680 "Sec-WebSocket-Version: 13\r\n"
Bence Béky8d1c6052018-02-07 12:48:1517681 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
17682 "Sec-WebSocket-Extensions: permessage-deflate; "
17683 "client_max_window_bits\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417684
17685 // The proxy responds to the connect with a 407, using a persistent
17686 // connection.
17687 MockRead data_reads[] = {
17688 // No credentials.
Bence Béky8d1c6052018-02-07 12:48:1517689 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"
17690 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
17691 "Content-Length: 0\r\n"
17692 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417693
17694 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
17695
Bence Béky8d1c6052018-02-07 12:48:1517696 MockRead("HTTP/1.1 101 Switching Protocols\r\n"
17697 "Upgrade: websocket\r\n"
17698 "Connection: Upgrade\r\n"
17699 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417700
Ryan Sleevib8d7ea02018-05-07 20:01:0117701 StaticSocketDataProvider data(data_reads, data_writes);
Adam Rice425cf122015-01-19 06:18:2417702 session_deps_.socket_factory->AddSocketDataProvider(&data);
17703 SSLSocketDataProvider ssl(ASYNC, OK);
17704 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
17705
Bence Béky8d1c6052018-02-07 12:48:1517706 TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
17707
bnc87dcefc2017-05-25 12:47:5817708 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917709 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2417710 trans->SetWebSocketHandshakeStreamCreateHelper(
17711 &websocket_stream_create_helper);
17712
17713 {
17714 TestCompletionCallback callback;
17715
tfarina42834112016-09-22 13:38:2017716 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117717 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2417718
17719 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117720 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2417721 }
17722
17723 const HttpResponseInfo* response = trans->GetResponseInfo();
17724 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5217725 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2417726 EXPECT_EQ(407, response->headers->response_code());
17727
17728 {
17729 TestCompletionCallback callback;
17730
17731 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
17732 callback.callback());
robpercival214763f2016-07-01 23:27:0117733 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2417734
17735 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117736 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2417737 }
17738
17739 response = trans->GetResponseInfo();
17740 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5217741 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2417742
17743 EXPECT_EQ(101, response->headers->response_code());
17744
17745 trans.reset();
17746 session->CloseAllConnections();
17747}
17748
17749// Verify that proxy headers are not sent to the destination server when
17750// establishing a tunnel for an insecure WebSocket connection.
17751// This requires the authentication info to be injected into the auth cache
17752// due to crbug.com/395064
17753// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
bncd16676a2016-07-20 16:23:0117754TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
Adam Rice425cf122015-01-19 06:18:2417755 HttpRequestInfo request;
17756 request.method = "GET";
bncce36dca22015-04-21 22:11:2317757 request.url = GURL("ws://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017758 request.traffic_annotation =
17759 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417760 AddWebSocketHeaders(&request.extra_headers);
17761
17762 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:5917763 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4917764 ProxyResolutionService::CreateFixedFromPacResult(
17765 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417766
danakj1fd259a02016-04-16 03:17:0917767 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2417768
17769 MockWrite data_writes[] = {
17770 // Try to establish a tunnel for the WebSocket connection, with
17771 // credentials. Because WebSockets have a separate set of socket pools,
17772 // they cannot and will not use the same TCP/IP connection as the
17773 // preflight HTTP request.
Bence Béky8d1c6052018-02-07 12:48:1517774 MockWrite("CONNECT www.example.org:80 HTTP/1.1\r\n"
17775 "Host: www.example.org:80\r\n"
17776 "Proxy-Connection: keep-alive\r\n"
17777 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417778
Bence Béky8d1c6052018-02-07 12:48:1517779 MockWrite("GET / HTTP/1.1\r\n"
17780 "Host: www.example.org\r\n"
17781 "Connection: Upgrade\r\n"
17782 "Upgrade: websocket\r\n"
17783 "Origin: http://www.example.org\r\n"
17784 "Sec-WebSocket-Version: 13\r\n"
17785 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
17786 "Sec-WebSocket-Extensions: permessage-deflate; "
17787 "client_max_window_bits\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417788
17789 MockRead data_reads[] = {
17790 // HTTP CONNECT with credentials.
17791 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
17792
17793 // WebSocket connection established inside tunnel.
Bence Béky8d1c6052018-02-07 12:48:1517794 MockRead("HTTP/1.1 101 Switching Protocols\r\n"
17795 "Upgrade: websocket\r\n"
17796 "Connection: Upgrade\r\n"
17797 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417798
Ryan Sleevib8d7ea02018-05-07 20:01:0117799 StaticSocketDataProvider data(data_reads, data_writes);
Adam Rice425cf122015-01-19 06:18:2417800 session_deps_.socket_factory->AddSocketDataProvider(&data);
17801
17802 session->http_auth_cache()->Add(
17803 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
17804 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
17805
Bence Béky8d1c6052018-02-07 12:48:1517806 TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
17807
bnc87dcefc2017-05-25 12:47:5817808 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917809 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2417810 trans->SetWebSocketHandshakeStreamCreateHelper(
17811 &websocket_stream_create_helper);
17812
17813 TestCompletionCallback callback;
17814
tfarina42834112016-09-22 13:38:2017815 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117816 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2417817
17818 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117819 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2417820
17821 const HttpResponseInfo* response = trans->GetResponseInfo();
17822 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5217823 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2417824
17825 EXPECT_EQ(101, response->headers->response_code());
17826
17827 trans.reset();
17828 session->CloseAllConnections();
17829}
17830
Bence Békydca6bd92018-01-30 13:43:0617831#endif // BUILDFLAG(ENABLE_WEBSOCKETS)
17832
bncd16676a2016-07-20 16:23:0117833TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost) {
danakj1fd259a02016-04-16 03:17:0917834 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217835 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917836 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217837 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2217838
17839 HttpRequestInfo request;
17840 request.method = "POST";
17841 request.url = GURL("http://www.foo.com/");
17842 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017843 request.traffic_annotation =
17844 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2217845
danakj1fd259a02016-04-16 03:17:0917846 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617847 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2217848 MockWrite data_writes[] = {
17849 MockWrite("POST / HTTP/1.1\r\n"
17850 "Host: www.foo.com\r\n"
17851 "Connection: keep-alive\r\n"
17852 "Content-Length: 3\r\n\r\n"),
17853 MockWrite("foo"),
17854 };
17855
17856 MockRead data_reads[] = {
17857 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
17858 MockRead(SYNCHRONOUS, OK),
17859 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117860 StaticSocketDataProvider data(data_reads, data_writes);
sclittlefb249892015-09-10 21:33:2217861 session_deps_.socket_factory->AddSocketDataProvider(&data);
17862
17863 TestCompletionCallback callback;
17864
17865 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017866 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0117867 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2217868
17869 std::string response_data;
bnc691fda62016-08-12 00:43:1617870 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2217871
Ryan Sleevib8d7ea02018-05-07 20:01:0117872 EXPECT_EQ(CountWriteBytes(data_writes), trans.GetTotalSentBytes());
17873 EXPECT_EQ(CountReadBytes(data_reads), trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2217874}
17875
bncd16676a2016-07-20 16:23:0117876TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost100Continue) {
danakj1fd259a02016-04-16 03:17:0917877 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217878 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917879 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217880 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2217881
17882 HttpRequestInfo request;
17883 request.method = "POST";
17884 request.url = GURL("http://www.foo.com/");
17885 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017886 request.traffic_annotation =
17887 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2217888
danakj1fd259a02016-04-16 03:17:0917889 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617890 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2217891 MockWrite data_writes[] = {
17892 MockWrite("POST / HTTP/1.1\r\n"
17893 "Host: www.foo.com\r\n"
17894 "Connection: keep-alive\r\n"
17895 "Content-Length: 3\r\n\r\n"),
17896 MockWrite("foo"),
17897 };
17898
17899 MockRead data_reads[] = {
17900 MockRead("HTTP/1.1 100 Continue\r\n\r\n"),
17901 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
17902 MockRead(SYNCHRONOUS, OK),
17903 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117904 StaticSocketDataProvider data(data_reads, data_writes);
sclittlefb249892015-09-10 21:33:2217905 session_deps_.socket_factory->AddSocketDataProvider(&data);
17906
17907 TestCompletionCallback callback;
17908
17909 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017910 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0117911 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2217912
17913 std::string response_data;
bnc691fda62016-08-12 00:43:1617914 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2217915
Ryan Sleevib8d7ea02018-05-07 20:01:0117916 EXPECT_EQ(CountWriteBytes(data_writes), trans.GetTotalSentBytes());
17917 EXPECT_EQ(CountReadBytes(data_reads), trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2217918}
17919
bncd16676a2016-07-20 16:23:0117920TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) {
sclittlefb249892015-09-10 21:33:2217921 ChunkedUploadDataStream upload_data_stream(0);
17922
17923 HttpRequestInfo request;
17924 request.method = "POST";
17925 request.url = GURL("http://www.foo.com/");
17926 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017927 request.traffic_annotation =
17928 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2217929
danakj1fd259a02016-04-16 03:17:0917930 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617931 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2217932 // Send headers successfully, but get an error while sending the body.
17933 MockWrite data_writes[] = {
17934 MockWrite("POST / HTTP/1.1\r\n"
17935 "Host: www.foo.com\r\n"
17936 "Connection: keep-alive\r\n"
17937 "Transfer-Encoding: chunked\r\n\r\n"),
17938 MockWrite("1\r\nf\r\n"), MockWrite("2\r\noo\r\n"), MockWrite("0\r\n\r\n"),
17939 };
17940
17941 MockRead data_reads[] = {
17942 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
17943 MockRead(SYNCHRONOUS, OK),
17944 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117945 StaticSocketDataProvider data(data_reads, data_writes);
sclittlefb249892015-09-10 21:33:2217946 session_deps_.socket_factory->AddSocketDataProvider(&data);
17947
17948 TestCompletionCallback callback;
17949
17950 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017951 trans.Start(&request, callback.callback(), NetLogWithSource()));
sclittlefb249892015-09-10 21:33:2217952
17953 base::RunLoop().RunUntilIdle();
17954 upload_data_stream.AppendData("f", 1, false);
17955
17956 base::RunLoop().RunUntilIdle();
17957 upload_data_stream.AppendData("oo", 2, true);
17958
robpercival214763f2016-07-01 23:27:0117959 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2217960
17961 std::string response_data;
bnc691fda62016-08-12 00:43:1617962 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2217963
Ryan Sleevib8d7ea02018-05-07 20:01:0117964 EXPECT_EQ(CountWriteBytes(data_writes), trans.GetTotalSentBytes());
17965 EXPECT_EQ(CountReadBytes(data_reads), trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2217966}
17967
eustasc7d27da2017-04-06 10:33:2017968void CheckContentEncodingMatching(SpdySessionDependencies* session_deps,
17969 const std::string& accept_encoding,
17970 const std::string& content_encoding,
sky50576f32017-05-01 19:28:0317971 const std::string& location,
eustasc7d27da2017-04-06 10:33:2017972 bool should_match) {
17973 HttpRequestInfo request;
17974 request.method = "GET";
17975 request.url = GURL("http://www.foo.com/");
17976 request.extra_headers.SetHeader(HttpRequestHeaders::kAcceptEncoding,
17977 accept_encoding);
Ramin Halavatib5e433e2018-02-07 07:41:1017978 request.traffic_annotation =
17979 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
eustasc7d27da2017-04-06 10:33:2017980
17981 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps));
17982 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17983 // Send headers successfully, but get an error while sending the body.
17984 MockWrite data_writes[] = {
17985 MockWrite("GET / HTTP/1.1\r\n"
17986 "Host: www.foo.com\r\n"
17987 "Connection: keep-alive\r\n"
17988 "Accept-Encoding: "),
17989 MockWrite(accept_encoding.data()), MockWrite("\r\n\r\n"),
17990 };
17991
sky50576f32017-05-01 19:28:0317992 std::string response_code = "200 OK";
17993 std::string extra;
17994 if (!location.empty()) {
17995 response_code = "301 Redirect\r\nLocation: ";
17996 response_code.append(location);
17997 }
17998
eustasc7d27da2017-04-06 10:33:2017999 MockRead data_reads[] = {
sky50576f32017-05-01 19:28:0318000 MockRead("HTTP/1.0 "),
18001 MockRead(response_code.data()),
18002 MockRead("\r\nContent-Encoding: "),
18003 MockRead(content_encoding.data()),
18004 MockRead("\r\n\r\n"),
eustasc7d27da2017-04-06 10:33:2018005 MockRead(SYNCHRONOUS, OK),
18006 };
Ryan Sleevib8d7ea02018-05-07 20:01:0118007 StaticSocketDataProvider data(data_reads, data_writes);
eustasc7d27da2017-04-06 10:33:2018008 session_deps->socket_factory->AddSocketDataProvider(&data);
18009
18010 TestCompletionCallback callback;
18011
18012 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18013 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18014
18015 rv = callback.WaitForResult();
18016 if (should_match) {
18017 EXPECT_THAT(rv, IsOk());
18018 } else {
18019 EXPECT_THAT(rv, IsError(ERR_CONTENT_DECODING_FAILED));
18020 }
18021}
18022
18023TEST_F(HttpNetworkTransactionTest, MatchContentEncoding1) {
sky50576f32017-05-01 19:28:0318024 CheckContentEncodingMatching(&session_deps_, "gzip,sdch", "br", "", false);
eustasc7d27da2017-04-06 10:33:2018025}
18026
18027TEST_F(HttpNetworkTransactionTest, MatchContentEncoding2) {
sky50576f32017-05-01 19:28:0318028 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "", "",
18029 true);
eustasc7d27da2017-04-06 10:33:2018030}
18031
18032TEST_F(HttpNetworkTransactionTest, MatchContentEncoding3) {
18033 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
sky50576f32017-05-01 19:28:0318034 "", false);
18035}
18036
18037TEST_F(HttpNetworkTransactionTest, MatchContentEncoding4) {
18038 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
18039 "www.foo.com/other", true);
eustasc7d27da2017-04-06 10:33:2018040}
18041
xunjieli96f2a402017-06-05 17:24:2718042TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsSync) {
18043 ProxyConfig proxy_config;
18044 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
18045 proxy_config.set_pac_mandatory(true);
18046 MockAsyncProxyResolver resolver;
Lily Houghton8c2f97d2018-01-22 05:06:5918047 session_deps_.proxy_resolution_service.reset(new ProxyResolutionService(
Ramin Halavatica8d5252018-03-12 05:33:4918048 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
18049 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
Bence Béky8f9d7d3952017-10-09 19:58:0418050 std::make_unique<FailingProxyResolverFactory>(), nullptr));
xunjieli96f2a402017-06-05 17:24:2718051
18052 HttpRequestInfo request;
18053 request.method = "GET";
18054 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1018055 request.traffic_annotation =
18056 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2718057
18058 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18059 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18060
18061 TestCompletionCallback callback;
18062
18063 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18064 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18065 EXPECT_THAT(callback.WaitForResult(),
18066 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
18067}
18068
18069TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsAsync) {
18070 ProxyConfig proxy_config;
18071 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
18072 proxy_config.set_pac_mandatory(true);
18073 MockAsyncProxyResolverFactory* proxy_resolver_factory =
18074 new MockAsyncProxyResolverFactory(false);
18075 MockAsyncProxyResolver resolver;
Lily Houghton8c2f97d2018-01-22 05:06:5918076 session_deps_.proxy_resolution_service.reset(new ProxyResolutionService(
Ramin Halavatica8d5252018-03-12 05:33:4918077 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
18078 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
Lily Houghton8c2f97d2018-01-22 05:06:5918079 base::WrapUnique(proxy_resolver_factory), nullptr));
xunjieli96f2a402017-06-05 17:24:2718080 HttpRequestInfo request;
18081 request.method = "GET";
18082 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1018083 request.traffic_annotation =
18084 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2718085
18086 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18087 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18088
18089 TestCompletionCallback callback;
18090 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18091 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18092
18093 proxy_resolver_factory->pending_requests()[0]->CompleteNowWithForwarder(
18094 ERR_FAILED, &resolver);
18095 EXPECT_THAT(callback.WaitForResult(),
18096 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
18097}
18098
18099TEST_F(HttpNetworkTransactionTest, NoSupportedProxies) {
Lily Houghton8c2f97d2018-01-22 05:06:5918100 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4918101 ProxyResolutionService::CreateFixedFromPacResult(
18102 "QUIC myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2718103 session_deps_.enable_quic = false;
18104 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18105
18106 HttpRequestInfo request;
18107 request.method = "GET";
18108 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1018109 request.traffic_annotation =
18110 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2718111
18112 TestCompletionCallback callback;
18113 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18114 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18115 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18116
18117 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NO_SUPPORTED_PROXIES));
18118}
18119
Douglas Creager3cb042052018-11-06 23:08:5218120//-----------------------------------------------------------------------------
Douglas Creager134b52e2018-11-09 18:00:1418121// Reporting tests
18122
18123#if BUILDFLAG(ENABLE_REPORTING)
18124class HttpNetworkTransactionReportingTest : public HttpNetworkTransactionTest {
18125 protected:
18126 void SetUp() override {
Douglas Creageref5eecdc2018-11-09 20:50:3618127 HttpNetworkTransactionTest::SetUp();
Douglas Creager134b52e2018-11-09 18:00:1418128 auto test_reporting_context = std::make_unique<TestReportingContext>(
18129 &clock_, &tick_clock_, ReportingPolicy());
18130 test_reporting_context_ = test_reporting_context.get();
18131 session_deps_.reporting_service =
18132 ReportingService::CreateForTesting(std::move(test_reporting_context));
18133 }
18134
18135 TestReportingContext* reporting_context() const {
18136 return test_reporting_context_;
18137 }
18138
18139 void clear_reporting_service() {
18140 session_deps_.reporting_service.reset();
18141 test_reporting_context_ = nullptr;
18142 }
18143
18144 // Makes an HTTPS request that should install a valid Reporting policy.
Lily Chenfec60d92019-01-24 01:16:4218145 void RequestPolicy(CertStatus cert_status = 0) {
18146 HttpRequestInfo request;
18147 request.method = "GET";
18148 request.url = GURL(url_);
18149 request.traffic_annotation =
18150 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
18151
Douglas Creager134b52e2018-11-09 18:00:1418152 MockRead data_reads[] = {
18153 MockRead("HTTP/1.0 200 OK\r\n"),
18154 MockRead("Report-To: {\"group\": \"nel\", \"max_age\": 86400, "
18155 "\"endpoints\": [{\"url\": "
18156 "\"https://www.example.org/upload/\"}]}\r\n"),
18157 MockRead("\r\n"),
18158 MockRead("hello world"),
18159 MockRead(SYNCHRONOUS, OK),
18160 };
18161 MockWrite data_writes[] = {
18162 MockWrite("GET / HTTP/1.1\r\n"
18163 "Host: www.example.org\r\n"
18164 "Connection: keep-alive\r\n\r\n"),
18165 };
18166
Lily Chenfec60d92019-01-24 01:16:4218167 StaticSocketDataProvider reads(data_reads, data_writes);
18168 session_deps_.socket_factory->AddSocketDataProvider(&reads);
Douglas Creager134b52e2018-11-09 18:00:1418169
18170 SSLSocketDataProvider ssl(ASYNC, OK);
18171 if (request.url.SchemeIsCryptographic()) {
18172 ssl.ssl_info.cert =
18173 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
18174 ASSERT_TRUE(ssl.ssl_info.cert);
Lily Chenfec60d92019-01-24 01:16:4218175 ssl.ssl_info.cert_status = cert_status;
Douglas Creager134b52e2018-11-09 18:00:1418176 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
18177 }
18178
Douglas Creager134b52e2018-11-09 18:00:1418179 TestCompletionCallback callback;
18180 auto session = CreateSession(&session_deps_);
18181 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18182 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
Lily Chenfec60d92019-01-24 01:16:4218183 EXPECT_THAT(callback.GetResult(rv), IsOk());
Douglas Creager134b52e2018-11-09 18:00:1418184 }
18185
18186 protected:
18187 std::string url_ = "https://www.example.org/";
Douglas Creager134b52e2018-11-09 18:00:1418188
18189 private:
18190 TestReportingContext* test_reporting_context_;
18191};
18192
18193TEST_F(HttpNetworkTransactionReportingTest,
18194 DontProcessReportToHeaderNoService) {
18195 base::HistogramTester histograms;
18196 clear_reporting_service();
18197 RequestPolicy();
18198 histograms.ExpectBucketCount(
18199 ReportingHeaderParser::kHeaderOutcomeHistogram,
18200 ReportingHeaderParser::HeaderOutcome::DISCARDED_NO_REPORTING_SERVICE, 1);
18201}
18202
18203TEST_F(HttpNetworkTransactionReportingTest, DontProcessReportToHeaderHttp) {
18204 base::HistogramTester histograms;
18205 url_ = "http://www.example.org/";
18206 RequestPolicy();
18207 histograms.ExpectBucketCount(
18208 ReportingHeaderParser::kHeaderOutcomeHistogram,
18209 ReportingHeaderParser::HeaderOutcome::DISCARDED_INVALID_SSL_INFO, 1);
18210}
18211
18212TEST_F(HttpNetworkTransactionReportingTest, ProcessReportToHeaderHttps) {
18213 RequestPolicy();
18214 std::vector<const ReportingClient*> clients;
18215 reporting_context()->cache()->GetClients(&clients);
18216 ASSERT_EQ(1u, clients.size());
18217 const auto* client = clients[0];
18218 EXPECT_EQ(url::Origin::Create(GURL("https://www.example.org/")),
18219 client->origin);
18220 EXPECT_EQ(GURL("https://www.example.org/upload/"), client->endpoint);
18221 EXPECT_EQ("nel", client->group);
18222}
18223
18224TEST_F(HttpNetworkTransactionReportingTest,
18225 DontProcessReportToHeaderInvalidHttps) {
18226 base::HistogramTester histograms;
Lily Chenfec60d92019-01-24 01:16:4218227 CertStatus cert_status = CERT_STATUS_COMMON_NAME_INVALID;
18228 RequestPolicy(cert_status);
Douglas Creager134b52e2018-11-09 18:00:1418229 histograms.ExpectBucketCount(
18230 ReportingHeaderParser::kHeaderOutcomeHistogram,
18231 ReportingHeaderParser::HeaderOutcome::DISCARDED_CERT_STATUS_ERROR, 1);
18232}
18233#endif // BUILDFLAG(ENABLE_REPORTING)
18234
18235//-----------------------------------------------------------------------------
Douglas Creager3cb042052018-11-06 23:08:5218236// Network Error Logging tests
18237
18238#if BUILDFLAG(ENABLE_REPORTING)
Lily Chenfec60d92019-01-24 01:16:4218239namespace {
18240
18241const char kUserAgent[] = "Mozilla/1.0";
18242const char kReferrer[] = "https://www.referrer.org/";
18243
18244} // namespace
18245
Douglas Creager3cb042052018-11-06 23:08:5218246class HttpNetworkTransactionNetworkErrorLoggingTest
18247 : public HttpNetworkTransactionTest {
18248 protected:
18249 void SetUp() override {
Douglas Creageref5eecdc2018-11-09 20:50:3618250 HttpNetworkTransactionTest::SetUp();
Douglas Creager3cb042052018-11-06 23:08:5218251 auto network_error_logging_service =
18252 std::make_unique<TestNetworkErrorLoggingService>();
18253 test_network_error_logging_service_ = network_error_logging_service.get();
18254 session_deps_.network_error_logging_service =
18255 std::move(network_error_logging_service);
Lily Chenfec60d92019-01-24 01:16:4218256
18257 extra_headers_.SetHeader("User-Agent", kUserAgent);
18258 extra_headers_.SetHeader("Referer", kReferrer);
18259
18260 request_.method = "GET";
18261 request_.url = GURL(url_);
18262 request_.extra_headers = extra_headers_;
18263 request_.reporting_upload_depth = reporting_upload_depth_;
18264 request_.traffic_annotation =
18265 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Douglas Creager3cb042052018-11-06 23:08:5218266 }
18267
18268 TestNetworkErrorLoggingService* network_error_logging_service() const {
18269 return test_network_error_logging_service_;
18270 }
18271
18272 void clear_network_error_logging_service() {
18273 session_deps_.network_error_logging_service.reset();
18274 test_network_error_logging_service_ = nullptr;
18275 }
18276
18277 // Makes an HTTPS request that should install a valid NEL policy.
Lily Chenfec60d92019-01-24 01:16:4218278 void RequestPolicy(CertStatus cert_status = 0) {
Douglas Creageref5eecdc2018-11-09 20:50:3618279 std::string extra_header_string = extra_headers_.ToString();
Douglas Creager3cb042052018-11-06 23:08:5218280 MockRead data_reads[] = {
18281 MockRead("HTTP/1.0 200 OK\r\n"),
18282 MockRead("NEL: {\"report_to\": \"nel\", \"max_age\": 86400}\r\n"),
18283 MockRead("\r\n"),
18284 MockRead("hello world"),
18285 MockRead(SYNCHRONOUS, OK),
18286 };
18287 MockWrite data_writes[] = {
18288 MockWrite("GET / HTTP/1.1\r\n"
18289 "Host: www.example.org\r\n"
Douglas Creageref5eecdc2018-11-09 20:50:3618290 "Connection: keep-alive\r\n"),
18291 MockWrite(ASYNC, extra_header_string.data(),
18292 extra_header_string.size()),
Douglas Creager3cb042052018-11-06 23:08:5218293 };
18294
Lily Chenfec60d92019-01-24 01:16:4218295 StaticSocketDataProvider reads(data_reads, data_writes);
18296 session_deps_.socket_factory->AddSocketDataProvider(&reads);
Douglas Creager3cb042052018-11-06 23:08:5218297
18298 SSLSocketDataProvider ssl(ASYNC, OK);
Lily Chenfec60d92019-01-24 01:16:4218299 if (request_.url.SchemeIsCryptographic()) {
Douglas Creager3cb042052018-11-06 23:08:5218300 ssl.ssl_info.cert =
18301 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
18302 ASSERT_TRUE(ssl.ssl_info.cert);
Lily Chenfec60d92019-01-24 01:16:4218303 ssl.ssl_info.cert_status = cert_status;
Douglas Creager3cb042052018-11-06 23:08:5218304 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
18305 }
18306
Douglas Creager3cb042052018-11-06 23:08:5218307 TestCompletionCallback callback;
18308 auto session = CreateSession(&session_deps_);
18309 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
Lily Chenfec60d92019-01-24 01:16:4218310 int rv = trans.Start(&request_, callback.callback(), NetLogWithSource());
18311 EXPECT_THAT(callback.GetResult(rv), IsOk());
18312
18313 std::string response_data;
18314 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
18315 EXPECT_EQ("hello world", response_data);
18316 }
18317
18318 void CheckReport(size_t index,
18319 int status_code,
18320 int error_type,
18321 IPAddress server_ip = IPAddress::IPv4Localhost()) {
18322 ASSERT_LT(index, network_error_logging_service()->errors().size());
18323
18324 const NetworkErrorLoggingService::RequestDetails& error =
18325 network_error_logging_service()->errors()[index];
18326 EXPECT_EQ(url_, error.uri);
18327 EXPECT_EQ(kReferrer, error.referrer);
18328 EXPECT_EQ(kUserAgent, error.user_agent);
18329 EXPECT_EQ(server_ip, error.server_ip);
18330 EXPECT_EQ("http/1.1", error.protocol);
18331 EXPECT_EQ("GET", error.method);
18332 EXPECT_EQ(status_code, error.status_code);
18333 EXPECT_EQ(error_type, error.type);
18334 EXPECT_EQ(0, error.reporting_upload_depth);
Douglas Creager3cb042052018-11-06 23:08:5218335 }
18336
18337 protected:
18338 std::string url_ = "https://www.example.org/";
18339 CertStatus cert_status_ = 0;
Lily Chenfec60d92019-01-24 01:16:4218340 HttpRequestInfo request_;
Douglas Creageref5eecdc2018-11-09 20:50:3618341 HttpRequestHeaders extra_headers_;
18342 int reporting_upload_depth_ = 0;
Douglas Creager3cb042052018-11-06 23:08:5218343
18344 private:
18345 TestNetworkErrorLoggingService* test_network_error_logging_service_;
18346};
18347
18348TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18349 DontProcessNelHeaderNoService) {
18350 base::HistogramTester histograms;
18351 clear_network_error_logging_service();
18352 RequestPolicy();
18353 histograms.ExpectBucketCount(
18354 NetworkErrorLoggingService::kHeaderOutcomeHistogram,
18355 NetworkErrorLoggingService::HeaderOutcome::
18356 DISCARDED_NO_NETWORK_ERROR_LOGGING_SERVICE,
18357 1);
18358}
18359
18360TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18361 DontProcessNelHeaderHttp) {
18362 base::HistogramTester histograms;
18363 url_ = "http://www.example.org/";
Lily Chenfec60d92019-01-24 01:16:4218364 request_.url = GURL(url_);
Douglas Creager3cb042052018-11-06 23:08:5218365 RequestPolicy();
18366 histograms.ExpectBucketCount(
18367 NetworkErrorLoggingService::kHeaderOutcomeHistogram,
18368 NetworkErrorLoggingService::HeaderOutcome::DISCARDED_INVALID_SSL_INFO, 1);
18369}
18370
18371TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, ProcessNelHeaderHttps) {
18372 RequestPolicy();
18373 ASSERT_EQ(1u, network_error_logging_service()->headers().size());
18374 const auto& header = network_error_logging_service()->headers()[0];
18375 EXPECT_EQ(url::Origin::Create(GURL("https://www.example.org/")),
18376 header.origin);
18377 EXPECT_EQ(IPAddress::IPv4Localhost(), header.received_ip_address);
18378 EXPECT_EQ("{\"report_to\": \"nel\", \"max_age\": 86400}", header.value);
18379}
18380
18381TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18382 DontProcessNelHeaderInvalidHttps) {
18383 base::HistogramTester histograms;
Lily Chenfec60d92019-01-24 01:16:4218384 CertStatus cert_status = CERT_STATUS_COMMON_NAME_INVALID;
18385 RequestPolicy(cert_status);
Douglas Creager3cb042052018-11-06 23:08:5218386 histograms.ExpectBucketCount(
18387 NetworkErrorLoggingService::kHeaderOutcomeHistogram,
18388 NetworkErrorLoggingService::HeaderOutcome::DISCARDED_CERT_STATUS_ERROR,
18389 1);
18390}
Douglas Creageref5eecdc2018-11-09 20:50:3618391
Lily Chenfec60d92019-01-24 01:16:4218392TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, CreateReportSuccess) {
Douglas Creageref5eecdc2018-11-09 20:50:3618393 RequestPolicy();
18394 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
Lily Chenfec60d92019-01-24 01:16:4218395 CheckReport(0 /* index */, 200 /* status_code */, OK);
18396}
18397
18398TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18399 CreateReportErrorAfterStart) {
18400 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18401 auto trans =
18402 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18403
18404 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
18405 StaticSocketDataProvider data;
18406 data.set_connect_data(mock_connect);
18407 session_deps_.socket_factory->AddSocketDataProvider(&data);
18408
18409 TestCompletionCallback callback;
18410
18411 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
18412 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_NAME_NOT_RESOLVED));
18413
18414 trans.reset();
18415
18416 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18417 CheckReport(0 /* index */, 0 /* status_code */, ERR_NAME_NOT_RESOLVED,
18418 IPAddress() /* server_ip */);
18419}
18420
18421// Same as above except the error is ASYNC
18422TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18423 CreateReportErrorAfterStartAsync) {
18424 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18425 auto trans =
18426 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18427
18428 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
18429 StaticSocketDataProvider data;
18430 data.set_connect_data(mock_connect);
18431 session_deps_.socket_factory->AddSocketDataProvider(&data);
18432
18433 TestCompletionCallback callback;
18434
18435 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
18436 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_NAME_NOT_RESOLVED));
18437
18438 trans.reset();
18439
18440 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18441 CheckReport(0 /* index */, 0 /* status_code */, ERR_NAME_NOT_RESOLVED,
18442 IPAddress() /* server_ip */);
18443}
18444
18445TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18446 CreateReportReadBodyError) {
18447 std::string extra_header_string = extra_headers_.ToString();
18448 MockRead data_reads[] = {
18449 MockRead("HTTP/1.0 200 OK\r\n"),
18450 MockRead("Content-Length: 100\r\n\r\n"), // wrong content length
18451 MockRead("hello world"),
18452 MockRead(SYNCHRONOUS, OK),
18453 };
18454 MockWrite data_writes[] = {
18455 MockWrite("GET / HTTP/1.1\r\n"
18456 "Host: www.example.org\r\n"
18457 "Connection: keep-alive\r\n"),
18458 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18459 };
18460
18461 StaticSocketDataProvider reads(data_reads, data_writes);
18462 session_deps_.socket_factory->AddSocketDataProvider(&reads);
18463
18464 SSLSocketDataProvider ssl(ASYNC, OK);
18465 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
18466
18467 // Log start time
18468 base::TimeTicks start_time = base::TimeTicks::Now();
18469
18470 TestCompletionCallback callback;
18471 auto session = CreateSession(&session_deps_);
18472 auto trans =
18473 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18474 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
18475 EXPECT_THAT(callback.GetResult(rv), IsOk());
18476
18477 const HttpResponseInfo* response = trans->GetResponseInfo();
18478 ASSERT_TRUE(response);
18479
18480 EXPECT_TRUE(response->headers);
18481 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
18482
18483 std::string response_data;
18484 rv = ReadTransaction(trans.get(), &response_data);
18485 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
18486
18487 trans.reset();
18488
18489 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18490
18491 CheckReport(0 /* index */, 200 /* status_code */,
18492 ERR_CONTENT_LENGTH_MISMATCH);
18493 const NetworkErrorLoggingService::RequestDetails& error =
18494 network_error_logging_service()->errors()[0];
18495 EXPECT_LE(error.elapsed_time, base::TimeTicks::Now() - start_time);
18496}
18497
18498// Same as above except the final read is ASYNC.
18499TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18500 CreateReportReadBodyErrorAsync) {
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(ASYNC, 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
18552TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18553 CreateReportRestartWithAuth) {
18554 std::string extra_header_string = extra_headers_.ToString();
18555 static const base::TimeDelta kSleepDuration =
18556 base::TimeDelta::FromMilliseconds(10);
18557
18558 MockWrite data_writes1[] = {
18559 MockWrite("GET / HTTP/1.1\r\n"
18560 "Host: www.example.org\r\n"
18561 "Connection: keep-alive\r\n"),
18562 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18563 };
18564
18565 MockRead data_reads1[] = {
18566 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
18567 // Give a couple authenticate options (only the middle one is actually
18568 // supported).
18569 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
18570 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
18571 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
18572 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
18573 // Large content-length -- won't matter, as connection will be reset.
18574 MockRead("Content-Length: 10000\r\n\r\n"),
18575 MockRead(SYNCHRONOUS, ERR_FAILED),
18576 };
18577
18578 // After calling trans->RestartWithAuth(), this is the request we should
18579 // be issuing -- the final header line contains the credentials.
18580 MockWrite data_writes2[] = {
18581 MockWrite("GET / HTTP/1.1\r\n"
18582 "Host: www.example.org\r\n"
18583 "Connection: keep-alive\r\n"
18584 "Authorization: Basic Zm9vOmJhcg==\r\n"),
18585 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18586 };
18587
18588 // Lastly, the server responds with the actual content.
18589 MockRead data_reads2[] = {
18590 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
18591 MockRead("hello world"),
18592 MockRead(SYNCHRONOUS, OK),
18593 };
18594
18595 StaticSocketDataProvider data1(data_reads1, data_writes1);
18596 StaticSocketDataProvider data2(data_reads2, data_writes2);
18597 session_deps_.socket_factory->AddSocketDataProvider(&data1);
18598 session_deps_.socket_factory->AddSocketDataProvider(&data2);
18599
18600 SSLSocketDataProvider ssl1(ASYNC, OK);
18601 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
18602 SSLSocketDataProvider ssl2(ASYNC, OK);
18603 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
18604
18605 base::TimeTicks start_time = base::TimeTicks::Now();
18606 base::TimeTicks restart_time;
18607
18608 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18609 auto trans =
18610 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18611
18612 TestCompletionCallback callback1;
18613
18614 int rv = trans->Start(&request_, callback1.callback(), NetLogWithSource());
18615 EXPECT_THAT(callback1.GetResult(rv), IsOk());
18616
18617 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18618
18619 TestCompletionCallback callback2;
18620
18621 // Wait 10 ms then restart with auth
18622 FastForwardBy(kSleepDuration);
18623 restart_time = base::TimeTicks::Now();
18624 rv =
18625 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
18626 EXPECT_THAT(callback2.GetResult(rv), IsOk());
18627
18628 std::string response_data;
18629 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
18630 EXPECT_EQ("hello world", response_data);
18631
18632 trans.reset();
18633
18634 // One 401 report for the auth challenge, then a 200 report for the successful
18635 // retry. Note that we don't report the error draining the body, as the first
18636 // request already generated a report for the auth challenge.
18637 ASSERT_EQ(2u, network_error_logging_service()->errors().size());
18638
18639 // Check error report contents
18640 CheckReport(0 /* index */, 401 /* status_code */, OK);
18641 CheckReport(1 /* index */, 200 /* status_code */, OK);
18642
18643 const NetworkErrorLoggingService::RequestDetails& error1 =
18644 network_error_logging_service()->errors()[0];
18645 const NetworkErrorLoggingService::RequestDetails& error2 =
18646 network_error_logging_service()->errors()[1];
18647
18648 // Sanity-check elapsed time values
18649 EXPECT_EQ(error1.elapsed_time, restart_time - start_time - kSleepDuration);
18650 // Check that the start time is refreshed when restarting with auth.
18651 EXPECT_EQ(error2.elapsed_time, base::TimeTicks::Now() - restart_time);
18652}
18653
18654// Same as above, except draining the body before restarting fails
18655// asynchronously.
18656TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18657 CreateReportRestartWithAuthAsync) {
18658 std::string extra_header_string = extra_headers_.ToString();
18659 static const base::TimeDelta kSleepDuration =
18660 base::TimeDelta::FromMilliseconds(10);
18661
18662 MockWrite data_writes1[] = {
18663 MockWrite("GET / HTTP/1.1\r\n"
18664 "Host: www.example.org\r\n"
18665 "Connection: keep-alive\r\n"),
18666 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18667 };
18668
18669 MockRead data_reads1[] = {
18670 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
18671 // Give a couple authenticate options (only the middle one is actually
18672 // supported).
18673 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
18674 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
18675 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
18676 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
18677 // Large content-length -- won't matter, as connection will be reset.
18678 MockRead("Content-Length: 10000\r\n\r\n"),
18679 MockRead(ASYNC, ERR_FAILED),
18680 };
18681
18682 // After calling trans->RestartWithAuth(), this is the request we should
18683 // be issuing -- the final header line contains the credentials.
18684 MockWrite data_writes2[] = {
18685 MockWrite("GET / HTTP/1.1\r\n"
18686 "Host: www.example.org\r\n"
18687 "Connection: keep-alive\r\n"
18688 "Authorization: Basic Zm9vOmJhcg==\r\n"),
18689 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18690 };
18691
18692 // Lastly, the server responds with the actual content.
18693 MockRead data_reads2[] = {
18694 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
18695 MockRead("hello world"),
18696 MockRead(SYNCHRONOUS, OK),
18697 };
18698
18699 StaticSocketDataProvider data1(data_reads1, data_writes1);
18700 StaticSocketDataProvider data2(data_reads2, data_writes2);
18701 session_deps_.socket_factory->AddSocketDataProvider(&data1);
18702 session_deps_.socket_factory->AddSocketDataProvider(&data2);
18703
18704 SSLSocketDataProvider ssl1(ASYNC, OK);
18705 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
18706 SSLSocketDataProvider ssl2(ASYNC, OK);
18707 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
18708
18709 base::TimeTicks start_time = base::TimeTicks::Now();
18710 base::TimeTicks restart_time;
18711
18712 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18713 auto trans =
18714 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18715
18716 TestCompletionCallback callback1;
18717
18718 int rv = trans->Start(&request_, callback1.callback(), NetLogWithSource());
18719 EXPECT_THAT(callback1.GetResult(rv), IsOk());
18720
18721 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18722
18723 TestCompletionCallback callback2;
18724
18725 // Wait 10 ms then restart with auth
18726 FastForwardBy(kSleepDuration);
18727 restart_time = base::TimeTicks::Now();
18728 rv =
18729 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
18730 EXPECT_THAT(callback2.GetResult(rv), IsOk());
18731
18732 std::string response_data;
18733 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
18734 EXPECT_EQ("hello world", response_data);
18735
18736 trans.reset();
18737
18738 // One 401 report for the auth challenge, then a 200 report for the successful
18739 // retry. Note that we don't report the error draining the body, as the first
18740 // request already generated a report for the auth challenge.
18741 ASSERT_EQ(2u, network_error_logging_service()->errors().size());
18742
18743 // Check error report contents
18744 CheckReport(0 /* index */, 401 /* status_code */, OK);
18745 CheckReport(1 /* index */, 200 /* status_code */, OK);
18746
18747 const NetworkErrorLoggingService::RequestDetails& error1 =
18748 network_error_logging_service()->errors()[0];
18749 const NetworkErrorLoggingService::RequestDetails& error2 =
18750 network_error_logging_service()->errors()[1];
18751
18752 // Sanity-check elapsed time values
18753 EXPECT_EQ(error1.elapsed_time, restart_time - start_time - kSleepDuration);
18754 // Check that the start time is refreshed when restarting with auth.
18755 EXPECT_EQ(error2.elapsed_time, base::TimeTicks::Now() - restart_time);
18756}
18757
18758TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18759 CreateReportRetryKeepAliveConnectionReset) {
18760 std::string extra_header_string = extra_headers_.ToString();
18761 MockWrite data_writes1[] = {
18762 MockWrite("GET / HTTP/1.1\r\n"
18763 "Host: www.example.org\r\n"
18764 "Connection: keep-alive\r\n"),
18765 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18766 MockWrite("GET / HTTP/1.1\r\n"
18767 "Host: www.example.org\r\n"
18768 "Connection: keep-alive\r\n"),
18769 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18770 };
18771
18772 MockRead data_reads1[] = {
18773 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
18774 MockRead("hello"),
18775 // Connection is reset
18776 MockRead(ASYNC, ERR_CONNECTION_RESET),
18777 };
18778
18779 // Successful retry
18780 MockRead data_reads2[] = {
18781 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
18782 MockRead("world"),
18783 MockRead(ASYNC, OK),
18784 };
18785
18786 StaticSocketDataProvider data1(data_reads1, data_writes1);
18787 StaticSocketDataProvider data2(data_reads2, base::span<MockWrite>());
18788 session_deps_.socket_factory->AddSocketDataProvider(&data1);
18789 session_deps_.socket_factory->AddSocketDataProvider(&data2);
18790
18791 SSLSocketDataProvider ssl1(ASYNC, OK);
18792 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
18793 SSLSocketDataProvider ssl2(ASYNC, OK);
18794 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
18795
18796 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18797 auto trans1 =
18798 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18799
18800 TestCompletionCallback callback1;
18801
18802 int rv = trans1->Start(&request_, callback1.callback(), NetLogWithSource());
18803 EXPECT_THAT(callback1.GetResult(rv), IsOk());
18804
18805 std::string response_data;
18806 ASSERT_THAT(ReadTransaction(trans1.get(), &response_data), IsOk());
18807 EXPECT_EQ("hello", response_data);
18808
18809 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18810
18811 auto trans2 =
18812 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18813
18814 TestCompletionCallback callback2;
18815
18816 rv = trans2->Start(&request_, callback2.callback(), NetLogWithSource());
18817 EXPECT_THAT(callback2.GetResult(rv), IsOk());
18818
18819 ASSERT_THAT(ReadTransaction(trans2.get(), &response_data), IsOk());
18820 EXPECT_EQ("world", response_data);
18821
18822 trans1.reset();
18823 trans2.reset();
18824
18825 // One OK report from first request, then a ERR_CONNECTION_RESET report from
18826 // the second request, then an OK report from the successful retry.
18827 ASSERT_EQ(3u, network_error_logging_service()->errors().size());
18828
18829 // Check error report contents
18830 CheckReport(0 /* index */, 200 /* status_code */, OK);
18831 CheckReport(1 /* index */, 0 /* status_code */, ERR_CONNECTION_RESET);
18832 CheckReport(2 /* index */, 200 /* status_code */, OK);
18833}
18834
18835TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18836 CreateReportRetryKeepAlive408) {
18837 std::string extra_header_string = extra_headers_.ToString();
18838 MockWrite data_writes1[] = {
18839 MockWrite("GET / HTTP/1.1\r\n"
18840 "Host: www.example.org\r\n"
18841 "Connection: keep-alive\r\n"),
18842 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18843 MockWrite("GET / HTTP/1.1\r\n"
18844 "Host: www.example.org\r\n"
18845 "Connection: keep-alive\r\n"),
18846 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18847 };
18848
18849 MockRead data_reads1[] = {
18850 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
18851 MockRead("hello"),
18852 // 408 Request Timeout
18853 MockRead(SYNCHRONOUS,
18854 "HTTP/1.1 408 Request Timeout\r\n"
18855 "Connection: Keep-Alive\r\n"
18856 "Content-Length: 6\r\n\r\n"
18857 "Pickle"),
18858 };
18859
18860 // Successful retry
18861 MockRead data_reads2[] = {
18862 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
18863 MockRead("world"),
18864 MockRead(ASYNC, OK),
18865 };
18866
18867 StaticSocketDataProvider data1(data_reads1, data_writes1);
18868 StaticSocketDataProvider data2(data_reads2, base::span<MockWrite>());
18869 session_deps_.socket_factory->AddSocketDataProvider(&data1);
18870 session_deps_.socket_factory->AddSocketDataProvider(&data2);
18871
18872 SSLSocketDataProvider ssl1(ASYNC, OK);
18873 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
18874 SSLSocketDataProvider ssl2(ASYNC, OK);
18875 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
18876
18877 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18878 auto trans1 =
18879 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18880
18881 TestCompletionCallback callback1;
18882
18883 int rv = trans1->Start(&request_, callback1.callback(), NetLogWithSource());
18884 EXPECT_THAT(callback1.GetResult(rv), IsOk());
18885
18886 std::string response_data;
18887 ASSERT_THAT(ReadTransaction(trans1.get(), &response_data), IsOk());
18888 EXPECT_EQ("hello", response_data);
18889
18890 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18891
18892 auto trans2 =
18893 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18894
18895 TestCompletionCallback callback2;
18896
18897 rv = trans2->Start(&request_, callback2.callback(), NetLogWithSource());
18898 EXPECT_THAT(callback2.GetResult(rv), IsOk());
18899
18900 ASSERT_THAT(ReadTransaction(trans2.get(), &response_data), IsOk());
18901 EXPECT_EQ("world", response_data);
18902
18903 trans1.reset();
18904 trans2.reset();
18905
18906 // One 200 report from first request, then a 408 report from
18907 // the second request, then a 200 report from the successful retry.
18908 ASSERT_EQ(3u, network_error_logging_service()->errors().size());
18909
18910 // Check error report contents
18911 CheckReport(0 /* index */, 200 /* status_code */, OK);
18912 CheckReport(1 /* index */, 408 /* status_code */, OK);
18913 CheckReport(2 /* index */, 200 /* status_code */, OK);
18914}
18915
18916TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18917 CreateReportRetry421WithoutConnectionPooling) {
18918 // Two hosts resolve to the same IP address.
18919 const std::string ip_addr = "1.2.3.4";
18920 IPAddress ip;
18921 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
18922 IPEndPoint peer_addr = IPEndPoint(ip, 443);
18923
18924 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
18925 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
18926 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
18927
18928 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18929
18930 // Two requests on the first connection.
18931 spdy::SpdySerializedFrame req1(
18932 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
18933 spdy_util_.UpdateWithStreamDestruction(1);
18934 spdy::SpdySerializedFrame req2(
18935 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
18936 spdy::SpdySerializedFrame rst(
18937 spdy_util_.ConstructSpdyRstStream(3, spdy::ERROR_CODE_CANCEL));
18938 MockWrite writes1[] = {
18939 CreateMockWrite(req1, 0),
18940 CreateMockWrite(req2, 3),
18941 CreateMockWrite(rst, 6),
18942 };
18943
18944 // The first one succeeds, the second gets error 421 Misdirected Request.
18945 spdy::SpdySerializedFrame resp1(
18946 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
18947 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
18948 spdy::SpdyHeaderBlock response_headers;
18949 response_headers[spdy::kHttp2StatusHeader] = "421";
18950 spdy::SpdySerializedFrame resp2(
18951 spdy_util_.ConstructSpdyReply(3, std::move(response_headers)));
18952 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
18953 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
18954
18955 MockConnect connect1(ASYNC, OK, peer_addr);
18956 SequencedSocketData data1(connect1, reads1, writes1);
18957 session_deps_.socket_factory->AddSocketDataProvider(&data1);
18958
18959 AddSSLSocketData();
18960
18961 // Retry the second request on a second connection.
18962 SpdyTestUtil spdy_util2;
18963 spdy::SpdySerializedFrame req3(
18964 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
18965 MockWrite writes2[] = {
18966 CreateMockWrite(req3, 0),
18967 };
18968
18969 spdy::SpdySerializedFrame resp3(
18970 spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
18971 spdy::SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
18972 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
18973 MockRead(ASYNC, 0, 3)};
18974
18975 MockConnect connect2(ASYNC, OK, peer_addr);
18976 SequencedSocketData data2(connect2, reads2, writes2);
18977 session_deps_.socket_factory->AddSocketDataProvider(&data2);
18978
18979 AddSSLSocketData();
18980
18981 // Preload mail.example.org into HostCache.
18982 HostPortPair host_port("mail.example.org", 443);
18983 HostResolver::RequestInfo resolve_info(host_port);
18984 AddressList ignored;
18985 std::unique_ptr<HostResolver::Request> request;
18986 TestCompletionCallback callback;
18987 int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
18988 &ignored, callback.callback(),
18989 &request, NetLogWithSource());
18990 EXPECT_THAT(callback.GetResult(rv), IsOk());
18991
18992 HttpRequestInfo request1;
18993 request1.method = "GET";
18994 request1.url = GURL("https://www.example.org/");
18995 request1.load_flags = 0;
18996 request1.traffic_annotation =
18997 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
18998 auto trans1 =
18999 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19000
19001 rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
19002 EXPECT_THAT(callback.GetResult(rv), IsOk());
19003
19004 const HttpResponseInfo* response = trans1->GetResponseInfo();
19005 ASSERT_TRUE(response);
19006 ASSERT_TRUE(response->headers);
19007 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
19008 EXPECT_TRUE(response->was_fetched_via_spdy);
19009 EXPECT_TRUE(response->was_alpn_negotiated);
19010 std::string response_data;
19011 ASSERT_THAT(ReadTransaction(trans1.get(), &response_data), IsOk());
19012 EXPECT_EQ("hello!", response_data);
19013
19014 trans1.reset();
19015
19016 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
19017
19018 HttpRequestInfo request2;
19019 request2.method = "GET";
19020 request2.url = GURL("https://mail.example.org/");
19021 request2.load_flags = 0;
19022 request2.traffic_annotation =
19023 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19024 auto trans2 =
19025 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19026
19027 BoundTestNetLog log;
19028 rv = trans2->Start(&request2, callback.callback(), log.bound());
19029 EXPECT_THAT(callback.GetResult(rv), IsOk());
19030
19031 response = trans2->GetResponseInfo();
19032 ASSERT_TRUE(response);
19033 ASSERT_TRUE(response->headers);
19034 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
19035 EXPECT_TRUE(response->was_fetched_via_spdy);
19036 EXPECT_TRUE(response->was_alpn_negotiated);
19037 ASSERT_THAT(ReadTransaction(trans2.get(), &response_data), IsOk());
19038 EXPECT_EQ("hello!", response_data);
19039
19040 trans2.reset();
19041
19042 // One 200 report from the first request, then a 421 report from the
19043 // second request, then a 200 report from the successful retry.
19044 ASSERT_EQ(3u, network_error_logging_service()->errors().size());
19045
19046 // Check error report contents
19047 const NetworkErrorLoggingService::RequestDetails& error1 =
19048 network_error_logging_service()->errors()[0];
19049 EXPECT_EQ(GURL("https://www.example.org/"), error1.uri);
19050 EXPECT_TRUE(error1.referrer.is_empty());
19051 EXPECT_EQ("", error1.user_agent);
19052 EXPECT_EQ(ip, error1.server_ip);
19053 EXPECT_EQ("h2", error1.protocol);
19054 EXPECT_EQ("GET", error1.method);
19055 EXPECT_EQ(200, error1.status_code);
19056 EXPECT_EQ(OK, error1.type);
19057 EXPECT_EQ(0, error1.reporting_upload_depth);
19058
19059 const NetworkErrorLoggingService::RequestDetails& error2 =
19060 network_error_logging_service()->errors()[1];
19061 EXPECT_EQ(GURL("https://mail.example.org/"), error2.uri);
19062 EXPECT_TRUE(error2.referrer.is_empty());
19063 EXPECT_EQ("", error2.user_agent);
19064 EXPECT_EQ(ip, error2.server_ip);
19065 EXPECT_EQ("h2", error2.protocol);
19066 EXPECT_EQ("GET", error2.method);
19067 EXPECT_EQ(421, error2.status_code);
19068 EXPECT_EQ(OK, error2.type);
19069 EXPECT_EQ(0, error2.reporting_upload_depth);
19070
19071 const NetworkErrorLoggingService::RequestDetails& error3 =
19072 network_error_logging_service()->errors()[2];
19073 EXPECT_EQ(GURL("https://mail.example.org/"), error3.uri);
19074 EXPECT_TRUE(error3.referrer.is_empty());
19075 EXPECT_EQ("", error3.user_agent);
19076 EXPECT_EQ(ip, error3.server_ip);
19077 EXPECT_EQ("h2", error3.protocol);
19078 EXPECT_EQ("GET", error3.method);
19079 EXPECT_EQ(200, error3.status_code);
19080 EXPECT_EQ(OK, error3.type);
19081 EXPECT_EQ(0, error3.reporting_upload_depth);
Douglas Creageref5eecdc2018-11-09 20:50:3619082}
19083
Lily Chen00196ab62018-12-04 19:52:2919084TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, DontCreateReportHttp) {
19085 base::HistogramTester histograms;
19086 RequestPolicy();
19087 EXPECT_EQ(1u, network_error_logging_service()->headers().size());
19088 EXPECT_EQ(1u, network_error_logging_service()->errors().size());
19089
19090 // Make HTTP request
19091 std::string extra_header_string = extra_headers_.ToString();
19092 MockRead data_reads[] = {
19093 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
19094 MockRead("hello world"),
19095 MockRead(SYNCHRONOUS, OK),
19096 };
19097 MockWrite data_writes[] = {
19098 MockWrite("GET / HTTP/1.1\r\n"
19099 "Host: www.example.org\r\n"
19100 "Connection: keep-alive\r\n"),
19101 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
19102 };
19103
Lily Chen00196ab62018-12-04 19:52:2919104 StaticSocketDataProvider reads(data_reads, data_writes);
19105 session_deps_.socket_factory->AddSocketDataProvider(&reads);
19106
Lily Chenfec60d92019-01-24 01:16:4219107 // Insecure url
19108 url_ = "http://www.example.org/";
19109 request_.url = GURL(url_);
19110
Lily Chen00196ab62018-12-04 19:52:2919111 TestCompletionCallback callback;
19112 auto session = CreateSession(&session_deps_);
Lily Chenfec60d92019-01-24 01:16:4219113 auto trans =
19114 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19115 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
19116 EXPECT_THAT(callback.GetResult(rv), IsOk());
19117
19118 std::string response_data;
19119 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
19120 EXPECT_EQ("hello world", response_data);
Lily Chen00196ab62018-12-04 19:52:2919121
19122 // Insecure request does not generate a report
19123 histograms.ExpectBucketCount(
19124 NetworkErrorLoggingService::kRequestOutcomeHistogram,
19125 NetworkErrorLoggingService::RequestOutcome::DISCARDED_INSECURE_ORIGIN, 1);
19126
19127 EXPECT_EQ(1u, network_error_logging_service()->errors().size());
19128}
19129
19130TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
19131 DontCreateReportHttpError) {
19132 base::HistogramTester histograms;
19133 RequestPolicy();
19134 EXPECT_EQ(1u, network_error_logging_service()->headers().size());
19135 EXPECT_EQ(1u, network_error_logging_service()->errors().size());
19136
19137 // Make HTTP request that fails
19138 MockRead data_reads[] = {
19139 MockRead("hello world"),
19140 MockRead(SYNCHRONOUS, OK),
19141 };
19142
19143 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
19144 session_deps_.socket_factory->AddSocketDataProvider(&data);
19145
Lily Chenfec60d92019-01-24 01:16:4219146 url_ = "http://www.originwithoutpolicy.com:2000/";
19147 request_.url = GURL(url_);
19148
Lily Chen00196ab62018-12-04 19:52:2919149 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19150
Lily Chen00196ab62018-12-04 19:52:2919151 auto trans =
19152 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Lily Chen00196ab62018-12-04 19:52:2919153 TestCompletionCallback callback;
Lily Chenfec60d92019-01-24 01:16:4219154 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
Lily Chen00196ab62018-12-04 19:52:2919155 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_INVALID_HTTP_RESPONSE));
19156
19157 // Insecure request does not generate a report, regardless of existence of a
19158 // policy for the origin.
19159 histograms.ExpectBucketCount(
19160 NetworkErrorLoggingService::kRequestOutcomeHistogram,
19161 NetworkErrorLoggingService::RequestOutcome::DISCARDED_INSECURE_ORIGIN, 1);
19162
19163 EXPECT_EQ(1u, network_error_logging_service()->errors().size());
19164}
19165
Douglas Creageref5eecdc2018-11-09 20:50:3619166TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
19167 ReportContainsUploadDepth) {
19168 reporting_upload_depth_ = 7;
Lily Chenfec60d92019-01-24 01:16:4219169 request_.reporting_upload_depth = reporting_upload_depth_;
Douglas Creageref5eecdc2018-11-09 20:50:3619170 RequestPolicy();
19171 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
Lily Chenfec60d92019-01-24 01:16:4219172 const NetworkErrorLoggingService::RequestDetails& error =
19173 network_error_logging_service()->errors()[0];
Douglas Creageref5eecdc2018-11-09 20:50:3619174 EXPECT_EQ(7, error.reporting_upload_depth);
19175}
19176
Lily Chenfec60d92019-01-24 01:16:4219177TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, ReportElapsedTime) {
19178 std::string extra_header_string = extra_headers_.ToString();
19179 static const base::TimeDelta kSleepDuration =
19180 base::TimeDelta::FromMilliseconds(10);
19181
19182 std::vector<MockWrite> data_writes = {
19183 MockWrite(ASYNC, 0,
19184 "GET / HTTP/1.1\r\n"
19185 "Host: www.example.org\r\n"
19186 "Connection: keep-alive\r\n"),
19187 MockWrite(ASYNC, 1, extra_header_string.data()),
19188 };
19189
19190 std::vector<MockRead> data_reads = {
19191 // Write one byte of the status line, followed by a pause.
19192 MockRead(ASYNC, 2, "H"),
19193 MockRead(ASYNC, ERR_IO_PENDING, 3),
19194 MockRead(ASYNC, 4, "TTP/1.1 200 OK\r\n\r\n"),
19195 MockRead(ASYNC, 5, "hello world"),
19196 MockRead(SYNCHRONOUS, OK, 6),
19197 };
19198
19199 SequencedSocketData data(data_reads, data_writes);
19200 session_deps_.socket_factory->AddSocketDataProvider(&data);
19201
19202 SSLSocketDataProvider ssl(ASYNC, OK);
19203 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
19204
19205 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19206
19207 auto trans =
19208 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19209
19210 TestCompletionCallback callback;
19211
19212 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
19213 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
19214
19215 data.RunUntilPaused();
19216 ASSERT_TRUE(data.IsPaused());
19217 FastForwardBy(kSleepDuration);
19218 data.Resume();
19219
19220 EXPECT_THAT(callback.GetResult(rv), IsOk());
19221
19222 std::string response_data;
19223 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
19224 EXPECT_EQ("hello world", response_data);
19225
19226 trans.reset();
19227
Douglas Creageref5eecdc2018-11-09 20:50:3619228 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
Lily Chenfec60d92019-01-24 01:16:4219229
19230 CheckReport(0 /* index */, 200 /* status_code */, OK);
19231
19232 const NetworkErrorLoggingService::RequestDetails& error =
19233 network_error_logging_service()->errors()[0];
19234
19235 // Sanity-check elapsed time in error report
19236 EXPECT_EQ(kSleepDuration, error.elapsed_time);
Douglas Creageref5eecdc2018-11-09 20:50:3619237}
Lily Chenfec60d92019-01-24 01:16:4219238
Douglas Creager3cb042052018-11-06 23:08:5219239#endif // BUILDFLAG(ENABLE_REPORTING)
19240
[email protected]89ceba9a2009-03-21 03:46:0619241} // namespace net