blob: e8e24f944cadf8c62d9e2f3a280d97d160e08d08 [file] [log] [blame]
[email protected]23e482282013-06-14 16:08:021// Copyright 2013 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit586acc5fe2008-07-26 22:42:524
[email protected]2d731a32010-04-29 01:04:065#include "net/http/http_network_transaction.h"
6
[email protected]77848d12008-11-14 00:00:227#include <math.h> // ceil
[email protected]5285d972011-10-18 18:56:348#include <stdarg.h>
sclittlebe1ccf62015-09-02 19:40:369#include <stdint.h>
danakj1fd259a02016-04-16 03:17:0910
avibf0746c2015-12-09 19:53:1411#include <limits>
rdsmith1d343be52016-10-21 20:37:5012#include <set>
[email protected]5285d972011-10-18 18:56:3413#include <string>
dchengc7eeda422015-12-26 03:56:4814#include <utility>
[email protected]95d88ffe2010-02-04 21:25:3315#include <vector>
[email protected]77848d12008-11-14 00:00:2216
Sebastien Marchand6d0558fd2019-01-25 16:49:3717#include "base/bind.h"
[email protected]68bf9152008-09-25 19:47:3018#include "base/compiler_specific.h"
[email protected]57999812013-02-24 05:40:5219#include "base/files/file_path.h"
thestigd8df0332014-09-04 06:33:2920#include "base/files/file_util.h"
[email protected]f3da152d2012-06-02 01:00:5721#include "base/json/json_writer.h"
Adam Rice425cf122015-01-19 06:18:2422#include "base/logging.h"
danakj1fd259a02016-04-16 03:17:0923#include "base/memory/ptr_util.h"
[email protected]bf828982013-08-14 18:01:4724#include "base/memory/weak_ptr.h"
[email protected]a34f61ee2014-03-18 20:59:4925#include "base/run_loop.h"
Avi Drissman4365a4782018-12-28 19:26:2426#include "base/stl_util.h"
Bence Békyd74f4382018-02-20 18:26:1927#include "base/strings/string_piece.h"
[email protected]125ef482013-06-11 18:32:4728#include "base/strings/string_util.h"
[email protected]750b2f3c2013-06-07 18:41:0529#include "base/strings/utf_string_conversions.h"
Douglas Creager3cb042052018-11-06 23:08:5230#include "base/test/metrics/histogram_tester.h"
Douglas Creager134b52e2018-11-09 18:00:1431#include "base/test/simple_test_clock.h"
32#include "base/test/simple_test_tick_clock.h"
[email protected]f36a8132011-09-02 18:36:3333#include "base/test/test_file_util.h"
gabf767595f2016-05-11 18:50:3534#include "base/threading/thread_task_runner_handle.h"
[email protected]277d5942010-08-11 21:02:3535#include "net/base/auth.h"
mmenkecbc2b712014-10-09 20:29:0736#include "net/base/chunked_upload_data_stream.h"
Bence Békya25e3f72018-02-13 21:13:3937#include "net/base/completion_once_callback.h"
mmenkecbc2b712014-10-09 20:29:0738#include "net/base/elements_upload_data_stream.h"
[email protected]58e32bb2013-01-21 18:23:2539#include "net/base/load_timing_info.h"
40#include "net/base/load_timing_info_test_util.h"
Adam Rice425cf122015-01-19 06:18:2441#include "net/base/net_errors.h"
tbansal28e68f82016-02-04 02:56:1542#include "net/base/proxy_delegate.h"
Lily Houghton582d4622018-01-22 22:43:4043#include "net/base/proxy_server.h"
[email protected]ac790b42009-12-02 04:31:3144#include "net/base/request_priority.h"
initial.commit586acc5fe2008-07-26 22:42:5245#include "net/base/test_completion_callback.h"
tbansal28e68f82016-02-04 02:56:1546#include "net/base/test_proxy_delegate.h"
[email protected]b2d26cfd2012-12-11 10:36:0647#include "net/base/upload_bytes_element_reader.h"
[email protected]d98961652012-09-11 20:27:2148#include "net/base/upload_file_element_reader.h"
Bence Béky230ac612017-08-30 19:17:0849#include "net/cert/cert_status_flags.h"
[email protected]6e7845ae2013-03-29 21:48:1150#include "net/cert/mock_cert_verifier.h"
[email protected]bc71b8772013-04-10 20:55:1651#include "net/dns/host_cache.h"
[email protected]f2cb3cf2013-03-21 01:40:5352#include "net/dns/mock_host_resolver.h"
[email protected]df41d0d82014-03-13 00:43:2453#include "net/http/http_auth_challenge_tokenizer.h"
[email protected]3c32c5f2010-05-18 15:18:1254#include "net/http/http_auth_handler_digest.h"
[email protected]3fd9dae2010-06-21 11:39:0055#include "net/http/http_auth_handler_mock.h"
[email protected]385a4672009-03-11 22:21:2956#include "net/http/http_auth_handler_ntlm.h"
aberentbba302d2015-12-03 10:20:1957#include "net/http/http_auth_scheme.h"
[email protected]0877e3d2009-10-17 22:29:5758#include "net/http/http_basic_stream.h"
initial.commit586acc5fe2008-07-26 22:42:5259#include "net/http/http_network_session.h"
[email protected]87bfa3f2010-09-30 14:54:5660#include "net/http/http_network_session_peer.h"
Adam Rice425cf122015-01-19 06:18:2461#include "net/http/http_request_headers.h"
mmenke5f94fda2016-06-02 20:54:1362#include "net/http/http_response_info.h"
[email protected]17291a022011-10-10 07:32:5363#include "net/http/http_server_properties_impl.h"
[email protected]0877e3d2009-10-17 22:29:5764#include "net/http/http_stream.h"
[email protected]8e6441ca2010-08-19 05:56:3865#include "net/http/http_stream_factory.h"
[email protected]c41737d2014-05-14 07:47:1966#include "net/http/http_transaction_test_util.h"
eroman87c53d62015-04-02 06:51:0767#include "net/log/net_log.h"
mikecirone8b85c432016-09-08 19:11:0068#include "net/log/net_log_event_type.h"
mikecironef22f9812016-10-04 03:40:1969#include "net/log/net_log_source.h"
vishal.b62985ca92015-04-17 08:45:5170#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4671#include "net/log/test_net_log_entry.h"
72#include "net/log/test_net_log_util.h"
Lily Houghton582d4622018-01-22 22:43:4073#include "net/proxy_resolution/mock_proxy_resolver.h"
74#include "net/proxy_resolution/proxy_config_service_fixed.h"
75#include "net/proxy_resolution/proxy_info.h"
Lily Houghtonffe89daa02018-03-09 18:30:0376#include "net/proxy_resolution/proxy_resolution_service.h"
Lily Houghton582d4622018-01-22 22:43:4077#include "net/proxy_resolution/proxy_resolver.h"
78#include "net/proxy_resolution/proxy_resolver_factory.h"
[email protected]f7984fc62009-06-22 23:26:4479#include "net/socket/client_socket_factory.h"
mmenked3641e12016-01-28 16:06:1580#include "net/socket/client_socket_pool.h"
[email protected]483fa202013-05-14 01:07:0381#include "net/socket/client_socket_pool_manager.h"
ttuttle1f2d7e92015-04-28 16:17:4782#include "net/socket/connection_attempts.h"
[email protected]a42dbd142011-11-17 16:42:0283#include "net/socket/mock_client_socket_pool_manager.h"
[email protected]bb88e1d32013-05-03 23:11:0784#include "net/socket/next_proto.h"
Paul Jensena457017a2018-01-19 23:52:0485#include "net/socket/socket_tag.h"
[email protected]f7984fc62009-06-22 23:26:4486#include "net/socket/socket_test_util.h"
87#include "net/socket/ssl_client_socket.h"
Bence Béky94658bf2018-05-11 19:22:5888#include "net/spdy/spdy_session.h"
89#include "net/spdy/spdy_session_pool.h"
90#include "net/spdy/spdy_test_util_common.h"
nharperb7441ef2016-01-25 23:54:1491#include "net/ssl/default_channel_id_store.h"
[email protected]536fd0b2013-03-14 17:41:5792#include "net/ssl/ssl_cert_request_info.h"
[email protected]e86839fd2013-08-14 18:29:0393#include "net/ssl/ssl_config_service.h"
[email protected]536fd0b2013-03-14 17:41:5794#include "net/ssl/ssl_info.h"
svaldez7872fd02015-11-19 21:10:5495#include "net/ssl/ssl_private_key.h"
[email protected]6e7845ae2013-03-29 21:48:1196#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:0197#include "net/test/gtest_util.h"
rsleevia69c79a2016-06-22 03:28:4398#include "net/test/test_data_directory.h"
Bence Béky98447b12018-05-08 03:14:0199#include "net/test/test_with_scoped_task_environment.h"
Victor Vasiliev27cc7712019-01-24 11:50:14100#include "net/third_party/quiche/src/spdy/core/spdy_framer.h"
[email protected]baee31a2018-01-18 06:10:23101#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
[email protected]831e4a32013-11-14 02:14:44102#include "net/websockets/websocket_handshake_stream_base.h"
Bence Békydca6bd92018-01-30 13:43:06103#include "net/websockets/websocket_test_util.h"
bncf4588402015-11-24 13:33:18104#include "testing/gmock/include/gmock/gmock.h"
initial.commit586acc5fe2008-07-26 22:42:52105#include "testing/gtest/include/gtest/gtest.h"
[email protected]23887f04f2008-12-02 19:20:15106#include "testing/platform_test.h"
[email protected]795cbf82013-07-22 09:37:27107#include "url/gurl.h"
initial.commit586acc5fe2008-07-26 22:42:52108
Zentaro Kavanagh5b27a6e22017-09-25 23:00:37109#if defined(NTLM_PORTABLE)
110#include "base/base64.h"
111#include "net/ntlm/ntlm_test_data.h"
112#endif
113
Douglas Creager3cb042052018-11-06 23:08:52114#if BUILDFLAG(ENABLE_REPORTING)
115#include "net/network_error_logging/network_error_logging_service.h"
116#include "net/network_error_logging/network_error_logging_test_util.h"
Douglas Creager134b52e2018-11-09 18:00:14117#include "net/reporting/reporting_cache.h"
118#include "net/reporting/reporting_client.h"
119#include "net/reporting/reporting_header_parser.h"
120#include "net/reporting/reporting_service.h"
121#include "net/reporting/reporting_test_util.h"
Douglas Creager3cb042052018-11-06 23:08:52122#endif // BUILDFLAG(ENABLE_REPORTING)
123
robpercival214763f2016-07-01 23:27:01124using net::test::IsError;
125using net::test::IsOk;
126
[email protected]ad65a3e2013-12-25 18:18:01127using base::ASCIIToUTF16;
128
initial.commit586acc5fe2008-07-26 22:42:52129//-----------------------------------------------------------------------------
130
ttuttle859dc7a2015-04-23 19:42:29131namespace net {
132
[email protected]13c8a092010-07-29 06:15:44133namespace {
134
[email protected]42cba2fb2013-03-29 19:58:57135const base::string16 kBar(ASCIIToUTF16("bar"));
136const base::string16 kBar2(ASCIIToUTF16("bar2"));
137const base::string16 kBar3(ASCIIToUTF16("bar3"));
138const base::string16 kBaz(ASCIIToUTF16("baz"));
139const base::string16 kFirst(ASCIIToUTF16("first"));
140const base::string16 kFoo(ASCIIToUTF16("foo"));
141const base::string16 kFoo2(ASCIIToUTF16("foo2"));
142const base::string16 kFoo3(ASCIIToUTF16("foo3"));
143const base::string16 kFou(ASCIIToUTF16("fou"));
144const base::string16 kSecond(ASCIIToUTF16("second"));
[email protected]42cba2fb2013-03-29 19:58:57145const base::string16 kWrongPassword(ASCIIToUTF16("wrongpassword"));
[email protected]13c8a092010-07-29 06:15:44146
bnc2df4b522016-07-08 18:17:43147const char kAlternativeServiceHttpHeader[] =
148 "Alt-Svc: h2=\"mail.example.org:443\"\r\n";
149
ttuttle859dc7a2015-04-23 19:42:29150int GetIdleSocketCountInTransportSocketPool(HttpNetworkSession* session) {
151 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
152 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02153}
154
ttuttle859dc7a2015-04-23 19:42:29155int GetIdleSocketCountInSSLSocketPool(HttpNetworkSession* session) {
156 return session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
157 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02158}
159
ttuttle859dc7a2015-04-23 19:42:29160bool IsTransportSocketPoolStalled(HttpNetworkSession* session) {
161 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
162 ->IsStalled();
[email protected]043b68c82013-08-22 23:41:52163}
164
[email protected]f3da152d2012-06-02 01:00:57165// Takes in a Value created from a NetLogHttpResponseParameter, and returns
166// a JSONified list of headers as a single string. Uses single quotes instead
167// of double quotes for easier comparison. Returns false on failure.
[email protected]ea5ef4c2013-06-13 22:50:27168bool GetHeaders(base::DictionaryValue* params, std::string* headers) {
[email protected]f3da152d2012-06-02 01:00:57169 if (!params)
170 return false;
[email protected]ea5ef4c2013-06-13 22:50:27171 base::ListValue* header_list;
[email protected]f3da152d2012-06-02 01:00:57172 if (!params->GetList("headers", &header_list))
173 return false;
174 std::string double_quote_headers;
estade8d046462015-05-16 01:02:34175 base::JSONWriter::Write(*header_list, &double_quote_headers);
[email protected]466c9862013-12-03 22:05:28176 base::ReplaceChars(double_quote_headers, "\"", "'", headers);
[email protected]f3da152d2012-06-02 01:00:57177 return true;
178}
179
[email protected]029c83b62013-01-24 05:28:20180// Tests LoadTimingInfo in the case a socket is reused and no PAC script is
181// used.
ttuttle859dc7a2015-04-23 19:42:29182void TestLoadTimingReused(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20183 EXPECT_TRUE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19184 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]58e32bb2013-01-21 18:23:25185
[email protected]029c83b62013-01-24 05:28:20186 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
187 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
188
ttuttle859dc7a2015-04-23 19:42:29189 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20190 EXPECT_FALSE(load_timing_info.send_start.is_null());
[email protected]58e32bb2013-01-21 18:23:25191
192 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]58e32bb2013-01-21 18:23:25193
[email protected]3b23a222013-05-15 21:33:25194 // Set at a higher level.
[email protected]58e32bb2013-01-21 18:23:25195 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
196 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25197 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25198}
199
[email protected]029c83b62013-01-24 05:28:20200// Tests LoadTimingInfo in the case a new socket is used and no PAC script is
201// used.
ttuttle859dc7a2015-04-23 19:42:29202void TestLoadTimingNotReused(const LoadTimingInfo& load_timing_info,
[email protected]58e32bb2013-01-21 18:23:25203 int connect_timing_flags) {
[email protected]029c83b62013-01-24 05:28:20204 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19205 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20206
207 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
208 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
209
ttuttle859dc7a2015-04-23 19:42:29210 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
211 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20212 EXPECT_LE(load_timing_info.connect_timing.connect_end,
213 load_timing_info.send_start);
214
215 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20216
[email protected]3b23a222013-05-15 21:33:25217 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20218 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
219 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25220 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20221}
222
223// Tests LoadTimingInfo in the case a socket is reused and a PAC script is
224// used.
ttuttle859dc7a2015-04-23 19:42:29225void TestLoadTimingReusedWithPac(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20226 EXPECT_TRUE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19227 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20228
ttuttle859dc7a2015-04-23 19:42:29229 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20230
231 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
232 EXPECT_LE(load_timing_info.proxy_resolve_start,
233 load_timing_info.proxy_resolve_end);
234 EXPECT_LE(load_timing_info.proxy_resolve_end,
235 load_timing_info.send_start);
236 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20237
[email protected]3b23a222013-05-15 21:33:25238 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20239 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
240 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25241 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20242}
243
244// Tests LoadTimingInfo in the case a new socket is used and a PAC script is
245// used.
ttuttle859dc7a2015-04-23 19:42:29246void TestLoadTimingNotReusedWithPac(const LoadTimingInfo& load_timing_info,
[email protected]029c83b62013-01-24 05:28:20247 int connect_timing_flags) {
248 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19249 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20250
251 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
252 EXPECT_LE(load_timing_info.proxy_resolve_start,
253 load_timing_info.proxy_resolve_end);
254 EXPECT_LE(load_timing_info.proxy_resolve_end,
255 load_timing_info.connect_timing.connect_start);
ttuttle859dc7a2015-04-23 19:42:29256 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
257 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20258 EXPECT_LE(load_timing_info.connect_timing.connect_end,
259 load_timing_info.send_start);
260
261 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20262
[email protected]3b23a222013-05-15 21:33:25263 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20264 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
265 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25266 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25267}
268
Matt Menke2436b2f2018-12-11 18:07:11269// ProxyResolver that records URLs passed to it, and that can be told what
270// result to return.
271class CapturingProxyResolver : public ProxyResolver {
272 public:
273 CapturingProxyResolver()
274 : proxy_server_(ProxyServer::SCHEME_HTTP, HostPortPair("myproxy", 80)) {}
275 ~CapturingProxyResolver() override = default;
276
277 int GetProxyForURL(const GURL& url,
278 ProxyInfo* results,
279 CompletionOnceCallback callback,
280 std::unique_ptr<Request>* request,
281 const NetLogWithSource& net_log) override {
282 results->UseProxyServer(proxy_server_);
283 resolved_.push_back(url);
284 return OK;
285 }
286
287 // Sets whether the resolver should use direct connections, instead of a
288 // proxy.
289 void set_proxy_server(ProxyServer proxy_server) {
290 proxy_server_ = proxy_server;
291 }
292
293 const std::vector<GURL>& resolved() const { return resolved_; }
294
295 private:
296 std::vector<GURL> resolved_;
297
298 ProxyServer proxy_server_;
299
300 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
301};
302
303class CapturingProxyResolverFactory : public ProxyResolverFactory {
304 public:
305 explicit CapturingProxyResolverFactory(CapturingProxyResolver* resolver)
306 : ProxyResolverFactory(false), resolver_(resolver) {}
307
308 int CreateProxyResolver(const scoped_refptr<PacFileData>& pac_script,
309 std::unique_ptr<ProxyResolver>* resolver,
310 CompletionOnceCallback callback,
311 std::unique_ptr<Request>* request) override {
312 *resolver = std::make_unique<ForwardingProxyResolver>(resolver_);
313 return OK;
314 }
315
316 private:
317 ProxyResolver* resolver_;
318};
319
danakj1fd259a02016-04-16 03:17:09320std::unique_ptr<HttpNetworkSession> CreateSession(
mmenkee65e7af2015-10-13 17:16:42321 SpdySessionDependencies* session_deps) {
[email protected]c6bf8152012-12-02 07:43:34322 return SpdySessionDependencies::SpdyCreateSession(session_deps);
[email protected]e8d536192008-10-17 22:21:14323}
324
xunjieli96f2a402017-06-05 17:24:27325class FailingProxyResolverFactory : public ProxyResolverFactory {
326 public:
327 FailingProxyResolverFactory() : ProxyResolverFactory(false) {}
328
329 // ProxyResolverFactory override.
Lily Houghton99597862018-03-07 16:40:42330 int CreateProxyResolver(const scoped_refptr<PacFileData>& script_data,
331 std::unique_ptr<ProxyResolver>* result,
Bence Békycc5b88a2018-05-25 20:24:17332 CompletionOnceCallback callback,
Lily Houghton99597862018-03-07 16:40:42333 std::unique_ptr<Request>* request) override {
xunjieli96f2a402017-06-05 17:24:27334 return ERR_PAC_SCRIPT_FAILED;
335 }
336};
337
David Benjamin5cb91132018-04-06 05:54:49338class TestSSLConfigService : public SSLConfigService {
339 public:
340 explicit TestSSLConfigService(const SSLConfig& config) : config_(config) {}
Ryan Sleevib8449e02018-07-15 04:31:07341 ~TestSSLConfigService() override = default;
David Benjamin5cb91132018-04-06 05:54:49342
343 void GetSSLConfig(SSLConfig* config) override { *config = config_; }
344
Nick Harper89bc7212018-07-31 19:07:57345 bool CanShareConnectionWithClientCerts(
346 const std::string& hostname) const override {
347 return false;
348 }
349
David Benjamin5cb91132018-04-06 05:54:49350 private:
David Benjamin5cb91132018-04-06 05:54:49351 SSLConfig config_;
352};
353
[email protected]448d4ca52012-03-04 04:12:23354} // namespace
355
Bence Béky98447b12018-05-08 03:14:01356class HttpNetworkTransactionTest : public PlatformTest,
357 public WithScopedTaskEnvironment {
[email protected]483fa202013-05-14 01:07:03358 public:
bncd16676a2016-07-20 16:23:01359 ~HttpNetworkTransactionTest() override {
[email protected]483fa202013-05-14 01:07:03360 // Important to restore the per-pool limit first, since the pool limit must
361 // always be greater than group limit, and the tests reduce both limits.
362 ClientSocketPoolManager::set_max_sockets_per_pool(
363 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
364 ClientSocketPoolManager::set_max_sockets_per_group(
365 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
366 }
367
[email protected]e3ceb682011-06-28 23:55:46368 protected:
[email protected]23e482282013-06-14 16:08:02369 HttpNetworkTransactionTest()
Andrew Comminos517a92c2019-01-14 17:49:56370 : WithScopedTaskEnvironment(
371 base::test::ScopedTaskEnvironment::MainThreadType::IO_MOCK_TIME,
372 base::test::ScopedTaskEnvironment::NowSource::
373 MAIN_THREAD_MOCK_TIME),
374 ssl_(ASYNC, OK),
bnc032658ba2016-09-26 18:17:15375 old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
[email protected]483fa202013-05-14 01:07:03376 HttpNetworkSession::NORMAL_SOCKET_POOL)),
377 old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
378 HttpNetworkSession::NORMAL_SOCKET_POOL)) {
bnca86731e2017-04-17 12:31:28379 session_deps_.enable_http2_alternative_service = true;
[email protected]483fa202013-05-14 01:07:03380 }
[email protected]bb88e1d32013-05-03 23:11:07381
[email protected]e3ceb682011-06-28 23:55:46382 struct SimpleGetHelperResult {
383 int rv;
384 std::string status_line;
385 std::string response_data;
sclittlefb249892015-09-10 21:33:22386 int64_t total_received_bytes;
387 int64_t total_sent_bytes;
[email protected]58e32bb2013-01-21 18:23:25388 LoadTimingInfo load_timing_info;
ttuttle1f2d7e92015-04-28 16:17:47389 ConnectionAttempts connection_attempts;
ttuttled9dbc652015-09-29 20:00:59390 IPEndPoint remote_endpoint_after_start;
[email protected]e3ceb682011-06-28 23:55:46391 };
392
dcheng67be2b1f2014-10-27 21:47:29393 void SetUp() override {
[email protected]0b0bf032010-09-21 18:08:50394 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55395 base::RunLoop().RunUntilIdle();
Andrew Comminos517a92c2019-01-14 17:49:56396 // Set an initial delay to ensure that the first call to TimeTicks::Now()
397 // before incrementing the counter does not return a null value.
398 FastForwardBy(TimeDelta::FromSeconds(1));
[email protected]2ff8b312010-04-26 22:20:54399 }
400
dcheng67be2b1f2014-10-27 21:47:29401 void TearDown() override {
[email protected]0b0bf032010-09-21 18:08:50402 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55403 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09404 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:55405 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09406 PlatformTest::TearDown();
[email protected]0b0bf032010-09-21 18:08:50407 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55408 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09409 }
410
Andrew Comminos1f2ff1cc2018-12-14 05:22:38411 void Check100ResponseTiming(bool use_spdy);
412
[email protected]202965992011-12-07 23:04:51413 // Either |write_failure| specifies a write failure or |read_failure|
414 // specifies a read failure when using a reused socket. In either case, the
415 // failure should cause the network transaction to resend the request, and the
416 // other argument should be NULL.
417 void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
418 const MockRead* read_failure);
initial.commit586acc5fe2008-07-26 22:42:52419
[email protected]a34f61ee2014-03-18 20:59:49420 // Either |write_failure| specifies a write failure or |read_failure|
421 // specifies a read failure when using a reused socket. In either case, the
422 // failure should cause the network transaction to resend the request, and the
423 // other argument should be NULL.
424 void PreconnectErrorResendRequestTest(const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:10425 const MockRead* read_failure,
426 bool use_spdy);
[email protected]a34f61ee2014-03-18 20:59:49427
Ryan Sleevib8d7ea02018-05-07 20:01:01428 SimpleGetHelperResult SimpleGetHelperForData(
429 base::span<StaticSocketDataProvider*> providers) {
[email protected]ff007e162009-05-23 09:13:15430 SimpleGetHelperResult out;
initial.commit586acc5fe2008-07-26 22:42:52431
[email protected]ff007e162009-05-23 09:13:15432 HttpRequestInfo request;
433 request.method = "GET";
bncce36dca22015-04-21 22:11:23434 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:10435 request.traffic_annotation =
436 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:52437
vishal.b62985ca92015-04-17 08:45:51438 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:07439 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:09440 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16441 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:27442
Ryan Sleevib8d7ea02018-05-07 20:01:01443 for (auto* provider : providers) {
444 session_deps_.socket_factory->AddSocketDataProvider(provider);
[email protected]5a60c8b2011-10-19 20:14:29445 }
initial.commit586acc5fe2008-07-26 22:42:52446
[email protected]49639fa2011-12-20 23:22:41447 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52448
eroman24bc6a12015-05-06 19:55:48449 EXPECT_TRUE(log.bound().IsCapturing());
bnc691fda62016-08-12 00:43:16450 int rv = trans.Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:01451 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:52452
[email protected]ff007e162009-05-23 09:13:15453 out.rv = callback.WaitForResult();
bnc691fda62016-08-12 00:43:16454 out.total_received_bytes = trans.GetTotalReceivedBytes();
455 out.total_sent_bytes = trans.GetTotalSentBytes();
[email protected]58e32bb2013-01-21 18:23:25456
457 // Even in the failure cases that use this function, connections are always
458 // successfully established before the error.
bnc691fda62016-08-12 00:43:16459 EXPECT_TRUE(trans.GetLoadTimingInfo(&out.load_timing_info));
[email protected]58e32bb2013-01-21 18:23:25460 TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
461
[email protected]ff007e162009-05-23 09:13:15462 if (out.rv != OK)
463 return out;
464
bnc691fda62016-08-12 00:43:16465 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50466 // Can't use ASSERT_* inside helper functions like this, so
467 // return an error.
wezca1070932016-05-26 20:30:52468 if (!response || !response->headers) {
[email protected]fe2255a2011-09-20 19:37:50469 out.rv = ERR_UNEXPECTED;
470 return out;
471 }
[email protected]ff007e162009-05-23 09:13:15472 out.status_line = response->headers->GetStatusLine();
473
[email protected]80a09a82012-11-16 17:40:06474 EXPECT_EQ("127.0.0.1", response->socket_address.host());
475 EXPECT_EQ(80, response->socket_address.port());
[email protected]6d81b482011-02-22 19:47:19476
ttuttled9dbc652015-09-29 20:00:59477 bool got_endpoint =
bnc691fda62016-08-12 00:43:16478 trans.GetRemoteEndpoint(&out.remote_endpoint_after_start);
ttuttled9dbc652015-09-29 20:00:59479 EXPECT_EQ(got_endpoint,
480 out.remote_endpoint_after_start.address().size() > 0);
481
bnc691fda62016-08-12 00:43:16482 rv = ReadTransaction(&trans, &out.response_data);
robpercival214763f2016-07-01 23:27:01483 EXPECT_THAT(rv, IsOk());
[email protected]b2fcd0e2010-12-01 15:19:40484
mmenke43758e62015-05-04 21:09:46485 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40486 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:39487 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00488 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
489 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:39490 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00491 entries, pos, NetLogEventType::HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
492 NetLogEventPhase::NONE);
[email protected]ff007e162009-05-23 09:13:15493
[email protected]f3da152d2012-06-02 01:00:57494 std::string line;
495 EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
496 EXPECT_EQ("GET / HTTP/1.1\r\n", line);
497
[email protected]79e1fd62013-06-20 06:50:04498 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:16499 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:04500 std::string value;
501 EXPECT_TRUE(request_headers.GetHeader("Host", &value));
bncce36dca22015-04-21 22:11:23502 EXPECT_EQ("www.example.org", value);
[email protected]79e1fd62013-06-20 06:50:04503 EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
504 EXPECT_EQ("keep-alive", value);
505
506 std::string response_headers;
507 EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
bncce36dca22015-04-21 22:11:23508 EXPECT_EQ("['Host: www.example.org','Connection: keep-alive']",
[email protected]79e1fd62013-06-20 06:50:04509 response_headers);
[email protected]3deb9a52010-11-11 00:24:40510
bnc691fda62016-08-12 00:43:16511 out.total_received_bytes = trans.GetTotalReceivedBytes();
sclittlefb249892015-09-10 21:33:22512 // The total number of sent bytes should not have changed.
bnc691fda62016-08-12 00:43:16513 EXPECT_EQ(out.total_sent_bytes, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:22514
bnc691fda62016-08-12 00:43:16515 trans.GetConnectionAttempts(&out.connection_attempts);
[email protected]aecfbf22008-10-16 02:02:47516 return out;
[email protected]ff007e162009-05-23 09:13:15517 }
initial.commit586acc5fe2008-07-26 22:42:52518
Ryan Sleevib8d7ea02018-05-07 20:01:01519 SimpleGetHelperResult SimpleGetHelper(base::span<const MockRead> data_reads) {
sclittlefb249892015-09-10 21:33:22520 MockWrite data_writes[] = {
521 MockWrite("GET / HTTP/1.1\r\n"
522 "Host: www.example.org\r\n"
523 "Connection: keep-alive\r\n\r\n"),
524 };
[email protected]5a60c8b2011-10-19 20:14:29525
Ryan Sleevib8d7ea02018-05-07 20:01:01526 StaticSocketDataProvider reads(data_reads, data_writes);
sclittlefb249892015-09-10 21:33:22527 StaticSocketDataProvider* data[] = {&reads};
Ryan Sleevib8d7ea02018-05-07 20:01:01528 SimpleGetHelperResult out = SimpleGetHelperForData(data);
sclittlefb249892015-09-10 21:33:22529
Ryan Sleevib8d7ea02018-05-07 20:01:01530 EXPECT_EQ(CountWriteBytes(data_writes), out.total_sent_bytes);
sclittlefb249892015-09-10 21:33:22531 return out;
[email protected]b8015c42013-12-24 15:18:19532 }
533
bnc032658ba2016-09-26 18:17:15534 void AddSSLSocketData() {
535 ssl_.next_proto = kProtoHTTP2;
Ryan Sleevi4f832092017-11-21 23:25:49536 ssl_.ssl_info.cert =
537 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
538 ASSERT_TRUE(ssl_.ssl_info.cert);
bnc032658ba2016-09-26 18:17:15539 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_);
540 }
541
[email protected]ff007e162009-05-23 09:13:15542 void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
543 int expected_status);
initial.commit586acc5fe2008-07-26 22:42:52544
[email protected]ff007e162009-05-23 09:13:15545 void ConnectStatusHelper(const MockRead& status);
[email protected]bb88e1d32013-05-03 23:11:07546
[email protected]bb88e1d32013-05-03 23:11:07547 void CheckErrorIsPassedBack(int error, IoMode mode);
548
Douglas Creager134b52e2018-11-09 18:00:14549 // These clocks are defined here, even though they're only used in the
550 // Reporting tests below, since they need to be destroyed after
551 // |session_deps_|.
552 base::SimpleTestClock clock_;
553 base::SimpleTestTickClock tick_clock_;
554
[email protected]4bd46222013-05-14 19:32:23555 SpdyTestUtil spdy_util_;
[email protected]bb88e1d32013-05-03 23:11:07556 SpdySessionDependencies session_deps_;
bnc032658ba2016-09-26 18:17:15557 SSLSocketDataProvider ssl_;
[email protected]483fa202013-05-14 01:07:03558
559 // Original socket limits. Some tests set these. Safest to always restore
560 // them once each test has been run.
561 int old_max_group_sockets_;
562 int old_max_pool_sockets_;
[email protected]ff007e162009-05-23 09:13:15563};
[email protected]231d5a32008-09-13 00:45:27564
[email protected]448d4ca52012-03-04 04:12:23565namespace {
566
ryansturm49a8cb12016-06-15 16:51:09567class BeforeHeadersSentHandler {
[email protected]597a1ab2014-06-26 08:12:27568 public:
ryansturm49a8cb12016-06-15 16:51:09569 BeforeHeadersSentHandler()
570 : observed_before_headers_sent_with_proxy_(false),
571 observed_before_headers_sent_(false) {}
[email protected]597a1ab2014-06-26 08:12:27572
ryansturm49a8cb12016-06-15 16:51:09573 void OnBeforeHeadersSent(const ProxyInfo& proxy_info,
574 HttpRequestHeaders* request_headers) {
575 observed_before_headers_sent_ = true;
576 if (!proxy_info.is_http() && !proxy_info.is_https() &&
577 !proxy_info.is_quic()) {
578 return;
579 }
580 observed_before_headers_sent_with_proxy_ = true;
[email protected]597a1ab2014-06-26 08:12:27581 observed_proxy_server_uri_ = proxy_info.proxy_server().ToURI();
582 }
583
ryansturm49a8cb12016-06-15 16:51:09584 bool observed_before_headers_sent_with_proxy() const {
585 return observed_before_headers_sent_with_proxy_;
586 }
587
588 bool observed_before_headers_sent() const {
589 return observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27590 }
591
592 std::string observed_proxy_server_uri() const {
593 return observed_proxy_server_uri_;
594 }
595
596 private:
ryansturm49a8cb12016-06-15 16:51:09597 bool observed_before_headers_sent_with_proxy_;
598 bool observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27599 std::string observed_proxy_server_uri_;
600
ryansturm49a8cb12016-06-15 16:51:09601 DISALLOW_COPY_AND_ASSIGN(BeforeHeadersSentHandler);
[email protected]597a1ab2014-06-26 08:12:27602};
603
[email protected]15a5ccf82008-10-23 19:57:43604// Fill |str| with a long header list that consumes >= |size| bytes.
605void FillLargeHeadersString(std::string* str, int size) {
thestig9d3bb0c2015-01-24 00:49:51606 const char row[] =
[email protected]4ddaf2502008-10-23 18:26:19607 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
608 const int sizeof_row = strlen(row);
609 const int num_rows = static_cast<int>(
610 ceil(static_cast<float>(size) / sizeof_row));
611 const int sizeof_data = num_rows * sizeof_row;
612 DCHECK(sizeof_data >= size);
[email protected]15a5ccf82008-10-23 19:57:43613 str->reserve(sizeof_data);
[email protected]372d34a2008-11-05 21:30:51614
[email protected]4ddaf2502008-10-23 18:26:19615 for (int i = 0; i < num_rows; ++i)
[email protected]15a5ccf82008-10-23 19:57:43616 str->append(row, sizeof_row);
[email protected]4ddaf2502008-10-23 18:26:19617}
618
thakis84dff942015-07-28 20:47:38619#if defined(NTLM_PORTABLE)
Zentaro Kavanagh6ccee512017-09-28 18:34:09620uint64_t MockGetMSTime() {
621 // Tue, 23 May 2017 20:13:07 +0000
622 return 131400439870000000;
623}
624
[email protected]385a4672009-03-11 22:21:29625// Alternative functions that eliminate randomness and dependency on the local
626// host name so that the generated NTLM messages are reproducible.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:37627void MockGenerateRandom(uint8_t* output, size_t n) {
628 // This is set to 0xaa because the client challenge for testing in
629 // [MS-NLMP] Section 4.2.1 is 8 bytes of 0xaa.
630 memset(output, 0xaa, n);
[email protected]385a4672009-03-11 22:21:29631}
632
[email protected]fe2bc6a2009-03-23 16:52:20633std::string MockGetHostName() {
Zentaro Kavanagh5b27a6e22017-09-25 23:00:37634 return ntlm::test::kHostnameAscii;
[email protected]385a4672009-03-11 22:21:29635}
thakis84dff942015-07-28 20:47:38636#endif // defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29637
[email protected]e60e47a2010-07-14 03:37:18638template<typename ParentPool>
639class CaptureGroupNameSocketPool : public ParentPool {
[email protected]04e5be32009-06-26 20:00:31640 public:
[email protected]9e1bdd32011-02-03 21:48:34641 CaptureGroupNameSocketPool(HostResolver* host_resolver,
642 CertVerifier* cert_verifier);
[email protected]e60e47a2010-07-14 03:37:18643
[email protected]d80a4322009-08-14 07:07:49644 const std::string last_group_name_received() const {
645 return last_group_name_;
646 }
647
Tarun Bansal162eabe52018-01-20 01:16:39648 bool socket_requested() const { return socket_requested_; }
649
dmichaeld6e570d2014-12-18 22:30:57650 int RequestSocket(const std::string& group_name,
651 const void* socket_params,
652 RequestPriority priority,
Paul Jensen8d6f87ec2018-01-13 00:46:54653 const SocketTag& socket_tag,
mmenked3641e12016-01-28 16:06:15654 ClientSocketPool::RespectLimits respect_limits,
dmichaeld6e570d2014-12-18 22:30:57655 ClientSocketHandle* handle,
Bence Béky5a8662b2018-07-03 13:04:03656 CompletionOnceCallback callback,
tfarina42834112016-09-22 13:38:20657 const NetLogWithSource& net_log) override {
[email protected]04e5be32009-06-26 20:00:31658 last_group_name_ = group_name;
Tarun Bansal162eabe52018-01-20 01:16:39659 socket_requested_ = true;
[email protected]04e5be32009-06-26 20:00:31660 return ERR_IO_PENDING;
661 }
dmichaeld6e570d2014-12-18 22:30:57662 void CancelRequest(const std::string& group_name,
663 ClientSocketHandle* handle) override {}
664 void ReleaseSocket(const std::string& group_name,
danakj1fd259a02016-04-16 03:17:09665 std::unique_ptr<StreamSocket> socket,
dmichaeld6e570d2014-12-18 22:30:57666 int id) override {}
667 void CloseIdleSockets() override {}
xunjieli92feb332017-03-03 17:19:23668 void CloseIdleSocketsInGroup(const std::string& group_name) override {}
dmichaeld6e570d2014-12-18 22:30:57669 int IdleSocketCount() const override { return 0; }
670 int IdleSocketCountInGroup(const std::string& group_name) const override {
[email protected]04e5be32009-06-26 20:00:31671 return 0;
672 }
dmichaeld6e570d2014-12-18 22:30:57673 LoadState GetLoadState(const std::string& group_name,
674 const ClientSocketHandle* handle) const override {
[email protected]04e5be32009-06-26 20:00:31675 return LOAD_STATE_IDLE;
676 }
[email protected]d80a4322009-08-14 07:07:49677
678 private:
[email protected]04e5be32009-06-26 20:00:31679 std::string last_group_name_;
Tarun Bansal162eabe52018-01-20 01:16:39680 bool socket_requested_ = false;
[email protected]04e5be32009-06-26 20:00:31681};
682
[email protected]ab739042011-04-07 15:22:28683typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
684CaptureGroupNameTransportSocketPool;
[email protected]e772db3f2010-07-12 18:11:13685typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
686CaptureGroupNameHttpProxySocketPool;
[email protected]2d731a32010-04-29 01:04:06687typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
[email protected]2227c692010-05-04 15:36:11688CaptureGroupNameSOCKSSocketPool;
[email protected]e60e47a2010-07-14 03:37:18689typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
690CaptureGroupNameSSLSocketPool;
691
rkaplowd90695c2015-03-25 22:12:41692template <typename ParentPool>
[email protected]e60e47a2010-07-14 03:37:18693CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34694 HostResolver* host_resolver,
695 CertVerifier* /* cert_verifier */)
tbansal7b403bcc2016-04-13 22:33:21696 : ParentPool(0, 0, host_resolver, NULL, NULL, NULL) {}
[email protected]e60e47a2010-07-14 03:37:18697
hashimoto0d3e4fb2015-01-09 05:02:50698template <>
[email protected]2df19bb2010-08-25 20:13:46699CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21700 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34701 CertVerifier* /* cert_verifier */)
Wojciech Dzierżanowski1f823562019-01-18 11:26:00702 : HttpProxyClientSocketPool(0, 0, NULL, NULL, NULL, NULL, NULL) {}
[email protected]2df19bb2010-08-25 20:13:46703
[email protected]007b3f82013-04-09 08:46:45704template <>
[email protected]e60e47a2010-07-14 03:37:18705CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21706 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34707 CertVerifier* cert_verifier)
[email protected]007b3f82013-04-09 08:46:45708 : SSLClientSocketPool(0,
709 0,
[email protected]007b3f82013-04-09 08:46:45710 cert_verifier,
711 NULL,
712 NULL,
[email protected]284303b62013-11-28 15:11:54713 NULL,
eranm6571b2b2014-12-03 15:53:23714 NULL,
[email protected]007b3f82013-04-09 08:46:45715 std::string(),
716 NULL,
717 NULL,
718 NULL,
719 NULL,
720 NULL,
Matt Menkec621aead02019-01-10 02:06:15721 NULL,
722 NULL) {}
[email protected]2227c692010-05-04 15:36:11723
[email protected]231d5a32008-09-13 00:45:27724//-----------------------------------------------------------------------------
725
[email protected]79cb5c12011-09-12 13:12:04726// Helper functions for validating that AuthChallengeInfo's are correctly
727// configured for common cases.
728bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
729 if (!auth_challenge)
730 return false;
731 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43732 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04733 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19734 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04735 return true;
736}
737
738bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
739 if (!auth_challenge)
740 return false;
741 EXPECT_TRUE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43742 EXPECT_EQ("http://myproxy:70", auth_challenge->challenger.Serialize());
743 EXPECT_EQ("MyRealm1", auth_challenge->realm);
744 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
745 return true;
746}
747
748bool CheckBasicSecureProxyAuth(const AuthChallengeInfo* auth_challenge) {
749 if (!auth_challenge)
750 return false;
751 EXPECT_TRUE(auth_challenge->is_proxy);
752 EXPECT_EQ("https://myproxy:70", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04753 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19754 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04755 return true;
756}
757
758bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
759 if (!auth_challenge)
760 return false;
761 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43762 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04763 EXPECT_EQ("digestive", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19764 EXPECT_EQ(kDigestAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04765 return true;
766}
767
thakis84dff942015-07-28 20:47:38768#if defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04769bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
770 if (!auth_challenge)
771 return false;
772 EXPECT_FALSE(auth_challenge->is_proxy);
Zentaro Kavanagh1890a3d2018-01-29 19:52:55773 EXPECT_EQ("https://server", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04774 EXPECT_EQ(std::string(), auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19775 EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04776 return true;
777}
David Benjamin5cb91132018-04-06 05:54:49778
779bool CheckNTLMProxyAuth(const AuthChallengeInfo* auth_challenge) {
780 if (!auth_challenge)
781 return false;
782 EXPECT_TRUE(auth_challenge->is_proxy);
783 EXPECT_EQ("http://server", auth_challenge->challenger.Serialize());
784 EXPECT_EQ(std::string(), auth_challenge->realm);
785 EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
786 return true;
787}
thakis84dff942015-07-28 20:47:38788#endif // defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04789
[email protected]448d4ca52012-03-04 04:12:23790} // namespace
791
bncd16676a2016-07-20 16:23:01792TEST_F(HttpNetworkTransactionTest, Basic) {
danakj1fd259a02016-04-16 03:17:09793 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16794 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]231d5a32008-09-13 00:45:27795}
796
bncd16676a2016-07-20 16:23:01797TEST_F(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27798 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35799 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
800 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06801 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27802 };
Ryan Sleevib8d7ea02018-05-07 20:01:01803 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01804 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27805 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
806 EXPECT_EQ("hello world", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01807 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22808 EXPECT_EQ(reads_size, out.total_received_bytes);
ttuttle1f2d7e92015-04-28 16:17:47809 EXPECT_EQ(0u, out.connection_attempts.size());
ttuttled9dbc652015-09-29 20:00:59810
811 EXPECT_FALSE(out.remote_endpoint_after_start.address().empty());
[email protected]231d5a32008-09-13 00:45:27812}
813
814// Response with no status line.
bncd16676a2016-07-20 16:23:01815TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27816 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35817 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06818 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27819 };
Ryan Sleevib8d7ea02018-05-07 20:01:01820 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41821 EXPECT_THAT(out.rv, IsOk());
822 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
823 EXPECT_EQ("hello world", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01824 int64_t reads_size = CountReadBytes(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41825 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27826}
827
mmenkea7da6da2016-09-01 21:56:52828// Response with no status line, and a weird port. Should fail by default.
829TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPort) {
830 MockRead data_reads[] = {
831 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
832 };
833
Ryan Sleevib8d7ea02018-05-07 20:01:01834 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
mmenkea7da6da2016-09-01 21:56:52835 session_deps_.socket_factory->AddSocketDataProvider(&data);
836
837 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
838
krasinc06a72a2016-12-21 03:42:46839 HttpRequestInfo request;
bnc87dcefc2017-05-25 12:47:58840 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:19841 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenkea7da6da2016-09-01 21:56:52842
mmenkea7da6da2016-09-01 21:56:52843 request.method = "GET";
844 request.url = GURL("http://www.example.com:2000/");
Ramin Halavatib5e433e2018-02-07 07:41:10845 request.traffic_annotation =
846 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
847
mmenkea7da6da2016-09-01 21:56:52848 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20849 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52850 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_INVALID_HTTP_RESPONSE));
851}
852
Shivani Sharmafdcaefd2017-11-02 00:12:26853// Tests that request info can be destroyed after the headers phase is complete.
854TEST_F(HttpNetworkTransactionTest, SimpleGETNoReadDestroyRequestInfo) {
855 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
856 auto trans =
857 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
858
859 MockRead data_reads[] = {
860 MockRead("HTTP/1.0 200 OK\r\n"), MockRead("Connection: keep-alive\r\n"),
861 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, 0),
862 };
Ryan Sleevib8d7ea02018-05-07 20:01:01863 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
Shivani Sharmafdcaefd2017-11-02 00:12:26864 session_deps_.socket_factory->AddSocketDataProvider(&data);
865
866 TestCompletionCallback callback;
867
868 {
869 auto request = std::make_unique<HttpRequestInfo>();
870 request->method = "GET";
871 request->url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:10872 request->traffic_annotation =
873 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Shivani Sharmafdcaefd2017-11-02 00:12:26874
875 int rv =
876 trans->Start(request.get(), callback.callback(), NetLogWithSource());
877
878 EXPECT_THAT(callback.GetResult(rv), IsOk());
879 } // Let request info be destroyed.
880
881 trans.reset();
882}
883
mmenkea7da6da2016-09-01 21:56:52884// Response with no status line, and a weird port. Option to allow weird ports
885// enabled.
886TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPortAllowed) {
887 MockRead data_reads[] = {
888 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
889 };
890
Ryan Sleevib8d7ea02018-05-07 20:01:01891 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
mmenkea7da6da2016-09-01 21:56:52892 session_deps_.socket_factory->AddSocketDataProvider(&data);
893 session_deps_.http_09_on_non_default_ports_enabled = true;
894 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
895
krasinc06a72a2016-12-21 03:42:46896 HttpRequestInfo request;
bnc87dcefc2017-05-25 12:47:58897 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:19898 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenkea7da6da2016-09-01 21:56:52899
mmenkea7da6da2016-09-01 21:56:52900 request.method = "GET";
901 request.url = GURL("http://www.example.com:2000/");
Ramin Halavatib5e433e2018-02-07 07:41:10902 request.traffic_annotation =
903 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
904
mmenkea7da6da2016-09-01 21:56:52905 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20906 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52907 EXPECT_THAT(callback.GetResult(rv), IsOk());
908
909 const HttpResponseInfo* info = trans->GetResponseInfo();
910 ASSERT_TRUE(info->headers);
911 EXPECT_EQ("HTTP/0.9 200 OK", info->headers->GetStatusLine());
912
913 // Don't bother to read the body - that's verified elsewhere, important thing
914 // is that the option to allow HTTP/0.9 on non-default ports is respected.
915}
916
[email protected]231d5a32008-09-13 00:45:27917// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01918TEST_F(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27919 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35920 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06921 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27922 };
Ryan Sleevib8d7ea02018-05-07 20:01:01923 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01924 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27925 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
926 EXPECT_EQ("DATA", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01927 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22928 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27929}
930
931// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01932TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27933 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35934 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06935 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27936 };
Ryan Sleevib8d7ea02018-05-07 20:01:01937 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01938 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27939 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
940 EXPECT_EQ("DATA", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01941 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22942 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27943}
944
945// Beyond 4 bytes of slop and it should fail to find a status line.
bncd16676a2016-07-20 16:23:01946TEST_F(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27947 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35948 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06949 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27950 };
Ryan Sleevib8d7ea02018-05-07 20:01:01951 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41952 EXPECT_THAT(out.rv, IsOk());
953 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
954 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01955 int64_t reads_size = CountReadBytes(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41956 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27957}
958
959// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
bncd16676a2016-07-20 16:23:01960TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27961 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35962 MockRead("\n"),
963 MockRead("\n"),
964 MockRead("Q"),
965 MockRead("J"),
966 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06967 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27968 };
Ryan Sleevib8d7ea02018-05-07 20:01:01969 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01970 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27971 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
972 EXPECT_EQ("DATA", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01973 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22974 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27975}
976
977// Close the connection before enough bytes to have a status line.
bncd16676a2016-07-20 16:23:01978TEST_F(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:27979 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35980 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:06981 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27982 };
Ryan Sleevib8d7ea02018-05-07 20:01:01983 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41984 EXPECT_THAT(out.rv, IsOk());
985 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
986 EXPECT_EQ("HTT", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01987 int64_t reads_size = CountReadBytes(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41988 EXPECT_EQ(reads_size, out.total_received_bytes);
initial.commit586acc5fe2008-07-26 22:42:52989}
990
[email protected]f9d44aa2008-09-23 23:57:17991// Simulate a 204 response, lacking a Content-Length header, sent over a
992// persistent connection. The response should still terminate since a 204
993// cannot have a response body.
bncd16676a2016-07-20 16:23:01994TEST_F(HttpNetworkTransactionTest, StopsReading204) {
[email protected]b8015c42013-12-24 15:18:19995 char junk[] = "junk";
[email protected]f9d44aa2008-09-23 23:57:17996 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35997 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
[email protected]b8015c42013-12-24 15:18:19998 MockRead(junk), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:06999 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:171000 };
Ryan Sleevib8d7ea02018-05-07 20:01:011001 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011002 EXPECT_THAT(out.rv, IsOk());
[email protected]f9d44aa2008-09-23 23:57:171003 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
1004 EXPECT_EQ("", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:011005 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:221006 int64_t response_size = reads_size - strlen(junk);
1007 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]f9d44aa2008-09-23 23:57:171008}
1009
[email protected]0877e3d2009-10-17 22:29:571010// A simple request using chunked encoding with some extra data after.
bncd16676a2016-07-20 16:23:011011TEST_F(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]b8015c42013-12-24 15:18:191012 std::string final_chunk = "0\r\n\r\n";
1013 std::string extra_data = "HTTP/1.1 200 OK\r\n";
1014 std::string last_read = final_chunk + extra_data;
[email protected]0877e3d2009-10-17 22:29:571015 MockRead data_reads[] = {
1016 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
1017 MockRead("5\r\nHello\r\n"),
1018 MockRead("1\r\n"),
1019 MockRead(" \r\n"),
1020 MockRead("5\r\nworld\r\n"),
[email protected]b8015c42013-12-24 15:18:191021 MockRead(last_read.data()),
[email protected]8ddf8322012-02-23 18:08:061022 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:571023 };
Ryan Sleevib8d7ea02018-05-07 20:01:011024 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011025 EXPECT_THAT(out.rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:571026 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1027 EXPECT_EQ("Hello world", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:011028 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:221029 int64_t response_size = reads_size - extra_data.size();
1030 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]0877e3d2009-10-17 22:29:571031}
1032
[email protected]9fe44f52010-09-23 18:36:001033// Next tests deal with http://crbug.com/56344.
1034
bncd16676a2016-07-20 16:23:011035TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001036 MultipleContentLengthHeadersNoTransferEncoding) {
1037 MockRead data_reads[] = {
1038 MockRead("HTTP/1.1 200 OK\r\n"),
1039 MockRead("Content-Length: 10\r\n"),
1040 MockRead("Content-Length: 5\r\n\r\n"),
1041 };
Ryan Sleevib8d7ea02018-05-07 20:01:011042 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011043 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]9fe44f52010-09-23 18:36:001044}
1045
bncd16676a2016-07-20 16:23:011046TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:041047 DuplicateContentLengthHeadersNoTransferEncoding) {
1048 MockRead data_reads[] = {
1049 MockRead("HTTP/1.1 200 OK\r\n"),
1050 MockRead("Content-Length: 5\r\n"),
1051 MockRead("Content-Length: 5\r\n\r\n"),
1052 MockRead("Hello"),
1053 };
Ryan Sleevib8d7ea02018-05-07 20:01:011054 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011055 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041056 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1057 EXPECT_EQ("Hello", out.response_data);
1058}
1059
bncd16676a2016-07-20 16:23:011060TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:041061 ComplexContentLengthHeadersNoTransferEncoding) {
1062 // More than 2 dupes.
1063 {
1064 MockRead data_reads[] = {
1065 MockRead("HTTP/1.1 200 OK\r\n"),
1066 MockRead("Content-Length: 5\r\n"),
1067 MockRead("Content-Length: 5\r\n"),
1068 MockRead("Content-Length: 5\r\n\r\n"),
1069 MockRead("Hello"),
1070 };
Ryan Sleevib8d7ea02018-05-07 20:01:011071 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011072 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041073 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1074 EXPECT_EQ("Hello", out.response_data);
1075 }
1076 // HTTP/1.0
1077 {
1078 MockRead data_reads[] = {
1079 MockRead("HTTP/1.0 200 OK\r\n"),
1080 MockRead("Content-Length: 5\r\n"),
1081 MockRead("Content-Length: 5\r\n"),
1082 MockRead("Content-Length: 5\r\n\r\n"),
1083 MockRead("Hello"),
1084 };
Ryan Sleevib8d7ea02018-05-07 20:01:011085 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011086 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041087 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
1088 EXPECT_EQ("Hello", out.response_data);
1089 }
1090 // 2 dupes and one mismatched.
1091 {
1092 MockRead data_reads[] = {
1093 MockRead("HTTP/1.1 200 OK\r\n"),
1094 MockRead("Content-Length: 10\r\n"),
1095 MockRead("Content-Length: 10\r\n"),
1096 MockRead("Content-Length: 5\r\n\r\n"),
1097 };
Ryan Sleevib8d7ea02018-05-07 20:01:011098 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011099 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]44b52042010-10-29 22:48:041100 }
1101}
1102
bncd16676a2016-07-20 16:23:011103TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001104 MultipleContentLengthHeadersTransferEncoding) {
1105 MockRead data_reads[] = {
1106 MockRead("HTTP/1.1 200 OK\r\n"),
1107 MockRead("Content-Length: 666\r\n"),
1108 MockRead("Content-Length: 1337\r\n"),
1109 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
1110 MockRead("5\r\nHello\r\n"),
1111 MockRead("1\r\n"),
1112 MockRead(" \r\n"),
1113 MockRead("5\r\nworld\r\n"),
1114 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:061115 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:001116 };
Ryan Sleevib8d7ea02018-05-07 20:01:011117 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011118 EXPECT_THAT(out.rv, IsOk());
[email protected]9fe44f52010-09-23 18:36:001119 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1120 EXPECT_EQ("Hello world", out.response_data);
1121}
1122
[email protected]1628fe92011-10-04 23:04:551123// Next tests deal with http://crbug.com/98895.
1124
1125// Checks that a single Content-Disposition header results in no error.
bncd16676a2016-07-20 16:23:011126TEST_F(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:551127 MockRead data_reads[] = {
1128 MockRead("HTTP/1.1 200 OK\r\n"),
1129 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
1130 MockRead("Content-Length: 5\r\n\r\n"),
1131 MockRead("Hello"),
1132 };
Ryan Sleevib8d7ea02018-05-07 20:01:011133 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011134 EXPECT_THAT(out.rv, IsOk());
[email protected]1628fe92011-10-04 23:04:551135 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1136 EXPECT_EQ("Hello", out.response_data);
1137}
1138
[email protected]54a9c6e52012-03-21 20:10:591139// Checks that two identical Content-Disposition headers result in no error.
bncd16676a2016-07-20 16:23:011140TEST_F(HttpNetworkTransactionTest, TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551141 MockRead data_reads[] = {
1142 MockRead("HTTP/1.1 200 OK\r\n"),
1143 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1144 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1145 MockRead("Content-Length: 5\r\n\r\n"),
1146 MockRead("Hello"),
1147 };
Ryan Sleevib8d7ea02018-05-07 20:01:011148 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011149 EXPECT_THAT(out.rv, IsOk());
[email protected]54a9c6e52012-03-21 20:10:591150 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1151 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:551152}
1153
1154// Checks that two distinct Content-Disposition headers result in an error.
bncd16676a2016-07-20 16:23:011155TEST_F(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551156 MockRead data_reads[] = {
1157 MockRead("HTTP/1.1 200 OK\r\n"),
1158 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1159 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
1160 MockRead("Content-Length: 5\r\n\r\n"),
1161 MockRead("Hello"),
1162 };
Ryan Sleevib8d7ea02018-05-07 20:01:011163 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011164 EXPECT_THAT(out.rv,
1165 IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION));
[email protected]1628fe92011-10-04 23:04:551166}
1167
[email protected]54a9c6e52012-03-21 20:10:591168// Checks that two identical Location headers result in no error.
1169// Also tests Location header behavior.
bncd16676a2016-07-20 16:23:011170TEST_F(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551171 MockRead data_reads[] = {
1172 MockRead("HTTP/1.1 302 Redirect\r\n"),
1173 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:591174 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:551175 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061176 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551177 };
1178
1179 HttpRequestInfo request;
1180 request.method = "GET";
1181 request.url = GURL("http://redirect.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101182 request.traffic_annotation =
1183 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1628fe92011-10-04 23:04:551184
danakj1fd259a02016-04-16 03:17:091185 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161186 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1628fe92011-10-04 23:04:551187
Ryan Sleevib8d7ea02018-05-07 20:01:011188 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071189 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:551190
[email protected]49639fa2011-12-20 23:22:411191 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:551192
tfarina42834112016-09-22 13:38:201193 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011194 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1628fe92011-10-04 23:04:551195
robpercival214763f2016-07-01 23:27:011196 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]1628fe92011-10-04 23:04:551197
bnc691fda62016-08-12 00:43:161198 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521199 ASSERT_TRUE(response);
1200 ASSERT_TRUE(response->headers);
[email protected]1628fe92011-10-04 23:04:551201 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
1202 std::string url;
1203 EXPECT_TRUE(response->headers->IsRedirect(&url));
1204 EXPECT_EQ("http://good.com/", url);
tbansal2ecbbc72016-10-06 17:15:471205 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]1628fe92011-10-04 23:04:551206}
1207
[email protected]1628fe92011-10-04 23:04:551208// Checks that two distinct Location headers result in an error.
bncd16676a2016-07-20 16:23:011209TEST_F(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551210 MockRead data_reads[] = {
1211 MockRead("HTTP/1.1 302 Redirect\r\n"),
1212 MockRead("Location: http://good.com/\r\n"),
1213 MockRead("Location: http://evil.com/\r\n"),
1214 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061215 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551216 };
Ryan Sleevib8d7ea02018-05-07 20:01:011217 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011218 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION));
[email protected]1628fe92011-10-04 23:04:551219}
1220
[email protected]ef0faf2e72009-03-05 23:27:231221// Do a request using the HEAD method. Verify that we don't try to read the
1222// message body (since HEAD has none).
bncd16676a2016-07-20 16:23:011223TEST_F(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:421224 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:231225 request.method = "HEAD";
bncce36dca22015-04-21 22:11:231226 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:101227 request.traffic_annotation =
1228 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ef0faf2e72009-03-05 23:27:231229
danakj1fd259a02016-04-16 03:17:091230 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161231 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:091232 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:161233 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:091234 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
1235 base::Unretained(&headers_handler)));
[email protected]cb9bf6ca2011-01-28 13:15:271236
[email protected]ef0faf2e72009-03-05 23:27:231237 MockWrite data_writes1[] = {
csharrisonf473dd192015-08-18 13:54:131238 MockWrite("HEAD / HTTP/1.1\r\n"
1239 "Host: www.example.org\r\n"
1240 "Connection: keep-alive\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231241 };
1242 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:231243 MockRead("HTTP/1.1 404 Not Found\r\n"), MockRead("Server: Blah\r\n"),
1244 MockRead("Content-Length: 1234\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231245
mmenked39192ee2015-12-09 00:57:231246 // No response body because the test stops reading here.
1247 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]ef0faf2e72009-03-05 23:27:231248 };
1249
Ryan Sleevib8d7ea02018-05-07 20:01:011250 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:071251 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:231252
[email protected]49639fa2011-12-20 23:22:411253 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:231254
tfarina42834112016-09-22 13:38:201255 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011256 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ef0faf2e72009-03-05 23:27:231257
1258 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:011259 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231260
bnc691fda62016-08-12 00:43:161261 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521262 ASSERT_TRUE(response);
[email protected]ef0faf2e72009-03-05 23:27:231263
1264 // Check that the headers got parsed.
wezca1070932016-05-26 20:30:521265 EXPECT_TRUE(response->headers);
[email protected]ef0faf2e72009-03-05 23:27:231266 EXPECT_EQ(1234, response->headers->GetContentLength());
1267 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471268 EXPECT_TRUE(response->proxy_server.is_direct());
ryansturm49a8cb12016-06-15 16:51:091269 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
1270 EXPECT_FALSE(headers_handler.observed_before_headers_sent_with_proxy());
[email protected]ef0faf2e72009-03-05 23:27:231271
1272 std::string server_header;
olli.raulaee489a52016-01-25 08:37:101273 size_t iter = 0;
[email protected]ef0faf2e72009-03-05 23:27:231274 bool has_server_header = response->headers->EnumerateHeader(
1275 &iter, "Server", &server_header);
1276 EXPECT_TRUE(has_server_header);
1277 EXPECT_EQ("Blah", server_header);
1278
1279 // Reading should give EOF right away, since there is no message body
1280 // (despite non-zero content-length).
1281 std::string response_data;
bnc691fda62016-08-12 00:43:161282 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011283 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231284 EXPECT_EQ("", response_data);
1285}
1286
bncd16676a2016-07-20 16:23:011287TEST_F(HttpNetworkTransactionTest, ReuseConnection) {
danakj1fd259a02016-04-16 03:17:091288 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:521289
1290 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351291 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1292 MockRead("hello"),
1293 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1294 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061295 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521296 };
Ryan Sleevib8d7ea02018-05-07 20:01:011297 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071298 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521299
[email protected]0b0bf032010-09-21 18:08:501300 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521301 "hello", "world"
1302 };
1303
1304 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:421305 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521306 request.method = "GET";
bncce36dca22015-04-21 22:11:231307 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:101308 request.traffic_annotation =
1309 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:521310
bnc691fda62016-08-12 00:43:161311 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271312
[email protected]49639fa2011-12-20 23:22:411313 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521314
tfarina42834112016-09-22 13:38:201315 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011316 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521317
1318 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011319 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521320
bnc691fda62016-08-12 00:43:161321 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521322 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521323
wezca1070932016-05-26 20:30:521324 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251325 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471326 EXPECT_TRUE(response->proxy_server.is_direct());
initial.commit586acc5fe2008-07-26 22:42:521327
1328 std::string response_data;
bnc691fda62016-08-12 00:43:161329 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011330 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251331 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521332 }
1333}
1334
bncd16676a2016-07-20 16:23:011335TEST_F(HttpNetworkTransactionTest, Ignores100) {
danakj1fd259a02016-04-16 03:17:091336 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:221337 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:191338 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:221339 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:271340
[email protected]1c773ea12009-04-28 19:58:421341 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521342 request.method = "POST";
1343 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271344 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:101345 request.traffic_annotation =
1346 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:521347
shivanishab9a143952016-09-19 17:23:411348 // Check the upload progress returned before initialization is correct.
1349 UploadProgress progress = request.upload_data_stream->GetUploadProgress();
1350 EXPECT_EQ(0u, progress.size());
1351 EXPECT_EQ(0u, progress.position());
1352
danakj1fd259a02016-04-16 03:17:091353 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161354 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271355
initial.commit586acc5fe2008-07-26 22:42:521356 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351357 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1358 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1359 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061360 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521361 };
Ryan Sleevib8d7ea02018-05-07 20:01:011362 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071363 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521364
[email protected]49639fa2011-12-20 23:22:411365 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521366
tfarina42834112016-09-22 13:38:201367 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011368 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521369
1370 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011371 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521372
bnc691fda62016-08-12 00:43:161373 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521374 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521375
wezca1070932016-05-26 20:30:521376 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251377 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521378
1379 std::string response_data;
bnc691fda62016-08-12 00:43:161380 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011381 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251382 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521383}
1384
[email protected]3a2d3662009-03-27 03:49:141385// This test is almost the same as Ignores100 above, but the response contains
1386// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571387// HTTP/1.1 and the two status headers are read in one read.
bncd16676a2016-07-20 16:23:011388TEST_F(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421389 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141390 request.method = "GET";
1391 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101392 request.traffic_annotation =
1393 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3a2d3662009-03-27 03:49:141394
danakj1fd259a02016-04-16 03:17:091395 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161396 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271397
[email protected]3a2d3662009-03-27 03:49:141398 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571399 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1400 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141401 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061402 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141403 };
Ryan Sleevib8d7ea02018-05-07 20:01:011404 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071405 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141406
[email protected]49639fa2011-12-20 23:22:411407 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141408
tfarina42834112016-09-22 13:38:201409 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011410 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3a2d3662009-03-27 03:49:141411
1412 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011413 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141414
bnc691fda62016-08-12 00:43:161415 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521416 ASSERT_TRUE(response);
[email protected]3a2d3662009-03-27 03:49:141417
wezca1070932016-05-26 20:30:521418 EXPECT_TRUE(response->headers);
[email protected]3a2d3662009-03-27 03:49:141419 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1420
1421 std::string response_data;
bnc691fda62016-08-12 00:43:161422 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011423 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141424 EXPECT_EQ("hello world", response_data);
1425}
1426
Andrew Comminos517a92c2019-01-14 17:49:561427TEST_F(HttpNetworkTransactionTest, LoadTimingMeasuresTimeToFirstByteForHttp) {
1428 static const base::TimeDelta kDelayAfterFirstByte =
Andrew Comminos1f2ff1cc2018-12-14 05:22:381429 base::TimeDelta::FromMilliseconds(10);
1430
1431 HttpRequestInfo request;
1432 request.method = "GET";
1433 request.url = GURL("http://www.foo.com/");
1434 request.traffic_annotation =
1435 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1436
1437 std::vector<MockWrite> data_writes = {
1438 MockWrite(ASYNC, 0,
1439 "GET / HTTP/1.1\r\n"
1440 "Host: www.foo.com\r\n"
1441 "Connection: keep-alive\r\n\r\n"),
1442 };
1443
1444 std::vector<MockRead> data_reads = {
1445 // Write one byte of the status line, followed by a pause.
1446 MockRead(ASYNC, 1, "H"),
1447 MockRead(ASYNC, ERR_IO_PENDING, 2),
1448 MockRead(ASYNC, 3, "TTP/1.1 200 OK\r\n\r\n"),
1449 MockRead(ASYNC, 4, "hello world"),
1450 MockRead(SYNCHRONOUS, OK, 5),
1451 };
1452
1453 SequencedSocketData data(data_reads, data_writes);
1454 session_deps_.socket_factory->AddSocketDataProvider(&data);
1455
1456 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1457
1458 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1459
1460 TestCompletionCallback callback;
1461
1462 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1463 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1464
1465 data.RunUntilPaused();
1466 ASSERT_TRUE(data.IsPaused());
Andrew Comminos517a92c2019-01-14 17:49:561467 FastForwardBy(kDelayAfterFirstByte);
Andrew Comminos1f2ff1cc2018-12-14 05:22:381468 data.Resume();
1469
1470 rv = callback.WaitForResult();
1471 EXPECT_THAT(rv, IsOk());
1472
1473 const HttpResponseInfo* response = trans.GetResponseInfo();
1474 ASSERT_TRUE(response);
1475
1476 EXPECT_TRUE(response->headers);
1477 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1478
1479 LoadTimingInfo load_timing_info;
1480 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
1481 EXPECT_FALSE(load_timing_info.receive_headers_start.is_null());
1482 EXPECT_FALSE(load_timing_info.connect_timing.connect_end.is_null());
Andrew Comminos517a92c2019-01-14 17:49:561483 // Ensure we didn't include the delay in the TTFB time.
1484 EXPECT_EQ(load_timing_info.receive_headers_start,
1485 load_timing_info.connect_timing.connect_end);
1486 // Ensure that the mock clock advanced at all.
1487 EXPECT_EQ(base::TimeTicks::Now() - load_timing_info.receive_headers_start,
1488 kDelayAfterFirstByte);
Andrew Comminos1f2ff1cc2018-12-14 05:22:381489
1490 std::string response_data;
1491 rv = ReadTransaction(&trans, &response_data);
1492 EXPECT_THAT(rv, IsOk());
1493 EXPECT_EQ("hello world", response_data);
1494}
1495
1496// Tests that the time-to-first-byte reported in a transaction's load timing
1497// info uses the first response, even if 1XX/informational.
1498void HttpNetworkTransactionTest::Check100ResponseTiming(bool use_spdy) {
Andrew Comminos517a92c2019-01-14 17:49:561499 static const base::TimeDelta kDelayAfter100Response =
Andrew Comminos1f2ff1cc2018-12-14 05:22:381500 base::TimeDelta::FromMilliseconds(10);
1501
1502 HttpRequestInfo request;
1503 request.method = "GET";
1504 request.url = GURL("https://www.foo.com/");
1505 request.traffic_annotation =
1506 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1507
1508 SSLSocketDataProvider ssl(ASYNC, OK);
1509 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
1510
1511 std::vector<MockWrite> data_writes;
1512 std::vector<MockRead> data_reads;
1513
1514 spdy::SpdySerializedFrame spdy_req(
1515 spdy_util_.ConstructSpdyGet(request.url.spec().c_str(), 1, LOWEST));
1516
1517 spdy::SpdyHeaderBlock spdy_resp1_headers;
1518 spdy_resp1_headers[spdy::kHttp2StatusHeader] = "100";
1519 spdy::SpdySerializedFrame spdy_resp1(
1520 spdy_util_.ConstructSpdyReply(1, spdy_resp1_headers.Clone()));
1521 spdy::SpdySerializedFrame spdy_resp2(
1522 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
1523 spdy::SpdySerializedFrame spdy_data(
1524 spdy_util_.ConstructSpdyDataFrame(1, "hello world", true));
1525
1526 if (use_spdy) {
1527 ssl.next_proto = kProtoHTTP2;
1528
1529 data_writes = {CreateMockWrite(spdy_req, 0)};
1530
1531 data_reads = {
1532 CreateMockRead(spdy_resp1, 1), MockRead(ASYNC, ERR_IO_PENDING, 2),
1533 CreateMockRead(spdy_resp2, 3), CreateMockRead(spdy_data, 4),
1534 MockRead(SYNCHRONOUS, OK, 5),
1535 };
1536 } else {
1537 data_writes = {
1538 MockWrite(ASYNC, 0,
1539 "GET / HTTP/1.1\r\n"
1540 "Host: www.foo.com\r\n"
1541 "Connection: keep-alive\r\n\r\n"),
1542 };
1543
1544 data_reads = {
1545 MockRead(ASYNC, 1, "HTTP/1.1 100 Continue\r\n\r\n"),
1546 MockRead(ASYNC, ERR_IO_PENDING, 2),
1547
1548 MockRead(ASYNC, 3, "HTTP/1.1 200 OK\r\n\r\n"),
1549 MockRead(ASYNC, 4, "hello world"),
1550 MockRead(SYNCHRONOUS, OK, 5),
1551 };
1552 }
1553
1554 SequencedSocketData data(data_reads, data_writes);
1555 session_deps_.socket_factory->AddSocketDataProvider(&data);
1556
1557 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1558
1559 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1560
1561 TestCompletionCallback callback;
1562
1563 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1564 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1565
1566 data.RunUntilPaused();
1567 // We should now have parsed the 100 response and hit ERR_IO_PENDING. Insert
1568 // the delay before parsing the 200 response.
1569 ASSERT_TRUE(data.IsPaused());
Andrew Comminos517a92c2019-01-14 17:49:561570 FastForwardBy(kDelayAfter100Response);
Andrew Comminos1f2ff1cc2018-12-14 05:22:381571 data.Resume();
1572
1573 rv = callback.WaitForResult();
1574 EXPECT_THAT(rv, IsOk());
1575
1576 const HttpResponseInfo* response = trans.GetResponseInfo();
1577 ASSERT_TRUE(response);
1578
1579 LoadTimingInfo load_timing_info;
1580 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
1581 EXPECT_FALSE(load_timing_info.receive_headers_start.is_null());
1582 EXPECT_FALSE(load_timing_info.connect_timing.connect_end.is_null());
Andrew Comminos517a92c2019-01-14 17:49:561583 // Ensure we didn't include the delay in the TTFB time.
1584 EXPECT_EQ(load_timing_info.receive_headers_start,
1585 load_timing_info.connect_timing.connect_end);
1586 // Ensure that the mock clock advanced at all.
1587 EXPECT_EQ(base::TimeTicks::Now() - load_timing_info.receive_headers_start,
1588 kDelayAfter100Response);
Andrew Comminos1f2ff1cc2018-12-14 05:22:381589
1590 std::string response_data;
1591 rv = ReadTransaction(&trans, &response_data);
1592 EXPECT_THAT(rv, IsOk());
1593 EXPECT_EQ("hello world", response_data);
1594}
1595
Andrew Comminos517a92c2019-01-14 17:49:561596TEST_F(HttpNetworkTransactionTest, MeasuresTimeToFirst100ResponseForHttp) {
Andrew Comminos1f2ff1cc2018-12-14 05:22:381597 Check100ResponseTiming(false /* use_spdy */);
1598}
1599
Andrew Comminos517a92c2019-01-14 17:49:561600TEST_F(HttpNetworkTransactionTest, MeasuresTimeToFirst100ResponseForSpdy) {
Andrew Comminos1f2ff1cc2018-12-14 05:22:381601 Check100ResponseTiming(true /* use_spdy */);
1602}
1603
bncd16676a2016-07-20 16:23:011604TEST_F(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
zmo9528c9f42015-08-04 22:12:081605 HttpRequestInfo request;
1606 request.method = "POST";
1607 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101608 request.traffic_annotation =
1609 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
zmo9528c9f42015-08-04 22:12:081610
danakj1fd259a02016-04-16 03:17:091611 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161612 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zmo9528c9f42015-08-04 22:12:081613
1614 MockRead data_reads[] = {
1615 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1616 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381617 };
Ryan Sleevib8d7ea02018-05-07 20:01:011618 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
zmo9528c9f42015-08-04 22:12:081619 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381620
zmo9528c9f42015-08-04 22:12:081621 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381622
tfarina42834112016-09-22 13:38:201623 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011624 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381625
zmo9528c9f42015-08-04 22:12:081626 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011627 EXPECT_THAT(rv, IsOk());
[email protected]ee9410e72010-01-07 01:42:381628
zmo9528c9f42015-08-04 22:12:081629 std::string response_data;
bnc691fda62016-08-12 00:43:161630 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011631 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:081632 EXPECT_EQ("", response_data);
[email protected]ee9410e72010-01-07 01:42:381633}
1634
bncd16676a2016-07-20 16:23:011635TEST_F(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381636 HttpRequestInfo request;
1637 request.method = "POST";
1638 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101639 request.traffic_annotation =
1640 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ee9410e72010-01-07 01:42:381641
danakj1fd259a02016-04-16 03:17:091642 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161643 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271644
[email protected]ee9410e72010-01-07 01:42:381645 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061646 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381647 };
Ryan Sleevib8d7ea02018-05-07 20:01:011648 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071649 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381650
[email protected]49639fa2011-12-20 23:22:411651 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381652
tfarina42834112016-09-22 13:38:201653 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011654 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381655
1656 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011657 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]ee9410e72010-01-07 01:42:381658}
1659
[email protected]23e482282013-06-14 16:08:021660void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511661 const MockWrite* write_failure,
1662 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421663 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521664 request.method = "GET";
1665 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101666 request.traffic_annotation =
1667 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:521668
vishal.b62985ca92015-04-17 08:45:511669 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071670 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091671 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271672
[email protected]202965992011-12-07 23:04:511673 // Written data for successfully sending both requests.
1674 MockWrite data1_writes[] = {
1675 MockWrite("GET / HTTP/1.1\r\n"
1676 "Host: www.foo.com\r\n"
1677 "Connection: keep-alive\r\n\r\n"),
1678 MockWrite("GET / HTTP/1.1\r\n"
1679 "Host: www.foo.com\r\n"
1680 "Connection: keep-alive\r\n\r\n")
1681 };
1682
1683 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521684 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351685 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1686 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061687 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521688 };
[email protected]202965992011-12-07 23:04:511689
1690 if (write_failure) {
[email protected]a34f61ee2014-03-18 20:59:491691 ASSERT_FALSE(read_failure);
[email protected]202965992011-12-07 23:04:511692 data1_writes[1] = *write_failure;
1693 } else {
1694 ASSERT_TRUE(read_failure);
1695 data1_reads[2] = *read_failure;
1696 }
1697
Ryan Sleevib8d7ea02018-05-07 20:01:011698 StaticSocketDataProvider data1(data1_reads, data1_writes);
[email protected]bb88e1d32013-05-03 23:11:071699 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521700
1701 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351702 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1703 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061704 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521705 };
Ryan Sleevib8d7ea02018-05-07 20:01:011706 StaticSocketDataProvider data2(data2_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071707 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521708
thestig9d3bb0c2015-01-24 00:49:511709 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521710 "hello", "world"
1711 };
1712
mikecironef22f9812016-10-04 03:40:191713 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521714 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411715 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521716
bnc691fda62016-08-12 00:43:161717 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
initial.commit586acc5fe2008-07-26 22:42:521718
tfarina42834112016-09-22 13:38:201719 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011720 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521721
1722 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011723 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521724
[email protected]58e32bb2013-01-21 18:23:251725 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161726 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:251727 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1728 if (i == 0) {
1729 first_socket_log_id = load_timing_info.socket_log_id;
1730 } else {
1731 // The second request should be using a new socket.
1732 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1733 }
1734
bnc691fda62016-08-12 00:43:161735 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521736 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521737
wezca1070932016-05-26 20:30:521738 EXPECT_TRUE(response->headers);
tbansal2ecbbc72016-10-06 17:15:471739 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]3d2a59b2008-09-26 19:44:251740 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521741
1742 std::string response_data;
bnc691fda62016-08-12 00:43:161743 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011744 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251745 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521746 }
1747}
[email protected]3d2a59b2008-09-26 19:44:251748
[email protected]a34f61ee2014-03-18 20:59:491749void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1750 const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:101751 const MockRead* read_failure,
1752 bool use_spdy) {
[email protected]a34f61ee2014-03-18 20:59:491753 HttpRequestInfo request;
1754 request.method = "GET";
[email protected]09356c652014-03-25 15:36:101755 request.url = GURL("https://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101756 request.traffic_annotation =
1757 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]a34f61ee2014-03-18 20:59:491758
vishal.b62985ca92015-04-17 08:45:511759 TestNetLog net_log;
[email protected]a34f61ee2014-03-18 20:59:491760 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091761 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a34f61ee2014-03-18 20:59:491762
[email protected]09356c652014-03-25 15:36:101763 SSLSocketDataProvider ssl1(ASYNC, OK);
1764 SSLSocketDataProvider ssl2(ASYNC, OK);
1765 if (use_spdy) {
bnc3cf2a592016-08-11 14:48:361766 ssl1.next_proto = kProtoHTTP2;
1767 ssl2.next_proto = kProtoHTTP2;
[email protected]09356c652014-03-25 15:36:101768 }
1769 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1770 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]a34f61ee2014-03-18 20:59:491771
[email protected]09356c652014-03-25 15:36:101772 // SPDY versions of the request and response.
Ryan Hamilton0239aac2018-05-19 00:03:131773 spdy::SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
bnc38dcd392016-02-09 23:19:491774 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
Ryan Hamilton0239aac2018-05-19 00:03:131775 spdy::SpdySerializedFrame spdy_response(
bnc42331402016-07-25 13:36:151776 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:131777 spdy::SpdySerializedFrame spdy_data(
Bence Békyd74f4382018-02-20 18:26:191778 spdy_util_.ConstructSpdyDataFrame(1, "hello", true));
[email protected]a34f61ee2014-03-18 20:59:491779
[email protected]09356c652014-03-25 15:36:101780 // HTTP/1.1 versions of the request and response.
1781 const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1782 "Host: www.foo.com\r\n"
1783 "Connection: keep-alive\r\n\r\n";
1784 const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1785 const char kHttpData[] = "hello";
1786
1787 std::vector<MockRead> data1_reads;
1788 std::vector<MockWrite> data1_writes;
[email protected]a34f61ee2014-03-18 20:59:491789 if (write_failure) {
1790 ASSERT_FALSE(read_failure);
[email protected]09356c652014-03-25 15:36:101791 data1_writes.push_back(*write_failure);
1792 data1_reads.push_back(MockRead(ASYNC, OK));
[email protected]a34f61ee2014-03-18 20:59:491793 } else {
1794 ASSERT_TRUE(read_failure);
[email protected]09356c652014-03-25 15:36:101795 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411796 data1_writes.push_back(CreateMockWrite(spdy_request));
[email protected]09356c652014-03-25 15:36:101797 } else {
1798 data1_writes.push_back(MockWrite(kHttpRequest));
1799 }
1800 data1_reads.push_back(*read_failure);
[email protected]a34f61ee2014-03-18 20:59:491801 }
1802
Ryan Sleevib8d7ea02018-05-07 20:01:011803 StaticSocketDataProvider data1(data1_reads, data1_writes);
[email protected]a34f61ee2014-03-18 20:59:491804 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1805
[email protected]09356c652014-03-25 15:36:101806 std::vector<MockRead> data2_reads;
1807 std::vector<MockWrite> data2_writes;
1808
1809 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411810 data2_writes.push_back(CreateMockWrite(spdy_request, 0, ASYNC));
[email protected]09356c652014-03-25 15:36:101811
bncdf80d44fd2016-07-15 20:27:411812 data2_reads.push_back(CreateMockRead(spdy_response, 1, ASYNC));
1813 data2_reads.push_back(CreateMockRead(spdy_data, 2, ASYNC));
[email protected]09356c652014-03-25 15:36:101814 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1815 } else {
1816 data2_writes.push_back(
1817 MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1818
1819 data2_reads.push_back(
1820 MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1821 data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1822 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1823 }
Ryan Sleevib8d7ea02018-05-07 20:01:011824 SequencedSocketData data2(data2_reads, data2_writes);
[email protected]a34f61ee2014-03-18 20:59:491825 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1826
1827 // Preconnect a socket.
nharper8cdb0fb2016-04-22 21:34:591828 session->http_stream_factory()->PreconnectStreams(1, request);
[email protected]a34f61ee2014-03-18 20:59:491829 // Wait for the preconnect to complete.
1830 // TODO(davidben): Some way to wait for an idle socket count might be handy.
1831 base::RunLoop().RunUntilIdle();
[email protected]09356c652014-03-25 15:36:101832 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]a34f61ee2014-03-18 20:59:491833
1834 // Make the request.
1835 TestCompletionCallback callback;
1836
bnc691fda62016-08-12 00:43:161837 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a34f61ee2014-03-18 20:59:491838
tfarina42834112016-09-22 13:38:201839 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011840 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a34f61ee2014-03-18 20:59:491841
1842 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011843 EXPECT_THAT(rv, IsOk());
[email protected]a34f61ee2014-03-18 20:59:491844
1845 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161846 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]09356c652014-03-25 15:36:101847 TestLoadTimingNotReused(
1848 load_timing_info,
1849 CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]a34f61ee2014-03-18 20:59:491850
bnc691fda62016-08-12 00:43:161851 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521852 ASSERT_TRUE(response);
[email protected]a34f61ee2014-03-18 20:59:491853
wezca1070932016-05-26 20:30:521854 EXPECT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:021855 if (response->was_fetched_via_spdy) {
1856 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
1857 } else {
1858 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1859 }
[email protected]a34f61ee2014-03-18 20:59:491860
1861 std::string response_data;
bnc691fda62016-08-12 00:43:161862 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011863 EXPECT_THAT(rv, IsOk());
[email protected]09356c652014-03-25 15:36:101864 EXPECT_EQ(kHttpData, response_data);
[email protected]a34f61ee2014-03-18 20:59:491865}
1866
Biljith Jayan45a41722017-08-16 18:43:141867// Test that we do not retry indefinitely when a server sends an error like
1868// ERR_SPDY_PING_FAILED, ERR_SPDY_SERVER_REFUSED_STREAM,
1869// ERR_QUIC_HANDSHAKE_FAILED or ERR_QUIC_PROTOCOL_ERROR.
1870TEST_F(HttpNetworkTransactionTest, FiniteRetriesOnIOError) {
1871 HttpRequestInfo request;
1872 request.method = "GET";
1873 request.url = GURL("https://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101874 request.traffic_annotation =
1875 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Biljith Jayan45a41722017-08-16 18:43:141876
1877 // Check whether we give up after the third try.
1878
1879 // Construct an HTTP2 request and a "Go away" response.
Ryan Hamilton0239aac2018-05-19 00:03:131880 spdy::SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
Biljith Jayan45a41722017-08-16 18:43:141881 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
Ryan Hamilton0239aac2018-05-19 00:03:131882 spdy::SpdySerializedFrame spdy_response_go_away(
1883 spdy_util_.ConstructSpdyGoAway(0));
Ryan Sleevib8d7ea02018-05-07 20:01:011884 MockRead data_read1[] = {CreateMockRead(spdy_response_go_away)};
1885 MockWrite data_write[] = {CreateMockWrite(spdy_request, 0)};
Biljith Jayan45a41722017-08-16 18:43:141886
1887 // Three go away responses.
Ryan Sleevib8d7ea02018-05-07 20:01:011888 StaticSocketDataProvider data1(data_read1, data_write);
1889 StaticSocketDataProvider data2(data_read1, data_write);
1890 StaticSocketDataProvider data3(data_read1, data_write);
Biljith Jayan45a41722017-08-16 18:43:141891
1892 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1893 AddSSLSocketData();
1894 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1895 AddSSLSocketData();
1896 session_deps_.socket_factory->AddSocketDataProvider(&data3);
1897 AddSSLSocketData();
1898
1899 TestCompletionCallback callback;
1900 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1901 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1902
1903 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1904 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1905
1906 rv = callback.WaitForResult();
1907 EXPECT_THAT(rv, IsError(ERR_SPDY_SERVER_REFUSED_STREAM));
1908}
1909
1910TEST_F(HttpNetworkTransactionTest, RetryTwiceOnIOError) {
1911 HttpRequestInfo request;
1912 request.method = "GET";
1913 request.url = GURL("https://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101914 request.traffic_annotation =
1915 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Biljith Jayan45a41722017-08-16 18:43:141916
1917 // Check whether we try atleast thrice before giving up.
1918
1919 // Construct an HTTP2 request and a "Go away" response.
Ryan Hamilton0239aac2018-05-19 00:03:131920 spdy::SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
Biljith Jayan45a41722017-08-16 18:43:141921 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
Ryan Hamilton0239aac2018-05-19 00:03:131922 spdy::SpdySerializedFrame spdy_response_go_away(
1923 spdy_util_.ConstructSpdyGoAway(0));
Ryan Sleevib8d7ea02018-05-07 20:01:011924 MockRead data_read1[] = {CreateMockRead(spdy_response_go_away)};
1925 MockWrite data_write[] = {CreateMockWrite(spdy_request, 0)};
Biljith Jayan45a41722017-08-16 18:43:141926
1927 // Construct a non error HTTP2 response.
Ryan Hamilton0239aac2018-05-19 00:03:131928 spdy::SpdySerializedFrame spdy_response_no_error(
Biljith Jayan45a41722017-08-16 18:43:141929 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:131930 spdy::SpdySerializedFrame spdy_data(
1931 spdy_util_.ConstructSpdyDataFrame(1, true));
Biljith Jayan45a41722017-08-16 18:43:141932 MockRead data_read2[] = {CreateMockRead(spdy_response_no_error, 1),
1933 CreateMockRead(spdy_data, 2)};
1934
1935 // Two error responses.
Ryan Sleevib8d7ea02018-05-07 20:01:011936 StaticSocketDataProvider data1(data_read1, data_write);
1937 StaticSocketDataProvider data2(data_read1, data_write);
Biljith Jayan45a41722017-08-16 18:43:141938 // Followed by a success response.
Ryan Sleevib8d7ea02018-05-07 20:01:011939 SequencedSocketData data3(data_read2, data_write);
Biljith Jayan45a41722017-08-16 18:43:141940
1941 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1942 AddSSLSocketData();
1943 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1944 AddSSLSocketData();
1945 session_deps_.socket_factory->AddSocketDataProvider(&data3);
1946 AddSSLSocketData();
1947
1948 TestCompletionCallback callback;
1949 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1950 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1951
1952 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1953 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1954
1955 rv = callback.WaitForResult();
1956 EXPECT_THAT(rv, IsOk());
1957}
1958
bncd16676a2016-07-20 16:23:011959TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061960 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]202965992011-12-07 23:04:511961 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1962}
1963
bncd16676a2016-07-20 16:23:011964TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061965 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]202965992011-12-07 23:04:511966 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251967}
1968
bncd16676a2016-07-20 16:23:011969TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061970 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]202965992011-12-07 23:04:511971 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251972}
1973
[email protected]d58ceea82014-06-04 10:55:541974// Make sure that on a 408 response (Request Timeout), the request is retried,
1975// if the socket was a reused keep alive socket.
bncd16676a2016-07-20 16:23:011976TEST_F(HttpNetworkTransactionTest, KeepAlive408) {
[email protected]d58ceea82014-06-04 10:55:541977 MockRead read_failure(SYNCHRONOUS,
1978 "HTTP/1.1 408 Request Timeout\r\n"
1979 "Connection: Keep-Alive\r\n"
1980 "Content-Length: 6\r\n\r\n"
1981 "Pickle");
1982 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1983}
1984
bncd16676a2016-07-20 16:23:011985TEST_F(HttpNetworkTransactionTest, PreconnectErrorNotConnectedOnWrite) {
[email protected]a34f61ee2014-03-18 20:59:491986 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]09356c652014-03-25 15:36:101987 PreconnectErrorResendRequestTest(&write_failure, NULL, false);
[email protected]a34f61ee2014-03-18 20:59:491988}
1989
bncd16676a2016-07-20 16:23:011990TEST_F(HttpNetworkTransactionTest, PreconnectErrorReset) {
[email protected]a34f61ee2014-03-18 20:59:491991 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]09356c652014-03-25 15:36:101992 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
[email protected]a34f61ee2014-03-18 20:59:491993}
1994
bncd16676a2016-07-20 16:23:011995TEST_F(HttpNetworkTransactionTest, PreconnectErrorEOF) {
[email protected]a34f61ee2014-03-18 20:59:491996 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]09356c652014-03-25 15:36:101997 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1998}
1999
bncd16676a2016-07-20 16:23:012000TEST_F(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:102001 MockRead read_failure(ASYNC, OK); // EOF
2002 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
2003}
2004
[email protected]d58ceea82014-06-04 10:55:542005// Make sure that on a 408 response (Request Timeout), the request is retried,
2006// if the socket was a preconnected (UNUSED_IDLE) socket.
bncd16676a2016-07-20 16:23:012007TEST_F(HttpNetworkTransactionTest, RetryOnIdle408) {
[email protected]d58ceea82014-06-04 10:55:542008 MockRead read_failure(SYNCHRONOUS,
2009 "HTTP/1.1 408 Request Timeout\r\n"
2010 "Connection: Keep-Alive\r\n"
2011 "Content-Length: 6\r\n\r\n"
2012 "Pickle");
2013 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
2014 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
2015}
2016
bncd16676a2016-07-20 16:23:012017TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorNotConnectedOnWrite) {
[email protected]09356c652014-03-25 15:36:102018 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
2019 PreconnectErrorResendRequestTest(&write_failure, NULL, true);
2020}
2021
bncd16676a2016-07-20 16:23:012022TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
[email protected]09356c652014-03-25 15:36:102023 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
2024 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
2025}
2026
bncd16676a2016-07-20 16:23:012027TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
[email protected]09356c652014-03-25 15:36:102028 MockRead read_failure(SYNCHRONOUS, OK); // EOF
2029 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
2030}
2031
bncd16676a2016-07-20 16:23:012032TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:102033 MockRead read_failure(ASYNC, OK); // EOF
2034 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
[email protected]a34f61ee2014-03-18 20:59:492035}
2036
bncd16676a2016-07-20 16:23:012037TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:422038 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:252039 request.method = "GET";
bncce36dca22015-04-21 22:11:232040 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102041 request.traffic_annotation =
2042 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3d2a59b2008-09-26 19:44:252043
danakj1fd259a02016-04-16 03:17:092044 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162045 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272046
[email protected]3d2a59b2008-09-26 19:44:252047 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:062048 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:352049 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
2050 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:062051 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:252052 };
Ryan Sleevib8d7ea02018-05-07 20:01:012053 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:072054 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:252055
[email protected]49639fa2011-12-20 23:22:412056 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:252057
tfarina42834112016-09-22 13:38:202058 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012059 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3d2a59b2008-09-26 19:44:252060
2061 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:012062 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:592063
2064 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:162065 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592066 EXPECT_LT(0u, endpoint.address().size());
[email protected]3d2a59b2008-09-26 19:44:252067}
2068
2069// What do various browsers do when the server closes a non-keepalive
2070// connection without sending any response header or body?
2071//
2072// IE7: error page
2073// Safari 3.1.2 (Windows): error page
2074// Firefox 3.0.1: blank page
2075// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:422076// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
2077// Us: error page (EMPTY_RESPONSE)
bncd16676a2016-07-20 16:23:012078TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:252079 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:062080 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:352081 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
2082 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:062083 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:252084 };
Ryan Sleevib8d7ea02018-05-07 20:01:012085 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:012086 EXPECT_THAT(out.rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]3d2a59b2008-09-26 19:44:252087}
[email protected]1826a402014-01-08 15:40:482088
[email protected]7a5378b2012-11-04 03:25:172089// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
2090// tests. There was a bug causing HttpNetworkTransaction to hang in the
2091// destructor in such situations.
2092// See http://crbug.com/154712 and http://crbug.com/156609.
bncd16676a2016-07-20 16:23:012093TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:172094 HttpRequestInfo request;
2095 request.method = "GET";
bncce36dca22015-04-21 22:11:232096 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102097 request.traffic_annotation =
2098 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7a5378b2012-11-04 03:25:172099
danakj1fd259a02016-04-16 03:17:092100 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:582101 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:192102 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:172103
2104 MockRead data_reads[] = {
2105 MockRead("HTTP/1.0 200 OK\r\n"),
2106 MockRead("Connection: keep-alive\r\n"),
2107 MockRead("Content-Length: 100\r\n\r\n"),
2108 MockRead("hello"),
2109 MockRead(SYNCHRONOUS, 0),
2110 };
Ryan Sleevib8d7ea02018-05-07 20:01:012111 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:072112 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:172113
2114 TestCompletionCallback callback;
2115
tfarina42834112016-09-22 13:38:202116 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012117 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:172118
2119 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:012120 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:172121
Victor Costan9c7302b2018-08-27 16:39:442122 scoped_refptr<IOBufferWithSize> io_buf =
2123 base::MakeRefCounted<IOBufferWithSize>(100);
[email protected]90499482013-06-01 00:39:502124 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:172125 if (rv == ERR_IO_PENDING)
2126 rv = callback.WaitForResult();
2127 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:502128 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
robpercival214763f2016-07-01 23:27:012129 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:172130
2131 trans.reset();
fdoray92e35a72016-06-10 15:54:552132 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:172133 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2134}
2135
bncd16676a2016-07-20 16:23:012136TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:172137 HttpRequestInfo request;
2138 request.method = "GET";
bncce36dca22015-04-21 22:11:232139 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102140 request.traffic_annotation =
2141 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7a5378b2012-11-04 03:25:172142
danakj1fd259a02016-04-16 03:17:092143 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:582144 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:192145 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:172146
2147 MockRead data_reads[] = {
2148 MockRead("HTTP/1.0 200 OK\r\n"),
2149 MockRead("Connection: keep-alive\r\n"),
2150 MockRead("Content-Length: 100\r\n\r\n"),
2151 MockRead(SYNCHRONOUS, 0),
2152 };
Ryan Sleevib8d7ea02018-05-07 20:01:012153 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:072154 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:172155
2156 TestCompletionCallback callback;
2157
tfarina42834112016-09-22 13:38:202158 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012159 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:172160
2161 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:012162 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:172163
Victor Costan9c7302b2018-08-27 16:39:442164 scoped_refptr<IOBufferWithSize> io_buf(
2165 base::MakeRefCounted<IOBufferWithSize>(100));
[email protected]90499482013-06-01 00:39:502166 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:172167 if (rv == ERR_IO_PENDING)
2168 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:012169 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:172170
2171 trans.reset();
fdoray92e35a72016-06-10 15:54:552172 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:172173 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2174}
2175
[email protected]0b0bf032010-09-21 18:08:502176// Test that we correctly reuse a keep-alive connection after not explicitly
2177// reading the body.
bncd16676a2016-07-20 16:23:012178TEST_F(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:132179 HttpRequestInfo request;
2180 request.method = "GET";
2181 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:102182 request.traffic_annotation =
2183 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]fc31d6a42010-06-24 18:05:132184
vishal.b62985ca92015-04-17 08:45:512185 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:072186 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:092187 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272188
mmenkecc2298e2015-12-07 18:20:182189 const char* request_data =
2190 "GET / HTTP/1.1\r\n"
2191 "Host: www.foo.com\r\n"
2192 "Connection: keep-alive\r\n\r\n";
2193 MockWrite data_writes[] = {
2194 MockWrite(ASYNC, 0, request_data), MockWrite(ASYNC, 2, request_data),
2195 MockWrite(ASYNC, 4, request_data), MockWrite(ASYNC, 6, request_data),
2196 MockWrite(ASYNC, 8, request_data), MockWrite(ASYNC, 10, request_data),
2197 MockWrite(ASYNC, 12, request_data), MockWrite(ASYNC, 14, request_data),
2198 MockWrite(ASYNC, 17, request_data), MockWrite(ASYNC, 20, request_data),
2199 };
2200
[email protected]0b0bf032010-09-21 18:08:502201 // Note that because all these reads happen in the same
2202 // StaticSocketDataProvider, it shows that the same socket is being reused for
2203 // all transactions.
mmenkecc2298e2015-12-07 18:20:182204 MockRead data_reads[] = {
2205 MockRead(ASYNC, 1, "HTTP/1.1 204 No Content\r\n\r\n"),
2206 MockRead(ASYNC, 3, "HTTP/1.1 205 Reset Content\r\n\r\n"),
2207 MockRead(ASYNC, 5, "HTTP/1.1 304 Not Modified\r\n\r\n"),
2208 MockRead(ASYNC, 7,
2209 "HTTP/1.1 302 Found\r\n"
2210 "Content-Length: 0\r\n\r\n"),
2211 MockRead(ASYNC, 9,
2212 "HTTP/1.1 302 Found\r\n"
2213 "Content-Length: 5\r\n\r\n"
2214 "hello"),
2215 MockRead(ASYNC, 11,
2216 "HTTP/1.1 301 Moved Permanently\r\n"
2217 "Content-Length: 0\r\n\r\n"),
2218 MockRead(ASYNC, 13,
2219 "HTTP/1.1 301 Moved Permanently\r\n"
2220 "Content-Length: 5\r\n\r\n"
2221 "hello"),
[email protected]fc31d6a42010-06-24 18:05:132222
mmenkecc2298e2015-12-07 18:20:182223 // In the next two rounds, IsConnectedAndIdle returns false, due to
2224 // the set_busy_before_sync_reads(true) call, while the
2225 // HttpNetworkTransaction is being shut down, but the socket is still
2226 // reuseable. See http://crbug.com/544255.
2227 MockRead(ASYNC, 15,
2228 "HTTP/1.1 200 Hunky-Dory\r\n"
2229 "Content-Length: 5\r\n\r\n"),
2230 MockRead(SYNCHRONOUS, 16, "hello"),
[email protected]fc31d6a42010-06-24 18:05:132231
mmenkecc2298e2015-12-07 18:20:182232 MockRead(ASYNC, 18,
2233 "HTTP/1.1 200 Hunky-Dory\r\n"
2234 "Content-Length: 5\r\n\r\n"
2235 "he"),
2236 MockRead(SYNCHRONOUS, 19, "llo"),
2237
2238 // The body of the final request is actually read.
2239 MockRead(ASYNC, 21, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
2240 MockRead(ASYNC, 22, "hello"),
2241 };
Ryan Sleevib8d7ea02018-05-07 20:01:012242 SequencedSocketData data(data_reads, data_writes);
mmenkecc2298e2015-12-07 18:20:182243 data.set_busy_before_sync_reads(true);
2244 session_deps_.socket_factory->AddSocketDataProvider(&data);
2245
Avi Drissman4365a4782018-12-28 19:26:242246 const int kNumUnreadBodies = base::size(data_writes) - 1;
[email protected]0b0bf032010-09-21 18:08:502247 std::string response_lines[kNumUnreadBodies];
2248
mikecironef22f9812016-10-04 03:40:192249 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
mmenkecc2298e2015-12-07 18:20:182250 for (size_t i = 0; i < kNumUnreadBodies; ++i) {
[email protected]49639fa2011-12-20 23:22:412251 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:132252
Jeremy Roman0579ed62017-08-29 15:56:192253 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
bnc87dcefc2017-05-25 12:47:582254 session.get());
[email protected]fc31d6a42010-06-24 18:05:132255
tfarina42834112016-09-22 13:38:202256 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012257 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]fc31d6a42010-06-24 18:05:132258
[email protected]58e32bb2013-01-21 18:23:252259 LoadTimingInfo load_timing_info;
2260 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2261 if (i == 0) {
2262 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
2263 first_socket_log_id = load_timing_info.socket_log_id;
2264 } else {
2265 TestLoadTimingReused(load_timing_info);
2266 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
2267 }
2268
[email protected]fc31d6a42010-06-24 18:05:132269 const HttpResponseInfo* response = trans->GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182270 ASSERT_TRUE(response);
[email protected]fc31d6a42010-06-24 18:05:132271
mmenkecc2298e2015-12-07 18:20:182272 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502273 response_lines[i] = response->headers->GetStatusLine();
2274
mmenkecc2298e2015-12-07 18:20:182275 // Delete the transaction without reading the response bodies. Then spin
2276 // the message loop, so the response bodies are drained.
2277 trans.reset();
2278 base::RunLoop().RunUntilIdle();
[email protected]fc31d6a42010-06-24 18:05:132279 }
[email protected]0b0bf032010-09-21 18:08:502280
2281 const char* const kStatusLines[] = {
mmenkecc2298e2015-12-07 18:20:182282 "HTTP/1.1 204 No Content",
2283 "HTTP/1.1 205 Reset Content",
2284 "HTTP/1.1 304 Not Modified",
2285 "HTTP/1.1 302 Found",
2286 "HTTP/1.1 302 Found",
2287 "HTTP/1.1 301 Moved Permanently",
2288 "HTTP/1.1 301 Moved Permanently",
2289 "HTTP/1.1 200 Hunky-Dory",
2290 "HTTP/1.1 200 Hunky-Dory",
[email protected]0b0bf032010-09-21 18:08:502291 };
2292
Avi Drissman4365a4782018-12-28 19:26:242293 static_assert(kNumUnreadBodies == base::size(kStatusLines),
mostynb91e0da982015-01-20 19:17:272294 "forgot to update kStatusLines");
[email protected]0b0bf032010-09-21 18:08:502295
2296 for (int i = 0; i < kNumUnreadBodies; ++i)
2297 EXPECT_EQ(kStatusLines[i], response_lines[i]);
2298
[email protected]49639fa2011-12-20 23:22:412299 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:162300 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202301 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012302 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:162303 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182304 ASSERT_TRUE(response);
2305 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502306 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2307 std::string response_data;
bnc691fda62016-08-12 00:43:162308 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:012309 EXPECT_THAT(rv, IsOk());
[email protected]0b0bf032010-09-21 18:08:502310 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:132311}
2312
mmenke5f94fda2016-06-02 20:54:132313// Sockets that receive extra data after a response is complete should not be
2314// reused.
bncd16676a2016-07-20 16:23:012315TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData1) {
mmenke5f94fda2016-06-02 20:54:132316 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2317 MockWrite data_writes1[] = {
2318 MockWrite("HEAD / HTTP/1.1\r\n"
2319 "Host: www.borked.com\r\n"
2320 "Connection: keep-alive\r\n\r\n"),
2321 };
2322
2323 MockRead data_reads1[] = {
2324 MockRead("HTTP/1.1 200 OK\r\n"
2325 "Connection: keep-alive\r\n"
2326 "Content-Length: 22\r\n\r\n"
2327 "This server is borked."),
2328 };
2329
2330 MockWrite data_writes2[] = {
2331 MockWrite("GET /foo HTTP/1.1\r\n"
2332 "Host: www.borked.com\r\n"
2333 "Connection: keep-alive\r\n\r\n"),
2334 };
2335
2336 MockRead data_reads2[] = {
2337 MockRead("HTTP/1.1 200 OK\r\n"
2338 "Content-Length: 3\r\n\r\n"
2339 "foo"),
2340 };
Ryan Sleevib8d7ea02018-05-07 20:01:012341 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke5f94fda2016-06-02 20:54:132342 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:012343 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke5f94fda2016-06-02 20:54:132344 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2345
2346 TestCompletionCallback callback;
2347 HttpRequestInfo request1;
2348 request1.method = "HEAD";
2349 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e2018-02-07 07:41:102350 request1.traffic_annotation =
2351 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132352
bnc87dcefc2017-05-25 12:47:582353 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192354 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202355 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012356 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132357
2358 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2359 ASSERT_TRUE(response1);
2360 ASSERT_TRUE(response1->headers);
2361 EXPECT_EQ(200, response1->headers->response_code());
2362 EXPECT_TRUE(response1->headers->IsKeepAlive());
2363
2364 std::string response_data1;
robpercival214763f2016-07-01 23:27:012365 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132366 EXPECT_EQ("", response_data1);
2367 // Deleting the transaction attempts to release the socket back into the
2368 // socket pool.
2369 trans1.reset();
2370
2371 HttpRequestInfo request2;
2372 request2.method = "GET";
2373 request2.url = GURL("http://www.borked.com/foo");
Ramin Halavatib5e433e2018-02-07 07:41:102374 request2.traffic_annotation =
2375 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132376
bnc87dcefc2017-05-25 12:47:582377 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192378 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202379 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012380 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132381
2382 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2383 ASSERT_TRUE(response2);
2384 ASSERT_TRUE(response2->headers);
2385 EXPECT_EQ(200, response2->headers->response_code());
2386
2387 std::string response_data2;
robpercival214763f2016-07-01 23:27:012388 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132389 EXPECT_EQ("foo", response_data2);
2390}
2391
bncd16676a2016-07-20 16:23:012392TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData2) {
mmenke5f94fda2016-06-02 20:54:132393 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2394 MockWrite data_writes1[] = {
2395 MockWrite("GET / HTTP/1.1\r\n"
2396 "Host: www.borked.com\r\n"
2397 "Connection: keep-alive\r\n\r\n"),
2398 };
2399
2400 MockRead data_reads1[] = {
2401 MockRead("HTTP/1.1 200 OK\r\n"
2402 "Connection: keep-alive\r\n"
2403 "Content-Length: 22\r\n\r\n"
2404 "This server is borked."
2405 "Bonus data!"),
2406 };
2407
2408 MockWrite data_writes2[] = {
2409 MockWrite("GET /foo HTTP/1.1\r\n"
2410 "Host: www.borked.com\r\n"
2411 "Connection: keep-alive\r\n\r\n"),
2412 };
2413
2414 MockRead data_reads2[] = {
2415 MockRead("HTTP/1.1 200 OK\r\n"
2416 "Content-Length: 3\r\n\r\n"
2417 "foo"),
2418 };
Ryan Sleevib8d7ea02018-05-07 20:01:012419 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke5f94fda2016-06-02 20:54:132420 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:012421 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke5f94fda2016-06-02 20:54:132422 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2423
2424 TestCompletionCallback callback;
2425 HttpRequestInfo request1;
2426 request1.method = "GET";
2427 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e2018-02-07 07:41:102428 request1.traffic_annotation =
2429 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132430
bnc87dcefc2017-05-25 12:47:582431 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192432 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202433 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012434 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132435
2436 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2437 ASSERT_TRUE(response1);
2438 ASSERT_TRUE(response1->headers);
2439 EXPECT_EQ(200, response1->headers->response_code());
2440 EXPECT_TRUE(response1->headers->IsKeepAlive());
2441
2442 std::string response_data1;
robpercival214763f2016-07-01 23:27:012443 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132444 EXPECT_EQ("This server is borked.", response_data1);
2445 // Deleting the transaction attempts to release the socket back into the
2446 // socket pool.
2447 trans1.reset();
2448
2449 HttpRequestInfo request2;
2450 request2.method = "GET";
2451 request2.url = GURL("http://www.borked.com/foo");
Ramin Halavatib5e433e2018-02-07 07:41:102452 request2.traffic_annotation =
2453 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132454
bnc87dcefc2017-05-25 12:47:582455 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192456 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202457 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012458 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132459
2460 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2461 ASSERT_TRUE(response2);
2462 ASSERT_TRUE(response2->headers);
2463 EXPECT_EQ(200, response2->headers->response_code());
2464
2465 std::string response_data2;
robpercival214763f2016-07-01 23:27:012466 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132467 EXPECT_EQ("foo", response_data2);
2468}
2469
bncd16676a2016-07-20 16:23:012470TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData3) {
mmenke5f94fda2016-06-02 20:54:132471 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2472 MockWrite data_writes1[] = {
2473 MockWrite("GET / HTTP/1.1\r\n"
2474 "Host: www.borked.com\r\n"
2475 "Connection: keep-alive\r\n\r\n"),
2476 };
2477
2478 MockRead data_reads1[] = {
2479 MockRead("HTTP/1.1 200 OK\r\n"
2480 "Connection: keep-alive\r\n"
2481 "Transfer-Encoding: chunked\r\n\r\n"),
2482 MockRead("16\r\nThis server is borked.\r\n"),
2483 MockRead("0\r\n\r\nBonus data!"),
2484 };
2485
2486 MockWrite data_writes2[] = {
2487 MockWrite("GET /foo HTTP/1.1\r\n"
2488 "Host: www.borked.com\r\n"
2489 "Connection: keep-alive\r\n\r\n"),
2490 };
2491
2492 MockRead data_reads2[] = {
2493 MockRead("HTTP/1.1 200 OK\r\n"
2494 "Content-Length: 3\r\n\r\n"
2495 "foo"),
2496 };
Ryan Sleevib8d7ea02018-05-07 20:01:012497 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke5f94fda2016-06-02 20:54:132498 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:012499 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke5f94fda2016-06-02 20:54:132500 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2501
2502 TestCompletionCallback callback;
2503 HttpRequestInfo request1;
2504 request1.method = "GET";
2505 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e2018-02-07 07:41:102506 request1.traffic_annotation =
2507 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132508
bnc87dcefc2017-05-25 12:47:582509 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192510 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202511 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012512 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132513
2514 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2515 ASSERT_TRUE(response1);
2516 ASSERT_TRUE(response1->headers);
2517 EXPECT_EQ(200, response1->headers->response_code());
2518 EXPECT_TRUE(response1->headers->IsKeepAlive());
2519
2520 std::string response_data1;
robpercival214763f2016-07-01 23:27:012521 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132522 EXPECT_EQ("This server is borked.", response_data1);
2523 // Deleting the transaction attempts to release the socket back into the
2524 // socket pool.
2525 trans1.reset();
2526
2527 HttpRequestInfo request2;
2528 request2.method = "GET";
2529 request2.url = GURL("http://www.borked.com/foo");
Ramin Halavatib5e433e2018-02-07 07:41:102530 request2.traffic_annotation =
2531 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132532
bnc87dcefc2017-05-25 12:47:582533 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192534 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202535 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012536 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132537
2538 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2539 ASSERT_TRUE(response2);
2540 ASSERT_TRUE(response2->headers);
2541 EXPECT_EQ(200, response2->headers->response_code());
2542
2543 std::string response_data2;
robpercival214763f2016-07-01 23:27:012544 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132545 EXPECT_EQ("foo", response_data2);
2546}
2547
2548// This is a little different from the others - it tests the case that the
2549// HttpStreamParser doesn't know if there's extra data on a socket or not when
2550// the HttpNetworkTransaction is torn down, because the response body hasn't
2551// been read from yet, but the request goes through the HttpResponseBodyDrainer.
bncd16676a2016-07-20 16:23:012552TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData4) {
mmenke5f94fda2016-06-02 20:54:132553 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2554 MockWrite data_writes1[] = {
2555 MockWrite("GET / HTTP/1.1\r\n"
2556 "Host: www.borked.com\r\n"
2557 "Connection: keep-alive\r\n\r\n"),
2558 };
2559
2560 MockRead data_reads1[] = {
2561 MockRead("HTTP/1.1 200 OK\r\n"
2562 "Connection: keep-alive\r\n"
2563 "Transfer-Encoding: chunked\r\n\r\n"),
2564 MockRead("16\r\nThis server is borked.\r\n"),
2565 MockRead("0\r\n\r\nBonus data!"),
2566 };
Ryan Sleevib8d7ea02018-05-07 20:01:012567 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke5f94fda2016-06-02 20:54:132568 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2569
2570 TestCompletionCallback callback;
2571 HttpRequestInfo request1;
2572 request1.method = "GET";
2573 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e2018-02-07 07:41:102574 request1.traffic_annotation =
2575 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132576
bnc87dcefc2017-05-25 12:47:582577 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:192578 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
bnc87dcefc2017-05-25 12:47:582579 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012580 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132581
bnc87dcefc2017-05-25 12:47:582582 const HttpResponseInfo* response1 = trans->GetResponseInfo();
mmenke5f94fda2016-06-02 20:54:132583 ASSERT_TRUE(response1);
2584 ASSERT_TRUE(response1->headers);
2585 EXPECT_EQ(200, response1->headers->response_code());
2586 EXPECT_TRUE(response1->headers->IsKeepAlive());
2587
2588 // Deleting the transaction creates an HttpResponseBodyDrainer to read the
2589 // response body.
bnc87dcefc2017-05-25 12:47:582590 trans.reset();
mmenke5f94fda2016-06-02 20:54:132591
2592 // Let the HttpResponseBodyDrainer drain the socket. It should determine the
2593 // socket can't be reused, rather than returning it to the socket pool.
2594 base::RunLoop().RunUntilIdle();
2595
2596 // There should be no idle sockets in the pool.
2597 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2598}
2599
[email protected]038e9a32008-10-08 22:40:162600// Test the request-challenge-retry sequence for basic auth.
2601// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012602TEST_F(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:422603 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:162604 request.method = "GET";
bncce36dca22015-04-21 22:11:232605 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102606 request.traffic_annotation =
2607 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]038e9a32008-10-08 22:40:162608
vishal.b62985ca92015-04-17 08:45:512609 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072610 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092611 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162612 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272613
[email protected]f9ee6b52008-11-08 06:46:232614 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232615 MockWrite(
2616 "GET / HTTP/1.1\r\n"
2617 "Host: www.example.org\r\n"
2618 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:232619 };
2620
[email protected]038e9a32008-10-08 22:40:162621 MockRead data_reads1[] = {
2622 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2623 // Give a couple authenticate options (only the middle one is actually
2624 // supported).
[email protected]22927ad2009-09-21 19:56:192625 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:162626 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2627 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2628 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2629 // Large content-length -- won't matter, as connection will be reset.
2630 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062631 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:162632 };
2633
2634 // After calling trans->RestartWithAuth(), this is the request we should
2635 // be issuing -- the final header line contains the credentials.
2636 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232637 MockWrite(
2638 "GET / HTTP/1.1\r\n"
2639 "Host: www.example.org\r\n"
2640 "Connection: keep-alive\r\n"
2641 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:162642 };
2643
2644 // Lastly, the server responds with the actual content.
2645 MockRead data_reads2[] = {
2646 MockRead("HTTP/1.0 200 OK\r\n"),
2647 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2648 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062649 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:162650 };
2651
Ryan Sleevib8d7ea02018-05-07 20:01:012652 StaticSocketDataProvider data1(data_reads1, data_writes1);
2653 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:072654 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2655 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:162656
[email protected]49639fa2011-12-20 23:22:412657 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:162658
tfarina42834112016-09-22 13:38:202659 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012660 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162661
2662 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012663 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162664
[email protected]58e32bb2013-01-21 18:23:252665 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162666 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
[email protected]58e32bb2013-01-21 18:23:252667 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2668
Ryan Sleevib8d7ea02018-05-07 20:01:012669 int64_t writes_size1 = CountWriteBytes(data_writes1);
bnc691fda62016-08-12 00:43:162670 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012671 int64_t reads_size1 = CountReadBytes(data_reads1);
bnc691fda62016-08-12 00:43:162672 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192673
bnc691fda62016-08-12 00:43:162674 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522675 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042676 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:162677
[email protected]49639fa2011-12-20 23:22:412678 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:162679
bnc691fda62016-08-12 00:43:162680 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012681 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162682
2683 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012684 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162685
[email protected]58e32bb2013-01-21 18:23:252686 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162687 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
[email protected]58e32bb2013-01-21 18:23:252688 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2689 // The load timing after restart should have a new socket ID, and times after
2690 // those of the first load timing.
2691 EXPECT_LE(load_timing_info1.receive_headers_end,
2692 load_timing_info2.connect_timing.connect_start);
2693 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2694
Ryan Sleevib8d7ea02018-05-07 20:01:012695 int64_t writes_size2 = CountWriteBytes(data_writes2);
bnc691fda62016-08-12 00:43:162696 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012697 int64_t reads_size2 = CountReadBytes(data_reads2);
bnc691fda62016-08-12 00:43:162698 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192699
bnc691fda62016-08-12 00:43:162700 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522701 ASSERT_TRUE(response);
2702 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:162703 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:162704}
2705
ttuttled9dbc652015-09-29 20:00:592706// Test the request-challenge-retry sequence for basic auth.
2707// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012708TEST_F(HttpNetworkTransactionTest, BasicAuthWithAddressChange) {
ttuttled9dbc652015-09-29 20:00:592709 HttpRequestInfo request;
2710 request.method = "GET";
2711 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102712 request.traffic_annotation =
2713 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttled9dbc652015-09-29 20:00:592714
2715 TestNetLog log;
2716 MockHostResolver* resolver = new MockHostResolver();
2717 session_deps_.net_log = &log;
2718 session_deps_.host_resolver.reset(resolver);
danakj1fd259a02016-04-16 03:17:092719 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
bnc691fda62016-08-12 00:43:162720 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttled9dbc652015-09-29 20:00:592721
2722 resolver->rules()->ClearRules();
2723 resolver->rules()->AddRule("www.example.org", "127.0.0.1");
2724
2725 MockWrite data_writes1[] = {
2726 MockWrite("GET / HTTP/1.1\r\n"
2727 "Host: www.example.org\r\n"
2728 "Connection: keep-alive\r\n\r\n"),
2729 };
2730
2731 MockRead data_reads1[] = {
2732 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2733 // Give a couple authenticate options (only the middle one is actually
2734 // supported).
2735 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
2736 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2737 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2738 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2739 // Large content-length -- won't matter, as connection will be reset.
2740 MockRead("Content-Length: 10000\r\n\r\n"),
2741 MockRead(SYNCHRONOUS, ERR_FAILED),
2742 };
2743
2744 // After calling trans->RestartWithAuth(), this is the request we should
2745 // be issuing -- the final header line contains the credentials.
2746 MockWrite data_writes2[] = {
2747 MockWrite("GET / HTTP/1.1\r\n"
2748 "Host: www.example.org\r\n"
2749 "Connection: keep-alive\r\n"
2750 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2751 };
2752
2753 // Lastly, the server responds with the actual content.
2754 MockRead data_reads2[] = {
2755 MockRead("HTTP/1.0 200 OK\r\n"),
2756 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2757 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, OK),
2758 };
2759
Ryan Sleevib8d7ea02018-05-07 20:01:012760 StaticSocketDataProvider data1(data_reads1, data_writes1);
2761 StaticSocketDataProvider data2(data_reads2, data_writes2);
ttuttled9dbc652015-09-29 20:00:592762 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2763 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2764
2765 TestCompletionCallback callback1;
2766
bnc691fda62016-08-12 00:43:162767 EXPECT_EQ(OK, callback1.GetResult(trans.Start(&request, callback1.callback(),
tfarina42834112016-09-22 13:38:202768 NetLogWithSource())));
ttuttled9dbc652015-09-29 20:00:592769
2770 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162771 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
ttuttled9dbc652015-09-29 20:00:592772 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2773
Ryan Sleevib8d7ea02018-05-07 20:01:012774 int64_t writes_size1 = CountWriteBytes(data_writes1);
bnc691fda62016-08-12 00:43:162775 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012776 int64_t reads_size1 = CountReadBytes(data_reads1);
bnc691fda62016-08-12 00:43:162777 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592778
bnc691fda62016-08-12 00:43:162779 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592780 ASSERT_TRUE(response);
2781 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2782
2783 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:162784 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592785 ASSERT_FALSE(endpoint.address().empty());
2786 EXPECT_EQ("127.0.0.1:80", endpoint.ToString());
2787
2788 resolver->rules()->ClearRules();
2789 resolver->rules()->AddRule("www.example.org", "127.0.0.2");
2790
2791 TestCompletionCallback callback2;
2792
bnc691fda62016-08-12 00:43:162793 EXPECT_EQ(OK, callback2.GetResult(trans.RestartWithAuth(
ttuttled9dbc652015-09-29 20:00:592794 AuthCredentials(kFoo, kBar), callback2.callback())));
2795
2796 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162797 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
ttuttled9dbc652015-09-29 20:00:592798 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2799 // The load timing after restart should have a new socket ID, and times after
2800 // those of the first load timing.
2801 EXPECT_LE(load_timing_info1.receive_headers_end,
2802 load_timing_info2.connect_timing.connect_start);
2803 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2804
Ryan Sleevib8d7ea02018-05-07 20:01:012805 int64_t writes_size2 = CountWriteBytes(data_writes2);
bnc691fda62016-08-12 00:43:162806 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012807 int64_t reads_size2 = CountReadBytes(data_reads2);
bnc691fda62016-08-12 00:43:162808 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592809
bnc691fda62016-08-12 00:43:162810 response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592811 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:522812 EXPECT_FALSE(response->auth_challenge);
ttuttled9dbc652015-09-29 20:00:592813 EXPECT_EQ(100, response->headers->GetContentLength());
2814
bnc691fda62016-08-12 00:43:162815 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592816 ASSERT_FALSE(endpoint.address().empty());
2817 EXPECT_EQ("127.0.0.2:80", endpoint.ToString());
2818}
2819
David Benjamin83ddfb32018-03-30 01:07:522820// Test that, if the server requests auth indefinitely, HttpNetworkTransaction
2821// will eventually give up.
2822TEST_F(HttpNetworkTransactionTest, BasicAuthForever) {
2823 HttpRequestInfo request;
2824 request.method = "GET";
2825 request.url = GURL("http://www.example.org/");
2826 request.traffic_annotation =
2827 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2828
2829 TestNetLog log;
2830 session_deps_.net_log = &log;
2831 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2832 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
2833
2834 MockWrite data_writes[] = {
2835 MockWrite("GET / HTTP/1.1\r\n"
2836 "Host: www.example.org\r\n"
2837 "Connection: keep-alive\r\n\r\n"),
2838 };
2839
2840 MockRead data_reads[] = {
2841 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2842 // Give a couple authenticate options (only the middle one is actually
2843 // supported).
2844 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
2845 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2846 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2847 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2848 // Large content-length -- won't matter, as connection will be reset.
2849 MockRead("Content-Length: 10000\r\n\r\n"),
2850 MockRead(SYNCHRONOUS, ERR_FAILED),
2851 };
2852
2853 // After calling trans->RestartWithAuth(), this is the request we should
2854 // be issuing -- the final header line contains the credentials.
2855 MockWrite data_writes_restart[] = {
2856 MockWrite("GET / HTTP/1.1\r\n"
2857 "Host: www.example.org\r\n"
2858 "Connection: keep-alive\r\n"
2859 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2860 };
2861
Ryan Sleevib8d7ea02018-05-07 20:01:012862 StaticSocketDataProvider data(data_reads, data_writes);
David Benjamin83ddfb32018-03-30 01:07:522863 session_deps_.socket_factory->AddSocketDataProvider(&data);
2864
2865 TestCompletionCallback callback;
2866 int rv = callback.GetResult(
2867 trans.Start(&request, callback.callback(), NetLogWithSource()));
2868
2869 std::vector<std::unique_ptr<StaticSocketDataProvider>> data_restarts;
2870 for (int i = 0; i < 32; i++) {
2871 // Check the previous response was a 401.
2872 EXPECT_THAT(rv, IsOk());
2873 const HttpResponseInfo* response = trans.GetResponseInfo();
2874 ASSERT_TRUE(response);
2875 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2876
2877 data_restarts.push_back(std::make_unique<StaticSocketDataProvider>(
Ryan Sleevib8d7ea02018-05-07 20:01:012878 data_reads, data_writes_restart));
David Benjamin83ddfb32018-03-30 01:07:522879 session_deps_.socket_factory->AddSocketDataProvider(
2880 data_restarts.back().get());
2881 rv = callback.GetResult(trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
2882 callback.callback()));
2883 }
2884
2885 // After too many tries, the transaction should have given up.
2886 EXPECT_THAT(rv, IsError(ERR_TOO_MANY_RETRIES));
2887}
2888
bncd16676a2016-07-20 16:23:012889TEST_F(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:462890 HttpRequestInfo request;
2891 request.method = "GET";
bncce36dca22015-04-21 22:11:232892 request.url = GURL("http://www.example.org/");
ttuttle859dc7a2015-04-23 19:42:292893 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:102894 request.traffic_annotation =
2895 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]861fcd52009-08-26 02:33:462896
danakj1fd259a02016-04-16 03:17:092897 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162898 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272899
[email protected]861fcd52009-08-26 02:33:462900 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:232901 MockWrite(
2902 "GET / HTTP/1.1\r\n"
2903 "Host: www.example.org\r\n"
2904 "Connection: keep-alive\r\n\r\n"),
[email protected]861fcd52009-08-26 02:33:462905 };
2906
2907 MockRead data_reads[] = {
2908 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2909 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2910 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2911 // Large content-length -- won't matter, as connection will be reset.
2912 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062913 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:462914 };
2915
Ryan Sleevib8d7ea02018-05-07 20:01:012916 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:072917 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:412918 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:462919
tfarina42834112016-09-22 13:38:202920 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012921 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]861fcd52009-08-26 02:33:462922
2923 rv = callback.WaitForResult();
2924 EXPECT_EQ(0, rv);
2925
Ryan Sleevib8d7ea02018-05-07 20:01:012926 int64_t writes_size = CountWriteBytes(data_writes);
bnc691fda62016-08-12 00:43:162927 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012928 int64_t reads_size = CountReadBytes(data_reads);
bnc691fda62016-08-12 00:43:162929 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192930
bnc691fda62016-08-12 00:43:162931 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522932 ASSERT_TRUE(response);
2933 EXPECT_FALSE(response->auth_challenge);
[email protected]861fcd52009-08-26 02:33:462934}
2935
[email protected]2d2697f92009-02-18 21:00:322936// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2937// connection.
bncd16676a2016-07-20 16:23:012938TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
mmenkecc2298e2015-12-07 18:20:182939 // On the second pass, the body read of the auth challenge is synchronous, so
2940 // IsConnectedAndIdle returns false. The socket should still be drained and
2941 // reused. See http://crbug.com/544255.
2942 for (int i = 0; i < 2; ++i) {
2943 HttpRequestInfo request;
2944 request.method = "GET";
2945 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102946 request.traffic_annotation =
2947 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:322948
mmenkecc2298e2015-12-07 18:20:182949 TestNetLog log;
2950 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092951 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272952
mmenkecc2298e2015-12-07 18:20:182953 MockWrite data_writes[] = {
2954 MockWrite(ASYNC, 0,
2955 "GET / HTTP/1.1\r\n"
2956 "Host: www.example.org\r\n"
2957 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322958
bnc691fda62016-08-12 00:43:162959 // After calling trans.RestartWithAuth(), this is the request we should
mmenkecc2298e2015-12-07 18:20:182960 // be issuing -- the final header line contains the credentials.
2961 MockWrite(ASYNC, 6,
2962 "GET / HTTP/1.1\r\n"
2963 "Host: www.example.org\r\n"
2964 "Connection: keep-alive\r\n"
2965 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2966 };
[email protected]2d2697f92009-02-18 21:00:322967
mmenkecc2298e2015-12-07 18:20:182968 MockRead data_reads[] = {
2969 MockRead(ASYNC, 1, "HTTP/1.1 401 Unauthorized\r\n"),
2970 MockRead(ASYNC, 2, "WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2971 MockRead(ASYNC, 3, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2972 MockRead(ASYNC, 4, "Content-Length: 14\r\n\r\n"),
2973 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 5, "Unauthorized\r\n"),
[email protected]2d2697f92009-02-18 21:00:322974
mmenkecc2298e2015-12-07 18:20:182975 // Lastly, the server responds with the actual content.
2976 MockRead(ASYNC, 7, "HTTP/1.1 200 OK\r\n"),
2977 MockRead(ASYNC, 8, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2978 MockRead(ASYNC, 9, "Content-Length: 5\r\n\r\n"),
2979 MockRead(ASYNC, 10, "Hello"),
2980 };
[email protected]2d2697f92009-02-18 21:00:322981
Ryan Sleevib8d7ea02018-05-07 20:01:012982 SequencedSocketData data(data_reads, data_writes);
mmenkecc2298e2015-12-07 18:20:182983 data.set_busy_before_sync_reads(true);
2984 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]2d0a4f92011-05-05 16:38:462985
mmenkecc2298e2015-12-07 18:20:182986 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322987
bnc691fda62016-08-12 00:43:162988 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202989 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012990 ASSERT_THAT(callback1.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322991
mmenkecc2298e2015-12-07 18:20:182992 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162993 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
mmenkecc2298e2015-12-07 18:20:182994 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
[email protected]2d2697f92009-02-18 21:00:322995
bnc691fda62016-08-12 00:43:162996 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182997 ASSERT_TRUE(response);
2998 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322999
mmenkecc2298e2015-12-07 18:20:183000 TestCompletionCallback callback2;
[email protected]58e32bb2013-01-21 18:23:253001
bnc691fda62016-08-12 00:43:163002 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
3003 callback2.callback());
robpercival214763f2016-07-01 23:27:013004 ASSERT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:323005
mmenkecc2298e2015-12-07 18:20:183006 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:163007 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
mmenkecc2298e2015-12-07 18:20:183008 TestLoadTimingReused(load_timing_info2);
3009 // The load timing after restart should have the same socket ID, and times
3010 // those of the first load timing.
3011 EXPECT_LE(load_timing_info1.receive_headers_end,
3012 load_timing_info2.send_start);
3013 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]2d2697f92009-02-18 21:00:323014
bnc691fda62016-08-12 00:43:163015 response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:183016 ASSERT_TRUE(response);
3017 EXPECT_FALSE(response->auth_challenge);
3018 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:323019
mmenkecc2298e2015-12-07 18:20:183020 std::string response_data;
bnc691fda62016-08-12 00:43:163021 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]2d2697f92009-02-18 21:00:323022
Ryan Sleevib8d7ea02018-05-07 20:01:013023 int64_t writes_size = CountWriteBytes(data_writes);
bnc691fda62016-08-12 00:43:163024 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:013025 int64_t reads_size = CountReadBytes(data_reads);
bnc691fda62016-08-12 00:43:163026 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
mmenkecc2298e2015-12-07 18:20:183027 }
[email protected]2d2697f92009-02-18 21:00:323028}
3029
3030// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3031// connection and with no response body to drain.
bncd16676a2016-07-20 16:23:013032TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:423033 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:323034 request.method = "GET";
bncce36dca22015-04-21 22:11:233035 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:103036 request.traffic_annotation =
3037 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:323038
danakj1fd259a02016-04-16 03:17:093039 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273040
[email protected]2d2697f92009-02-18 21:00:323041 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:163042 MockWrite("GET / HTTP/1.1\r\n"
3043 "Host: www.example.org\r\n"
3044 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323045
bnc691fda62016-08-12 00:43:163046 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:233047 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:163048 MockWrite("GET / HTTP/1.1\r\n"
3049 "Host: www.example.org\r\n"
3050 "Connection: keep-alive\r\n"
3051 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323052 };
3053
[email protected]2d2697f92009-02-18 21:00:323054 MockRead data_reads1[] = {
3055 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
3056 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:313057 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:323058
3059 // Lastly, the server responds with the actual content.
3060 MockRead("HTTP/1.1 200 OK\r\n"),
3061 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:503062 MockRead("Content-Length: 5\r\n\r\n"),
3063 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:323064 };
3065
[email protected]2d0a4f92011-05-05 16:38:463066 // An incorrect reconnect would cause this to be read.
3067 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:063068 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:463069 };
3070
Ryan Sleevib8d7ea02018-05-07 20:01:013071 StaticSocketDataProvider data1(data_reads1, data_writes1);
3072 StaticSocketDataProvider data2(data_reads2, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:073073 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3074 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:323075
[email protected]49639fa2011-12-20 23:22:413076 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323077
bnc691fda62016-08-12 00:43:163078 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:203079 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013080 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:323081
3082 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013083 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:323084
bnc691fda62016-08-12 00:43:163085 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523086 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:043087 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:323088
[email protected]49639fa2011-12-20 23:22:413089 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323090
bnc691fda62016-08-12 00:43:163091 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013092 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:323093
3094 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013095 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:323096
bnc691fda62016-08-12 00:43:163097 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523098 ASSERT_TRUE(response);
3099 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503100 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:323101}
3102
3103// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3104// connection and with a large response body to drain.
bncd16676a2016-07-20 16:23:013105TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:423106 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:323107 request.method = "GET";
bncce36dca22015-04-21 22:11:233108 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:103109 request.traffic_annotation =
3110 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:323111
danakj1fd259a02016-04-16 03:17:093112 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273113
[email protected]2d2697f92009-02-18 21:00:323114 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:163115 MockWrite("GET / HTTP/1.1\r\n"
3116 "Host: www.example.org\r\n"
3117 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323118
bnc691fda62016-08-12 00:43:163119 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:233120 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:163121 MockWrite("GET / HTTP/1.1\r\n"
3122 "Host: www.example.org\r\n"
3123 "Connection: keep-alive\r\n"
3124 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323125 };
3126
3127 // Respond with 5 kb of response body.
3128 std::string large_body_string("Unauthorized");
3129 large_body_string.append(5 * 1024, ' ');
3130 large_body_string.append("\r\n");
3131
3132 MockRead data_reads1[] = {
3133 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
3134 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3135 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3136 // 5134 = 12 + 5 * 1024 + 2
3137 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063138 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:323139
3140 // Lastly, the server responds with the actual content.
3141 MockRead("HTTP/1.1 200 OK\r\n"),
3142 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:503143 MockRead("Content-Length: 5\r\n\r\n"),
3144 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:323145 };
3146
[email protected]2d0a4f92011-05-05 16:38:463147 // An incorrect reconnect would cause this to be read.
3148 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:063149 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:463150 };
3151
Ryan Sleevib8d7ea02018-05-07 20:01:013152 StaticSocketDataProvider data1(data_reads1, data_writes1);
3153 StaticSocketDataProvider data2(data_reads2, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:073154 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3155 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:323156
[email protected]49639fa2011-12-20 23:22:413157 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323158
bnc691fda62016-08-12 00:43:163159 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:203160 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013161 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:323162
3163 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013164 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:323165
bnc691fda62016-08-12 00:43:163166 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523167 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:043168 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:323169
[email protected]49639fa2011-12-20 23:22:413170 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323171
bnc691fda62016-08-12 00:43:163172 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013173 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:323174
3175 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013176 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:323177
bnc691fda62016-08-12 00:43:163178 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523179 ASSERT_TRUE(response);
3180 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503181 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:323182}
3183
3184// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:313185// connection, but the server gets impatient and closes the connection.
bncd16676a2016-07-20 16:23:013186TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:313187 HttpRequestInfo request;
3188 request.method = "GET";
bncce36dca22015-04-21 22:11:233189 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:103190 request.traffic_annotation =
3191 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]11203f012009-11-12 23:02:313192
danakj1fd259a02016-04-16 03:17:093193 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273194
[email protected]11203f012009-11-12 23:02:313195 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233196 MockWrite(
3197 "GET / HTTP/1.1\r\n"
3198 "Host: www.example.org\r\n"
3199 "Connection: keep-alive\r\n\r\n"),
3200 // This simulates the seemingly successful write to a closed connection
3201 // if the bug is not fixed.
3202 MockWrite(
3203 "GET / HTTP/1.1\r\n"
3204 "Host: www.example.org\r\n"
3205 "Connection: keep-alive\r\n"
3206 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:313207 };
3208
3209 MockRead data_reads1[] = {
3210 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
3211 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3212 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3213 MockRead("Content-Length: 14\r\n\r\n"),
3214 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:063215 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:313216 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:063217 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:313218 };
3219
bnc691fda62016-08-12 00:43:163220 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]11203f012009-11-12 23:02:313221 // be issuing -- the final header line contains the credentials.
3222 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:233223 MockWrite(
3224 "GET / HTTP/1.1\r\n"
3225 "Host: www.example.org\r\n"
3226 "Connection: keep-alive\r\n"
3227 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:313228 };
3229
3230 // Lastly, the server responds with the actual content.
3231 MockRead data_reads2[] = {
3232 MockRead("HTTP/1.1 200 OK\r\n"),
3233 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:503234 MockRead("Content-Length: 5\r\n\r\n"),
3235 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:313236 };
3237
Ryan Sleevib8d7ea02018-05-07 20:01:013238 StaticSocketDataProvider data1(data_reads1, data_writes1);
3239 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:073240 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3241 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:313242
[email protected]49639fa2011-12-20 23:22:413243 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:313244
bnc691fda62016-08-12 00:43:163245 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:203246 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013247 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:313248
3249 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013250 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:313251
bnc691fda62016-08-12 00:43:163252 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523253 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:043254 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:313255
[email protected]49639fa2011-12-20 23:22:413256 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:313257
bnc691fda62016-08-12 00:43:163258 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013259 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:313260
3261 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013262 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:313263
bnc691fda62016-08-12 00:43:163264 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523265 ASSERT_TRUE(response);
3266 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503267 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:313268}
3269
[email protected]394816e92010-08-03 07:38:593270// Test the request-challenge-retry sequence for basic auth, over a connection
3271// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013272TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
ttuttle34f63b52015-03-05 04:33:013273 HttpRequestInfo request;
3274 request.method = "GET";
bncce36dca22015-04-21 22:11:233275 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:013276 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293277 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103278 request.traffic_annotation =
3279 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle34f63b52015-03-05 04:33:013280
3281 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593282 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493283 ProxyResolutionService::CreateFixedFromPacResult(
3284 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513285 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:013286 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093287 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013288
3289 // Since we have proxy, should try to establish tunnel.
3290 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543291 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173292 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543293 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013294 };
3295
mmenkee71e15332015-10-07 16:39:543296 // The proxy responds to the connect with a 407, using a non-persistent
ttuttle34f63b52015-03-05 04:33:013297 // connection.
3298 MockRead data_reads1[] = {
3299 // No credentials.
3300 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
3301 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
mmenkee71e15332015-10-07 16:39:543302 };
ttuttle34f63b52015-03-05 04:33:013303
mmenkee71e15332015-10-07 16:39:543304 // Since the first connection couldn't be reused, need to establish another
3305 // once given credentials.
3306 MockWrite data_writes2[] = {
3307 // After calling trans->RestartWithAuth(), this is the request we should
3308 // be issuing -- the final header line contains the credentials.
3309 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173310 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543311 "Proxy-Connection: keep-alive\r\n"
3312 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3313
3314 MockWrite("GET / HTTP/1.1\r\n"
3315 "Host: www.example.org\r\n"
3316 "Connection: keep-alive\r\n\r\n"),
3317 };
3318
3319 MockRead data_reads2[] = {
ttuttle34f63b52015-03-05 04:33:013320 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3321
3322 MockRead("HTTP/1.1 200 OK\r\n"),
3323 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3324 MockRead("Content-Length: 5\r\n\r\n"),
3325 MockRead(SYNCHRONOUS, "hello"),
3326 };
3327
Ryan Sleevib8d7ea02018-05-07 20:01:013328 StaticSocketDataProvider data1(data_reads1, data_writes1);
ttuttle34f63b52015-03-05 04:33:013329 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:013330 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenkee71e15332015-10-07 16:39:543331 session_deps_.socket_factory->AddSocketDataProvider(&data2);
ttuttle34f63b52015-03-05 04:33:013332 SSLSocketDataProvider ssl(ASYNC, OK);
3333 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3334
3335 TestCompletionCallback callback1;
3336
bnc87dcefc2017-05-25 12:47:583337 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193338 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013339
3340 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013341 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:013342
3343 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013344 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463345 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:013346 log.GetEntries(&entries);
3347 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003348 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3349 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013350 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003351 entries, pos,
3352 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3353 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013354
3355 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523356 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013357 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523358 ASSERT_TRUE(response->headers);
ttuttle34f63b52015-03-05 04:33:013359 EXPECT_EQ(407, response->headers->response_code());
3360 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3361 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3362
3363 LoadTimingInfo load_timing_info;
3364 // CONNECT requests and responses are handled at the connect job level, so
3365 // the transaction does not yet have a connection.
3366 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3367
3368 TestCompletionCallback callback2;
3369
3370 rv =
3371 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013372 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:013373
3374 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013375 EXPECT_THAT(rv, IsOk());
ttuttle34f63b52015-03-05 04:33:013376
3377 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523378 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013379
3380 EXPECT_TRUE(response->headers->IsKeepAlive());
3381 EXPECT_EQ(200, response->headers->response_code());
3382 EXPECT_EQ(5, response->headers->GetContentLength());
3383 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3384
3385 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523386 EXPECT_FALSE(response->auth_challenge);
ttuttle34f63b52015-03-05 04:33:013387
3388 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3389 TestLoadTimingNotReusedWithPac(load_timing_info,
3390 CONNECT_TIMING_HAS_SSL_TIMES);
3391
3392 trans.reset();
3393 session->CloseAllConnections();
3394}
3395
3396// Test the request-challenge-retry sequence for basic auth, over a connection
3397// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013398TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) {
[email protected]394816e92010-08-03 07:38:593399 HttpRequestInfo request;
3400 request.method = "GET";
bncce36dca22015-04-21 22:11:233401 request.url = GURL("https://www.example.org/");
[email protected]394816e92010-08-03 07:38:593402 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293403 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103404 request.traffic_annotation =
3405 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]394816e92010-08-03 07:38:593406
[email protected]cb9bf6ca2011-01-28 13:15:273407 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593408 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493409 ProxyResolutionService::CreateFixedFromPacResult(
3410 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513411 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073412 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093413 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273414
[email protected]394816e92010-08-03 07:38:593415 // Since we have proxy, should try to establish tunnel.
3416 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543417 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173418 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543419 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenkee0b5c882015-08-26 20:29:113420 };
3421
mmenkee71e15332015-10-07 16:39:543422 // The proxy responds to the connect with a 407, using a non-persistent
mmenke0fd148d2015-09-30 23:00:083423 // connection.
3424 MockRead data_reads1[] = {
mmenkee71e15332015-10-07 16:39:543425 // No credentials.
3426 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3427 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3428 MockRead("Proxy-Connection: close\r\n\r\n"),
3429 };
mmenkee0b5c882015-08-26 20:29:113430
mmenkee71e15332015-10-07 16:39:543431 MockWrite data_writes2[] = {
3432 // After calling trans->RestartWithAuth(), this is the request we should
3433 // be issuing -- the final header line contains the credentials.
3434 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173435 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543436 "Proxy-Connection: keep-alive\r\n"
3437 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
mmenke0fd148d2015-09-30 23:00:083438
mmenkee71e15332015-10-07 16:39:543439 MockWrite("GET / HTTP/1.1\r\n"
3440 "Host: www.example.org\r\n"
3441 "Connection: keep-alive\r\n\r\n"),
3442 };
3443
3444 MockRead data_reads2[] = {
3445 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3446
3447 MockRead("HTTP/1.1 200 OK\r\n"),
3448 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3449 MockRead("Content-Length: 5\r\n\r\n"),
3450 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:593451 };
3452
Ryan Sleevib8d7ea02018-05-07 20:01:013453 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:073454 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:013455 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenkee71e15332015-10-07 16:39:543456 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8ddf8322012-02-23 18:08:063457 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073458 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:593459
[email protected]49639fa2011-12-20 23:22:413460 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:593461
bnc87dcefc2017-05-25 12:47:583462 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193463 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:503464
[email protected]49639fa2011-12-20 23:22:413465 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013466 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593467
3468 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013469 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463470 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403471 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:593472 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003473 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3474 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593475 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403476 entries, pos,
mikecirone8b85c432016-09-08 19:11:003477 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3478 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593479
3480 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523481 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013482 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523483 ASSERT_TRUE(response->headers);
[email protected]394816e92010-08-03 07:38:593484 EXPECT_EQ(407, response->headers->response_code());
3485 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043486 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:593487
[email protected]029c83b62013-01-24 05:28:203488 LoadTimingInfo load_timing_info;
3489 // CONNECT requests and responses are handled at the connect job level, so
3490 // the transaction does not yet have a connection.
3491 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3492
[email protected]49639fa2011-12-20 23:22:413493 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:593494
[email protected]49639fa2011-12-20 23:22:413495 rv = trans->RestartWithAuth(
3496 AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013497 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593498
3499 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013500 EXPECT_THAT(rv, IsOk());
[email protected]394816e92010-08-03 07:38:593501
3502 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523503 ASSERT_TRUE(response);
[email protected]394816e92010-08-03 07:38:593504
3505 EXPECT_TRUE(response->headers->IsKeepAlive());
3506 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:503507 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:593508 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3509
3510 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523511 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503512
[email protected]029c83b62013-01-24 05:28:203513 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3514 TestLoadTimingNotReusedWithPac(load_timing_info,
3515 CONNECT_TIMING_HAS_SSL_TIMES);
3516
[email protected]0b0bf032010-09-21 18:08:503517 trans.reset();
[email protected]102e27c2011-02-23 01:01:313518 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:593519}
3520
[email protected]11203f012009-11-12 23:02:313521// Test the request-challenge-retry sequence for basic auth, over a keep-alive
ttuttle34f63b52015-03-05 04:33:013522// proxy connection with HTTP/1.0 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013523TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
mmenked39192ee2015-12-09 00:57:233524 // On the second pass, the body read of the auth challenge is synchronous, so
3525 // IsConnectedAndIdle returns false. The socket should still be drained and
3526 // reused. See http://crbug.com/544255.
3527 for (int i = 0; i < 2; ++i) {
3528 HttpRequestInfo request;
3529 request.method = "GET";
3530 request.url = GURL("https://www.example.org/");
3531 // Ensure that proxy authentication is attempted even
3532 // when the no authentication data flag is set.
3533 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103534 request.traffic_annotation =
3535 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle34f63b52015-03-05 04:33:013536
mmenked39192ee2015-12-09 00:57:233537 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593538 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493539 ProxyResolutionService::CreateFixed("myproxy:70",
3540 TRAFFIC_ANNOTATION_FOR_TESTS);
mmenked39192ee2015-12-09 00:57:233541 BoundTestNetLog log;
3542 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093543 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013544
bnc691fda62016-08-12 00:43:163545 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013546
mmenked39192ee2015-12-09 00:57:233547 // Since we have proxy, should try to establish tunnel.
3548 MockWrite data_writes1[] = {
3549 MockWrite(ASYNC, 0,
3550 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3551 "Host: www.example.org:443\r\n"
3552 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013553
bnc691fda62016-08-12 00:43:163554 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233555 // be issuing -- the final header line contains the credentials.
3556 MockWrite(ASYNC, 3,
3557 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3558 "Host: www.example.org:443\r\n"
3559 "Proxy-Connection: keep-alive\r\n"
3560 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3561 };
ttuttle34f63b52015-03-05 04:33:013562
mmenked39192ee2015-12-09 00:57:233563 // The proxy responds to the connect with a 407, using a persistent
3564 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3565 MockRead data_reads1[] = {
3566 // No credentials.
3567 MockRead(ASYNC, 1,
3568 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3569 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3570 "Proxy-Connection: keep-alive\r\n"
3571 "Content-Length: 10\r\n\r\n"),
3572 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
ttuttle34f63b52015-03-05 04:33:013573
mmenked39192ee2015-12-09 00:57:233574 // Wrong credentials (wrong password).
3575 MockRead(ASYNC, 4,
3576 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3577 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3578 "Proxy-Connection: keep-alive\r\n"
3579 "Content-Length: 10\r\n\r\n"),
3580 // No response body because the test stops reading here.
3581 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3582 };
ttuttle34f63b52015-03-05 04:33:013583
Ryan Sleevib8d7ea02018-05-07 20:01:013584 SequencedSocketData data1(data_reads1, data_writes1);
mmenked39192ee2015-12-09 00:57:233585 data1.set_busy_before_sync_reads(true);
3586 session_deps_.socket_factory->AddSocketDataProvider(&data1);
ttuttle34f63b52015-03-05 04:33:013587
mmenked39192ee2015-12-09 00:57:233588 TestCompletionCallback callback1;
ttuttle34f63b52015-03-05 04:33:013589
bnc691fda62016-08-12 00:43:163590 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013591 EXPECT_THAT(callback1.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013592
mmenked39192ee2015-12-09 00:57:233593 TestNetLogEntry::List entries;
3594 log.GetEntries(&entries);
3595 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003596 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3597 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233598 ExpectLogContainsSomewhere(
3599 entries, pos,
mikecirone8b85c432016-09-08 19:11:003600 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3601 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013602
bnc691fda62016-08-12 00:43:163603 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233604 ASSERT_TRUE(response);
3605 ASSERT_TRUE(response->headers);
3606 EXPECT_TRUE(response->headers->IsKeepAlive());
3607 EXPECT_EQ(407, response->headers->response_code());
3608 EXPECT_EQ(10, response->headers->GetContentLength());
3609 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3610 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013611
mmenked39192ee2015-12-09 00:57:233612 TestCompletionCallback callback2;
ttuttle34f63b52015-03-05 04:33:013613
mmenked39192ee2015-12-09 00:57:233614 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163615 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3616 callback2.callback());
robpercival214763f2016-07-01 23:27:013617 EXPECT_THAT(callback2.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013618
bnc691fda62016-08-12 00:43:163619 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233620 ASSERT_TRUE(response);
3621 ASSERT_TRUE(response->headers);
3622 EXPECT_TRUE(response->headers->IsKeepAlive());
3623 EXPECT_EQ(407, response->headers->response_code());
3624 EXPECT_EQ(10, response->headers->GetContentLength());
3625 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3626 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013627
mmenked39192ee2015-12-09 00:57:233628 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3629 // out of scope.
3630 session->CloseAllConnections();
3631 }
ttuttle34f63b52015-03-05 04:33:013632}
3633
3634// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3635// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013636TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
mmenked39192ee2015-12-09 00:57:233637 // On the second pass, the body read of the auth challenge is synchronous, so
3638 // IsConnectedAndIdle returns false. The socket should still be drained and
3639 // reused. See http://crbug.com/544255.
3640 for (int i = 0; i < 2; ++i) {
3641 HttpRequestInfo request;
3642 request.method = "GET";
3643 request.url = GURL("https://www.example.org/");
3644 // Ensure that proxy authentication is attempted even
3645 // when the no authentication data flag is set.
3646 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103647 request.traffic_annotation =
3648 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenked39192ee2015-12-09 00:57:233649
3650 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593651 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493652 ProxyResolutionService::CreateFixed("myproxy:70",
3653 TRAFFIC_ANNOTATION_FOR_TESTS);
mmenked39192ee2015-12-09 00:57:233654 BoundTestNetLog log;
3655 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093656 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenked39192ee2015-12-09 00:57:233657
bnc691fda62016-08-12 00:43:163658 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenked39192ee2015-12-09 00:57:233659
3660 // Since we have proxy, should try to establish tunnel.
3661 MockWrite data_writes1[] = {
3662 MockWrite(ASYNC, 0,
3663 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3664 "Host: www.example.org:443\r\n"
3665 "Proxy-Connection: keep-alive\r\n\r\n"),
3666
bnc691fda62016-08-12 00:43:163667 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233668 // be issuing -- the final header line contains the credentials.
3669 MockWrite(ASYNC, 3,
3670 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3671 "Host: www.example.org:443\r\n"
3672 "Proxy-Connection: keep-alive\r\n"
3673 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3674 };
3675
3676 // The proxy responds to the connect with a 407, using a persistent
3677 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3678 MockRead data_reads1[] = {
3679 // No credentials.
3680 MockRead(ASYNC, 1,
3681 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3682 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3683 "Content-Length: 10\r\n\r\n"),
3684 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
3685
3686 // Wrong credentials (wrong password).
3687 MockRead(ASYNC, 4,
3688 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3689 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3690 "Content-Length: 10\r\n\r\n"),
3691 // No response body because the test stops reading here.
3692 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3693 };
3694
Ryan Sleevib8d7ea02018-05-07 20:01:013695 SequencedSocketData data1(data_reads1, data_writes1);
mmenked39192ee2015-12-09 00:57:233696 data1.set_busy_before_sync_reads(true);
3697 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3698
3699 TestCompletionCallback callback1;
3700
bnc691fda62016-08-12 00:43:163701 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013702 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233703
3704 TestNetLogEntry::List entries;
3705 log.GetEntries(&entries);
3706 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003707 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3708 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233709 ExpectLogContainsSomewhere(
3710 entries, pos,
mikecirone8b85c432016-09-08 19:11:003711 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3712 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233713
bnc691fda62016-08-12 00:43:163714 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233715 ASSERT_TRUE(response);
3716 ASSERT_TRUE(response->headers);
3717 EXPECT_TRUE(response->headers->IsKeepAlive());
3718 EXPECT_EQ(407, response->headers->response_code());
3719 EXPECT_EQ(10, response->headers->GetContentLength());
3720 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3721 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3722
3723 TestCompletionCallback callback2;
3724
3725 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163726 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3727 callback2.callback());
robpercival214763f2016-07-01 23:27:013728 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233729
bnc691fda62016-08-12 00:43:163730 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233731 ASSERT_TRUE(response);
3732 ASSERT_TRUE(response->headers);
3733 EXPECT_TRUE(response->headers->IsKeepAlive());
3734 EXPECT_EQ(407, response->headers->response_code());
3735 EXPECT_EQ(10, response->headers->GetContentLength());
3736 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3737 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3738
3739 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3740 // out of scope.
3741 session->CloseAllConnections();
3742 }
3743}
3744
3745// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3746// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel, in
3747// the case the server sends extra data on the original socket, so it can't be
3748// reused.
bncd16676a2016-07-20 16:23:013749TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveExtraData) {
[email protected]cb9bf6ca2011-01-28 13:15:273750 HttpRequestInfo request;
3751 request.method = "GET";
bncce36dca22015-04-21 22:11:233752 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273753 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293754 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103755 request.traffic_annotation =
3756 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:273757
[email protected]2d2697f92009-02-18 21:00:323758 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593759 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493760 ProxyResolutionService::CreateFixedFromPacResult(
3761 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513762 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073763 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093764 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:323765
[email protected]2d2697f92009-02-18 21:00:323766 // Since we have proxy, should try to establish tunnel.
3767 MockWrite data_writes1[] = {
mmenked39192ee2015-12-09 00:57:233768 MockWrite(ASYNC, 0,
3769 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173770 "Host: www.example.org:443\r\n"
3771 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233772 };
[email protected]2d2697f92009-02-18 21:00:323773
mmenked39192ee2015-12-09 00:57:233774 // The proxy responds to the connect with a 407, using a persistent, but sends
3775 // extra data, so the socket cannot be reused.
3776 MockRead data_reads1[] = {
3777 // No credentials.
3778 MockRead(ASYNC, 1,
3779 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3780 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3781 "Content-Length: 10\r\n\r\n"),
3782 MockRead(SYNCHRONOUS, 2, "0123456789"),
3783 MockRead(SYNCHRONOUS, 3, "I'm broken!"),
3784 };
3785
3786 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:233787 // After calling trans->RestartWithAuth(), this is the request we should
3788 // be issuing -- the final header line contains the credentials.
mmenked39192ee2015-12-09 00:57:233789 MockWrite(ASYNC, 0,
3790 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173791 "Host: www.example.org:443\r\n"
3792 "Proxy-Connection: keep-alive\r\n"
mmenked39192ee2015-12-09 00:57:233793 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3794
3795 MockWrite(ASYNC, 2,
3796 "GET / HTTP/1.1\r\n"
3797 "Host: www.example.org\r\n"
3798 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323799 };
3800
mmenked39192ee2015-12-09 00:57:233801 MockRead data_reads2[] = {
3802 MockRead(ASYNC, 1, "HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323803
mmenked39192ee2015-12-09 00:57:233804 MockRead(ASYNC, 3,
3805 "HTTP/1.1 200 OK\r\n"
3806 "Content-Type: text/html; charset=iso-8859-1\r\n"
3807 "Content-Length: 5\r\n\r\n"),
3808 // No response body because the test stops reading here.
3809 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 4),
[email protected]2d2697f92009-02-18 21:00:323810 };
3811
Ryan Sleevib8d7ea02018-05-07 20:01:013812 SequencedSocketData data1(data_reads1, data_writes1);
mmenked39192ee2015-12-09 00:57:233813 data1.set_busy_before_sync_reads(true);
[email protected]bb88e1d32013-05-03 23:11:073814 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:013815 SequencedSocketData data2(data_reads2, data_writes2);
mmenked39192ee2015-12-09 00:57:233816 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3817 SSLSocketDataProvider ssl(ASYNC, OK);
3818 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d2697f92009-02-18 21:00:323819
[email protected]49639fa2011-12-20 23:22:413820 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323821
bnc87dcefc2017-05-25 12:47:583822 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193823 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d2697f92009-02-18 21:00:323824
mmenked39192ee2015-12-09 00:57:233825 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013826 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233827
mmenke43758e62015-05-04 21:09:463828 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403829 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:393830 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003831 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3832 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:393833 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403834 entries, pos,
mikecirone8b85c432016-09-08 19:11:003835 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3836 NetLogEventPhase::NONE);
[email protected]2d2697f92009-02-18 21:00:323837
[email protected]1c773ea12009-04-28 19:58:423838 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243839 ASSERT_TRUE(response);
3840 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:323841 EXPECT_TRUE(response->headers->IsKeepAlive());
3842 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423843 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043844 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:323845
mmenked39192ee2015-12-09 00:57:233846 LoadTimingInfo load_timing_info;
3847 // CONNECT requests and responses are handled at the connect job level, so
3848 // the transaction does not yet have a connection.
3849 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3850
[email protected]49639fa2011-12-20 23:22:413851 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323852
mmenked39192ee2015-12-09 00:57:233853 rv =
3854 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013855 EXPECT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:323856
[email protected]2d2697f92009-02-18 21:00:323857 EXPECT_TRUE(response->headers->IsKeepAlive());
mmenked39192ee2015-12-09 00:57:233858 EXPECT_EQ(200, response->headers->response_code());
3859 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:423860 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]e772db3f2010-07-12 18:11:133861
mmenked39192ee2015-12-09 00:57:233862 // The password prompt info should not be set.
3863 EXPECT_FALSE(response->auth_challenge);
3864
3865 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3866 TestLoadTimingNotReusedWithPac(load_timing_info,
3867 CONNECT_TIMING_HAS_SSL_TIMES);
3868
3869 trans.reset();
[email protected]102e27c2011-02-23 01:01:313870 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:323871}
3872
mmenkee71e15332015-10-07 16:39:543873// Test the case a proxy closes a socket while the challenge body is being
3874// drained.
bncd16676a2016-07-20 16:23:013875TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHangupDuringBody) {
mmenkee71e15332015-10-07 16:39:543876 HttpRequestInfo request;
3877 request.method = "GET";
3878 request.url = GURL("https://www.example.org/");
3879 // Ensure that proxy authentication is attempted even
3880 // when the no authentication data flag is set.
3881 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103882 request.traffic_annotation =
3883 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenkee71e15332015-10-07 16:39:543884
3885 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:493886 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
3887 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:093888 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenkee71e15332015-10-07 16:39:543889
bnc691fda62016-08-12 00:43:163890 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkee71e15332015-10-07 16:39:543891
3892 // Since we have proxy, should try to establish tunnel.
3893 MockWrite data_writes1[] = {
3894 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173895 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543896 "Proxy-Connection: keep-alive\r\n\r\n"),
3897 };
3898
3899 // The proxy responds to the connect with a 407, using a persistent
3900 // connection.
3901 MockRead data_reads1[] = {
3902 // No credentials.
3903 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3904 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3905 MockRead("Content-Length: 10\r\n\r\n"), MockRead("spam!"),
3906 // Server hands up in the middle of the body.
3907 MockRead(ASYNC, ERR_CONNECTION_CLOSED),
3908 };
3909
3910 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:163911 // After calling trans.RestartWithAuth(), this is the request we should
mmenkee71e15332015-10-07 16:39:543912 // be issuing -- the final header line contains the credentials.
3913 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173914 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543915 "Proxy-Connection: keep-alive\r\n"
3916 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3917
3918 MockWrite("GET / HTTP/1.1\r\n"
3919 "Host: www.example.org\r\n"
3920 "Connection: keep-alive\r\n\r\n"),
3921 };
3922
3923 MockRead data_reads2[] = {
3924 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3925
3926 MockRead("HTTP/1.1 200 OK\r\n"),
3927 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3928 MockRead("Content-Length: 5\r\n\r\n"),
3929 MockRead(SYNCHRONOUS, "hello"),
3930 };
3931
Ryan Sleevib8d7ea02018-05-07 20:01:013932 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenkee71e15332015-10-07 16:39:543933 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:013934 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenkee71e15332015-10-07 16:39:543935 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3936 SSLSocketDataProvider ssl(ASYNC, OK);
3937 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3938
3939 TestCompletionCallback callback;
3940
tfarina42834112016-09-22 13:38:203941 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013942 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543943
bnc691fda62016-08-12 00:43:163944 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543945 ASSERT_TRUE(response);
3946 ASSERT_TRUE(response->headers);
3947 EXPECT_TRUE(response->headers->IsKeepAlive());
3948 EXPECT_EQ(407, response->headers->response_code());
3949 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3950
bnc691fda62016-08-12 00:43:163951 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
robpercival214763f2016-07-01 23:27:013952 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543953
bnc691fda62016-08-12 00:43:163954 response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543955 ASSERT_TRUE(response);
3956 ASSERT_TRUE(response->headers);
3957 EXPECT_TRUE(response->headers->IsKeepAlive());
3958 EXPECT_EQ(200, response->headers->response_code());
3959 std::string body;
bnc691fda62016-08-12 00:43:163960 EXPECT_THAT(ReadTransaction(&trans, &body), IsOk());
mmenkee71e15332015-10-07 16:39:543961 EXPECT_EQ("hello", body);
3962}
3963
[email protected]a8e9b162009-03-12 00:06:443964// Test that we don't read the response body when we fail to establish a tunnel,
3965// even if the user cancels the proxy's auth attempt.
bncd16676a2016-07-20 16:23:013966TEST_F(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:273967 HttpRequestInfo request;
3968 request.method = "GET";
bncce36dca22015-04-21 22:11:233969 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:103970 request.traffic_annotation =
3971 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:273972
[email protected]a8e9b162009-03-12 00:06:443973 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:493974 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
3975 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]a8e9b162009-03-12 00:06:443976
danakj1fd259a02016-04-16 03:17:093977 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:443978
bnc691fda62016-08-12 00:43:163979 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a8e9b162009-03-12 00:06:443980
[email protected]a8e9b162009-03-12 00:06:443981 // Since we have proxy, should try to establish tunnel.
3982 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173983 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3984 "Host: www.example.org:443\r\n"
3985 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:443986 };
3987
3988 // The proxy responds to the connect with a 407.
3989 MockRead data_reads[] = {
ttuttle7933c112015-01-06 00:55:243990 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3991 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3992 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233993 MockRead("0123456789"),
ttuttle7933c112015-01-06 00:55:243994 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]a8e9b162009-03-12 00:06:443995 };
3996
Ryan Sleevib8d7ea02018-05-07 20:01:013997 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:073998 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:443999
[email protected]49639fa2011-12-20 23:22:414000 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:444001
tfarina42834112016-09-22 13:38:204002 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014003 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a8e9b162009-03-12 00:06:444004
4005 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:014006 EXPECT_THAT(rv, IsOk());
[email protected]a8e9b162009-03-12 00:06:444007
bnc691fda62016-08-12 00:43:164008 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:244009 ASSERT_TRUE(response);
4010 ASSERT_TRUE(response->headers);
[email protected]a8e9b162009-03-12 00:06:444011 EXPECT_TRUE(response->headers->IsKeepAlive());
4012 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:424013 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:444014
4015 std::string response_data;
bnc691fda62016-08-12 00:43:164016 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:014017 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]e60e47a2010-07-14 03:37:184018
4019 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:314020 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:444021}
4022
ttuttle7933c112015-01-06 00:55:244023// Test that we don't pass extraneous headers from the proxy's response to the
4024// caller when the proxy responds to CONNECT with 407.
bncd16676a2016-07-20 16:23:014025TEST_F(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
ttuttle7933c112015-01-06 00:55:244026 HttpRequestInfo request;
4027 request.method = "GET";
bncce36dca22015-04-21 22:11:234028 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104029 request.traffic_annotation =
4030 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle7933c112015-01-06 00:55:244031
4032 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:494033 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
4034 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle7933c112015-01-06 00:55:244035
danakj1fd259a02016-04-16 03:17:094036 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle7933c112015-01-06 00:55:244037
bnc691fda62016-08-12 00:43:164038 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle7933c112015-01-06 00:55:244039
4040 // Since we have proxy, should try to establish tunnel.
4041 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:174042 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4043 "Host: www.example.org:443\r\n"
4044 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle7933c112015-01-06 00:55:244045 };
4046
4047 // The proxy responds to the connect with a 407.
4048 MockRead data_reads[] = {
4049 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4050 MockRead("X-Foo: bar\r\n"),
4051 MockRead("Set-Cookie: foo=bar\r\n"),
4052 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4053 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:234054 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
ttuttle7933c112015-01-06 00:55:244055 };
4056
Ryan Sleevib8d7ea02018-05-07 20:01:014057 StaticSocketDataProvider data(data_reads, data_writes);
ttuttle7933c112015-01-06 00:55:244058 session_deps_.socket_factory->AddSocketDataProvider(&data);
4059
4060 TestCompletionCallback callback;
4061
tfarina42834112016-09-22 13:38:204062 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014063 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle7933c112015-01-06 00:55:244064
4065 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:014066 EXPECT_THAT(rv, IsOk());
ttuttle7933c112015-01-06 00:55:244067
bnc691fda62016-08-12 00:43:164068 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:244069 ASSERT_TRUE(response);
4070 ASSERT_TRUE(response->headers);
4071 EXPECT_TRUE(response->headers->IsKeepAlive());
4072 EXPECT_EQ(407, response->headers->response_code());
4073 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4074 EXPECT_FALSE(response->headers->HasHeader("X-Foo"));
4075 EXPECT_FALSE(response->headers->HasHeader("Set-Cookie"));
4076
4077 std::string response_data;
bnc691fda62016-08-12 00:43:164078 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:014079 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
ttuttle7933c112015-01-06 00:55:244080
4081 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
4082 session->CloseAllConnections();
4083}
4084
[email protected]8fdbcd22010-05-05 02:54:524085// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
4086// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
bncd16676a2016-07-20 16:23:014087TEST_F(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:524088 HttpRequestInfo request;
4089 request.method = "GET";
bncce36dca22015-04-21 22:11:234090 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104091 request.traffic_annotation =
4092 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8fdbcd22010-05-05 02:54:524093
[email protected]cb9bf6ca2011-01-28 13:15:274094 // We are using a DIRECT connection (i.e. no proxy) for this session.
danakj1fd259a02016-04-16 03:17:094095 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:164096 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:274097
[email protected]8fdbcd22010-05-05 02:54:524098 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:234099 MockWrite(
4100 "GET / HTTP/1.1\r\n"
4101 "Host: www.example.org\r\n"
4102 "Connection: keep-alive\r\n\r\n"),
[email protected]8fdbcd22010-05-05 02:54:524103 };
4104
4105 MockRead data_reads1[] = {
4106 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
4107 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4108 // Large content-length -- won't matter, as connection will be reset.
4109 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064110 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:524111 };
4112
Ryan Sleevib8d7ea02018-05-07 20:01:014113 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:074114 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:524115
[email protected]49639fa2011-12-20 23:22:414116 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:524117
tfarina42834112016-09-22 13:38:204118 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014119 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8fdbcd22010-05-05 02:54:524120
4121 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:014122 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
[email protected]8fdbcd22010-05-05 02:54:524123}
4124
[email protected]7a67a8152010-11-05 18:31:104125// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
4126// through a non-authenticating proxy. The request should fail with
4127// ERR_UNEXPECTED_PROXY_AUTH.
4128// Note that it is impossible to detect if an HTTP server returns a 407 through
4129// a non-authenticating proxy - there is nothing to indicate whether the
4130// response came from the proxy or the server, so it is treated as if the proxy
4131// issued the challenge.
bncd16676a2016-07-20 16:23:014132TEST_F(HttpNetworkTransactionTest, HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:274133 HttpRequestInfo request;
4134 request.method = "GET";
bncce36dca22015-04-21 22:11:234135 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104136 request.traffic_annotation =
4137 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:274138
Ramin Halavatica8d5252018-03-12 05:33:494139 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
4140 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:514141 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074142 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094143 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:104144
[email protected]7a67a8152010-11-05 18:31:104145 // Since we have proxy, should try to establish tunnel.
4146 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174147 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4148 "Host: www.example.org:443\r\n"
4149 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:104150
rsleevidb16bb02015-11-12 23:47:174151 MockWrite("GET / HTTP/1.1\r\n"
4152 "Host: www.example.org\r\n"
4153 "Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:104154 };
4155
4156 MockRead data_reads1[] = {
4157 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4158
4159 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
4160 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4161 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:064162 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:104163 };
4164
Ryan Sleevib8d7ea02018-05-07 20:01:014165 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:074166 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:064167 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074168 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:104169
[email protected]49639fa2011-12-20 23:22:414170 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:104171
bnc691fda62016-08-12 00:43:164172 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]7a67a8152010-11-05 18:31:104173
bnc691fda62016-08-12 00:43:164174 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014175 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a67a8152010-11-05 18:31:104176
4177 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014178 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
mmenke43758e62015-05-04 21:09:464179 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:404180 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:104181 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:004182 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
4183 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:104184 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:404185 entries, pos,
mikecirone8b85c432016-09-08 19:11:004186 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
4187 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:104188}
[email protected]2df19bb2010-08-25 20:13:464189
mmenke2a1781d2015-10-07 19:25:334190// Test a proxy auth scheme that allows default credentials and a proxy server
4191// that uses non-persistent connections.
bncd16676a2016-07-20 16:23:014192TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334193 AuthAllowsDefaultCredentialsTunnelConnectionClose) {
4194 HttpRequestInfo request;
4195 request.method = "GET";
4196 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104197 request.traffic_annotation =
4198 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334199
4200 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594201 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494202 ProxyResolutionService::CreateFixedFromPacResult(
4203 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334204
Jeremy Roman0579ed62017-08-29 15:56:194205 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334206 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194207 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334208 mock_handler->set_allows_default_credentials(true);
4209 auth_handler_factory->AddMockHandler(mock_handler.release(),
4210 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484211 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334212
4213 // Add NetLog just so can verify load timing information gets a NetLog ID.
4214 NetLog net_log;
4215 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094216 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334217
4218 // Since we have proxy, should try to establish tunnel.
4219 MockWrite data_writes1[] = {
4220 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174221 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334222 "Proxy-Connection: keep-alive\r\n\r\n"),
4223 };
4224
4225 // The proxy responds to the connect with a 407, using a non-persistent
4226 // connection.
4227 MockRead data_reads1[] = {
4228 // No credentials.
4229 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4230 MockRead("Proxy-Authenticate: Mock\r\n"),
4231 MockRead("Proxy-Connection: close\r\n\r\n"),
4232 };
4233
4234 // Since the first connection couldn't be reused, need to establish another
4235 // once given credentials.
4236 MockWrite data_writes2[] = {
4237 // After calling trans->RestartWithAuth(), this is the request we should
4238 // be issuing -- the final header line contains the credentials.
4239 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174240 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334241 "Proxy-Connection: keep-alive\r\n"
4242 "Proxy-Authorization: auth_token\r\n\r\n"),
4243
4244 MockWrite("GET / HTTP/1.1\r\n"
4245 "Host: www.example.org\r\n"
4246 "Connection: keep-alive\r\n\r\n"),
4247 };
4248
4249 MockRead data_reads2[] = {
4250 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
4251
4252 MockRead("HTTP/1.1 200 OK\r\n"),
4253 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4254 MockRead("Content-Length: 5\r\n\r\n"),
4255 MockRead(SYNCHRONOUS, "hello"),
4256 };
4257
Ryan Sleevib8d7ea02018-05-07 20:01:014258 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke2a1781d2015-10-07 19:25:334259 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:014260 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke2a1781d2015-10-07 19:25:334261 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4262 SSLSocketDataProvider ssl(ASYNC, OK);
4263 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4264
bnc87dcefc2017-05-25 12:47:584265 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194266 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334267
4268 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204269 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014270 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334271
4272 const HttpResponseInfo* response = trans->GetResponseInfo();
4273 ASSERT_TRUE(response);
4274 ASSERT_TRUE(response->headers);
4275 EXPECT_FALSE(response->headers->IsKeepAlive());
4276 EXPECT_EQ(407, response->headers->response_code());
4277 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4278 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
wezca1070932016-05-26 20:30:524279 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:334280
4281 LoadTimingInfo load_timing_info;
4282 // CONNECT requests and responses are handled at the connect job level, so
4283 // the transaction does not yet have a connection.
4284 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4285
4286 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014287 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334288 response = trans->GetResponseInfo();
4289 ASSERT_TRUE(response);
4290 ASSERT_TRUE(response->headers);
4291 EXPECT_TRUE(response->headers->IsKeepAlive());
4292 EXPECT_EQ(200, response->headers->response_code());
4293 EXPECT_EQ(5, response->headers->GetContentLength());
4294 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4295
4296 // The password prompt info should not be set.
4297 EXPECT_FALSE(response->auth_challenge);
4298
4299 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4300 TestLoadTimingNotReusedWithPac(load_timing_info,
4301 CONNECT_TIMING_HAS_SSL_TIMES);
4302
4303 trans.reset();
4304 session->CloseAllConnections();
4305}
4306
4307// Test a proxy auth scheme that allows default credentials and a proxy server
4308// that hangs up when credentials are initially sent.
bncd16676a2016-07-20 16:23:014309TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334310 AuthAllowsDefaultCredentialsTunnelServerClosesConnection) {
4311 HttpRequestInfo request;
4312 request.method = "GET";
4313 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104314 request.traffic_annotation =
4315 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334316
4317 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594318 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494319 ProxyResolutionService::CreateFixedFromPacResult(
4320 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334321
Jeremy Roman0579ed62017-08-29 15:56:194322 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334323 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194324 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334325 mock_handler->set_allows_default_credentials(true);
4326 auth_handler_factory->AddMockHandler(mock_handler.release(),
4327 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484328 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334329
4330 // Add NetLog just so can verify load timing information gets a NetLog ID.
4331 NetLog net_log;
4332 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094333 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334334
4335 // Should try to establish tunnel.
4336 MockWrite data_writes1[] = {
4337 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174338 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334339 "Proxy-Connection: keep-alive\r\n\r\n"),
4340
4341 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174342 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334343 "Proxy-Connection: keep-alive\r\n"
4344 "Proxy-Authorization: auth_token\r\n\r\n"),
4345 };
4346
4347 // The proxy responds to the connect with a 407, using a non-persistent
4348 // connection.
4349 MockRead data_reads1[] = {
4350 // No credentials.
4351 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4352 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4353 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4354 };
4355
4356 // Since the first connection was closed, need to establish another once given
4357 // credentials.
4358 MockWrite data_writes2[] = {
4359 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174360 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334361 "Proxy-Connection: keep-alive\r\n"
4362 "Proxy-Authorization: auth_token\r\n\r\n"),
4363
4364 MockWrite("GET / HTTP/1.1\r\n"
4365 "Host: www.example.org\r\n"
4366 "Connection: keep-alive\r\n\r\n"),
4367 };
4368
4369 MockRead data_reads2[] = {
4370 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
4371
4372 MockRead("HTTP/1.1 200 OK\r\n"),
4373 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4374 MockRead("Content-Length: 5\r\n\r\n"),
4375 MockRead(SYNCHRONOUS, "hello"),
4376 };
4377
Ryan Sleevib8d7ea02018-05-07 20:01:014378 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke2a1781d2015-10-07 19:25:334379 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:014380 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke2a1781d2015-10-07 19:25:334381 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4382 SSLSocketDataProvider ssl(ASYNC, OK);
4383 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4384
bnc87dcefc2017-05-25 12:47:584385 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194386 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334387
4388 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204389 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014390 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334391
4392 const HttpResponseInfo* response = trans->GetResponseInfo();
4393 ASSERT_TRUE(response);
4394 ASSERT_TRUE(response->headers);
4395 EXPECT_TRUE(response->headers->IsKeepAlive());
4396 EXPECT_EQ(407, response->headers->response_code());
4397 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4398 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4399 EXPECT_FALSE(response->auth_challenge);
4400
4401 LoadTimingInfo load_timing_info;
4402 // CONNECT requests and responses are handled at the connect job level, so
4403 // the transaction does not yet have a connection.
4404 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4405
4406 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014407 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334408
4409 response = trans->GetResponseInfo();
4410 ASSERT_TRUE(response);
4411 ASSERT_TRUE(response->headers);
4412 EXPECT_TRUE(response->headers->IsKeepAlive());
4413 EXPECT_EQ(200, response->headers->response_code());
4414 EXPECT_EQ(5, response->headers->GetContentLength());
4415 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4416
4417 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524418 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:334419
4420 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4421 TestLoadTimingNotReusedWithPac(load_timing_info,
4422 CONNECT_TIMING_HAS_SSL_TIMES);
4423
4424 trans.reset();
4425 session->CloseAllConnections();
4426}
4427
4428// Test a proxy auth scheme that allows default credentials and a proxy server
4429// that hangs up when credentials are initially sent, and hangs up again when
4430// they are retried.
bncd16676a2016-07-20 16:23:014431TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334432 AuthAllowsDefaultCredentialsTunnelServerClosesConnectionTwice) {
4433 HttpRequestInfo request;
4434 request.method = "GET";
4435 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104436 request.traffic_annotation =
4437 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334438
4439 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594440 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494441 ProxyResolutionService::CreateFixedFromPacResult(
4442 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334443
Jeremy Roman0579ed62017-08-29 15:56:194444 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334445 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194446 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334447 mock_handler->set_allows_default_credentials(true);
4448 auth_handler_factory->AddMockHandler(mock_handler.release(),
4449 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484450 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334451
4452 // Add NetLog just so can verify load timing information gets a NetLog ID.
4453 NetLog net_log;
4454 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094455 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334456
4457 // Should try to establish tunnel.
4458 MockWrite data_writes1[] = {
4459 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174460 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334461 "Proxy-Connection: keep-alive\r\n\r\n"),
4462
4463 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174464 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334465 "Proxy-Connection: keep-alive\r\n"
4466 "Proxy-Authorization: auth_token\r\n\r\n"),
4467 };
4468
4469 // The proxy responds to the connect with a 407, and then hangs up after the
4470 // second request is sent.
4471 MockRead data_reads1[] = {
4472 // No credentials.
4473 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4474 MockRead("Content-Length: 0\r\n"),
4475 MockRead("Proxy-Connection: keep-alive\r\n"),
4476 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4477 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4478 };
4479
4480 // HttpNetworkTransaction sees a reused connection that was closed with
4481 // ERR_CONNECTION_CLOSED, realized it might have been a race, so retries the
4482 // request.
4483 MockWrite data_writes2[] = {
4484 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174485 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334486 "Proxy-Connection: keep-alive\r\n\r\n"),
4487 };
4488
4489 // The proxy, having had more than enough of us, just hangs up.
4490 MockRead data_reads2[] = {
4491 // No credentials.
4492 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4493 };
4494
Ryan Sleevib8d7ea02018-05-07 20:01:014495 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke2a1781d2015-10-07 19:25:334496 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:014497 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke2a1781d2015-10-07 19:25:334498 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4499
bnc87dcefc2017-05-25 12:47:584500 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194501 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334502
4503 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204504 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014505 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334506
4507 const HttpResponseInfo* response = trans->GetResponseInfo();
4508 ASSERT_TRUE(response);
4509 ASSERT_TRUE(response->headers);
4510 EXPECT_TRUE(response->headers->IsKeepAlive());
4511 EXPECT_EQ(407, response->headers->response_code());
4512 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4513 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4514 EXPECT_FALSE(response->auth_challenge);
4515
4516 LoadTimingInfo load_timing_info;
4517 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4518
4519 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014520 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_EMPTY_RESPONSE));
mmenke2a1781d2015-10-07 19:25:334521
4522 trans.reset();
4523 session->CloseAllConnections();
4524}
4525
Asanka Herathbc3f8f62018-11-16 23:08:304526// This test exercises an odd edge case where the proxy closes the connection
4527// after the authentication handshake is complete. Presumably this technique is
4528// used in lieu of returning a 403 or 5xx status code when the authentication
4529// succeeds, but the user is not authorized to connect to the destination
4530// server. There's no standard for what a proxy should do to indicate a blocked
4531// site.
4532TEST_F(HttpNetworkTransactionTest,
4533 AuthAllowsDefaultCredentialsTunnelConnectionClosesBeforeBody) {
4534 HttpRequestInfo request;
4535 request.method = "GET";
4536 request.url = GURL("https://www.example.org/");
4537 request.traffic_annotation =
4538 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4539
4540 // Configure against proxy server "myproxy:70".
4541 session_deps_.proxy_resolution_service =
4542 ProxyResolutionService::CreateFixedFromPacResult(
4543 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
4544
Steven Valdez0ef94d02018-11-19 23:28:134545 // When TLS 1.3 is enabled, spurious connections are made as part of the SSL
4546 // version interference probes.
4547 // TODO(crbug.com/906668): Correctly handle version interference probes to
4548 // test TLS 1.3.
4549 SSLConfig config;
4550 config.version_max = SSL_PROTOCOL_VERSION_TLS1_2;
4551 session_deps_.ssl_config_service =
4552 std::make_unique<TestSSLConfigService>(config);
4553
Asanka Herathbc3f8f62018-11-16 23:08:304554 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
4555 auth_handler_factory->set_do_init_from_challenge(true);
4556
4557 // Create two mock AuthHandlers. This is because the transaction gets retried
4558 // after the first ERR_CONNECTION_CLOSED since it's ambiguous whether there
4559 // was a real network error.
4560 //
4561 // The handlers support both default and explicit credentials. The retry
4562 // mentioned above should be able to reuse the default identity. Thus there
4563 // should never be a need to prompt for explicit credentials.
4564 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
4565 mock_handler->set_allows_default_credentials(true);
4566 mock_handler->set_allows_explicit_credentials(true);
4567 mock_handler->set_connection_based(true);
4568 auth_handler_factory->AddMockHandler(mock_handler.release(),
4569 HttpAuth::AUTH_PROXY);
4570 mock_handler = std::make_unique<HttpAuthHandlerMock>();
4571 mock_handler->set_allows_default_credentials(true);
4572 mock_handler->set_allows_explicit_credentials(true);
4573 mock_handler->set_connection_based(true);
4574 auth_handler_factory->AddMockHandler(mock_handler.release(),
4575 HttpAuth::AUTH_PROXY);
4576 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
4577
4578 NetLog net_log;
4579 session_deps_.net_log = &net_log;
4580 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4581
4582 // Data for both sockets.
4583 //
4584 // Writes are for the tunnel establishment attempts and the
4585 // authentication handshake.
4586 MockWrite data_writes1[] = {
4587 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4588 "Host: www.example.org:443\r\n"
4589 "Proxy-Connection: keep-alive\r\n\r\n"),
4590
4591 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4592 "Host: www.example.org:443\r\n"
4593 "Proxy-Connection: keep-alive\r\n"
4594 "Proxy-Authorization: auth_token\r\n\r\n"),
4595
4596 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4597 "Host: www.example.org:443\r\n"
4598 "Proxy-Connection: keep-alive\r\n"
4599 "Proxy-Authorization: auth_token\r\n\r\n"),
4600 };
4601
4602 // The server side of the authentication handshake. Note that the response to
4603 // the final CONNECT request is ERR_CONNECTION_CLOSED.
4604 MockRead data_reads1[] = {
4605 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4606 MockRead("Content-Length: 0\r\n"),
4607 MockRead("Proxy-Connection: keep-alive\r\n"),
4608 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4609
4610 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4611 MockRead("Content-Length: 0\r\n"),
4612 MockRead("Proxy-Connection: keep-alive\r\n"),
4613 MockRead("Proxy-Authenticate: Mock foo\r\n\r\n"),
4614
4615 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4616 };
4617
4618 StaticSocketDataProvider data1(data_reads1, data_writes1);
4619 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4620
4621 // The second socket is for the reconnection attempt. Data is identical to the
4622 // first attempt.
4623 StaticSocketDataProvider data2(data_reads1, data_writes1);
4624 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4625
4626 auto trans =
4627 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
4628
4629 TestCompletionCallback callback;
4630 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4631
4632 // Two rounds per handshake. After one retry, the error is propagated up the
4633 // stack.
4634 for (int i = 0; i < 4; ++i) {
4635 EXPECT_THAT(callback.GetResult(rv), IsOk());
4636
4637 const HttpResponseInfo* response = trans->GetResponseInfo();
4638 ASSERT_TRUE(response);
4639 ASSERT_TRUE(response->headers);
4640 EXPECT_EQ(407, response->headers->response_code());
4641 ASSERT_TRUE(trans->IsReadyToRestartForAuth());
4642
4643 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4644 }
4645
4646 // One shall be the number thou shalt retry, and the number of the retrying
4647 // shall be one. Two shalt thou not retry, neither retry thou zero, excepting
4648 // that thou then proceed to one. Three is right out. Once the number one,
4649 // being the first number, be reached, then lobbest thou thy
4650 // ERR_CONNECTION_CLOSED towards they network transaction, who shall snuff it.
4651 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.GetResult(rv));
4652
4653 trans.reset();
4654 session->CloseAllConnections();
4655}
4656
mmenke2a1781d2015-10-07 19:25:334657// Test a proxy auth scheme that allows default credentials and a proxy server
4658// that hangs up when credentials are initially sent, and sends a challenge
4659// again they are retried.
bncd16676a2016-07-20 16:23:014660TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334661 AuthAllowsDefaultCredentialsTunnelServerChallengesTwice) {
4662 HttpRequestInfo request;
4663 request.method = "GET";
4664 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104665 request.traffic_annotation =
4666 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334667
4668 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594669 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494670 ProxyResolutionService::CreateFixedFromPacResult(
4671 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334672
Jeremy Roman0579ed62017-08-29 15:56:194673 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334674 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194675 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334676 mock_handler->set_allows_default_credentials(true);
4677 auth_handler_factory->AddMockHandler(mock_handler.release(),
4678 HttpAuth::AUTH_PROXY);
4679 // Add another handler for the second challenge. It supports default
4680 // credentials, but they shouldn't be used, since they were already tried.
Jeremy Roman0579ed62017-08-29 15:56:194681 mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334682 mock_handler->set_allows_default_credentials(true);
4683 auth_handler_factory->AddMockHandler(mock_handler.release(),
4684 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484685 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334686
4687 // Add NetLog just so can verify load timing information gets a NetLog ID.
4688 NetLog net_log;
4689 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094690 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334691
4692 // Should try to establish tunnel.
4693 MockWrite data_writes1[] = {
4694 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174695 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334696 "Proxy-Connection: keep-alive\r\n\r\n"),
4697 };
4698
4699 // The proxy responds to the connect with a 407, using a non-persistent
4700 // connection.
4701 MockRead data_reads1[] = {
4702 // No credentials.
4703 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4704 MockRead("Proxy-Authenticate: Mock\r\n"),
4705 MockRead("Proxy-Connection: close\r\n\r\n"),
4706 };
4707
4708 // Since the first connection was closed, need to establish another once given
4709 // credentials.
4710 MockWrite data_writes2[] = {
4711 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174712 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334713 "Proxy-Connection: keep-alive\r\n"
4714 "Proxy-Authorization: auth_token\r\n\r\n"),
4715 };
4716
4717 MockRead data_reads2[] = {
4718 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4719 MockRead("Proxy-Authenticate: Mock\r\n"),
4720 MockRead("Proxy-Connection: close\r\n\r\n"),
4721 };
4722
Ryan Sleevib8d7ea02018-05-07 20:01:014723 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke2a1781d2015-10-07 19:25:334724 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:014725 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke2a1781d2015-10-07 19:25:334726 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4727 SSLSocketDataProvider ssl(ASYNC, OK);
4728 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4729
bnc87dcefc2017-05-25 12:47:584730 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194731 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334732
4733 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204734 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014735 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334736
4737 const HttpResponseInfo* response = trans->GetResponseInfo();
4738 ASSERT_TRUE(response);
4739 ASSERT_TRUE(response->headers);
4740 EXPECT_EQ(407, response->headers->response_code());
4741 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4742 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4743 EXPECT_FALSE(response->auth_challenge);
4744
4745 LoadTimingInfo load_timing_info;
4746 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4747
4748 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014749 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334750 response = trans->GetResponseInfo();
4751 ASSERT_TRUE(response);
4752 ASSERT_TRUE(response->headers);
4753 EXPECT_EQ(407, response->headers->response_code());
4754 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4755 EXPECT_TRUE(response->auth_challenge);
4756
4757 trans.reset();
4758 session->CloseAllConnections();
4759}
4760
asankae2257db2016-10-11 22:03:164761// A more nuanced test than GenerateAuthToken test which asserts that
4762// ERR_INVALID_AUTH_CREDENTIALS does not cause the auth scheme to be
4763// unnecessarily invalidated, and that if the server co-operates, the
4764// authentication handshake can continue with the same scheme but with a
4765// different identity.
4766TEST_F(HttpNetworkTransactionTest, NonPermanentGenerateAuthTokenError) {
4767 HttpRequestInfo request;
4768 request.method = "GET";
4769 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104770 request.traffic_annotation =
4771 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
asankae2257db2016-10-11 22:03:164772
Jeremy Roman0579ed62017-08-29 15:56:194773 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
asankae2257db2016-10-11 22:03:164774 auth_handler_factory->set_do_init_from_challenge(true);
4775
4776 // First handler. Uses default credentials, but barfs at generate auth token.
Jeremy Roman0579ed62017-08-29 15:56:194777 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164778 mock_handler->set_allows_default_credentials(true);
4779 mock_handler->set_allows_explicit_credentials(true);
4780 mock_handler->set_connection_based(true);
4781 mock_handler->SetGenerateExpectation(true, ERR_INVALID_AUTH_CREDENTIALS);
4782 auth_handler_factory->AddMockHandler(mock_handler.release(),
4783 HttpAuth::AUTH_SERVER);
4784
4785 // Add another handler for the second challenge. It supports default
4786 // credentials, but they shouldn't be used, since they were already tried.
Jeremy Roman0579ed62017-08-29 15:56:194787 mock_handler = std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164788 mock_handler->set_allows_default_credentials(true);
4789 mock_handler->set_allows_explicit_credentials(true);
4790 mock_handler->set_connection_based(true);
4791 auth_handler_factory->AddMockHandler(mock_handler.release(),
4792 HttpAuth::AUTH_SERVER);
4793 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
4794
4795 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4796
4797 MockWrite data_writes1[] = {
4798 MockWrite("GET / HTTP/1.1\r\n"
4799 "Host: www.example.org\r\n"
4800 "Connection: keep-alive\r\n\r\n"),
4801 };
4802
4803 MockRead data_reads1[] = {
4804 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4805 "WWW-Authenticate: Mock\r\n"
4806 "Connection: keep-alive\r\n\r\n"),
4807 };
4808
4809 // Identical to data_writes1[]. The AuthHandler encounters a
4810 // ERR_INVALID_AUTH_CREDENTIALS during the GenerateAuthToken stage, so the
4811 // transaction procceds without an authorization header.
4812 MockWrite data_writes2[] = {
4813 MockWrite("GET / HTTP/1.1\r\n"
4814 "Host: www.example.org\r\n"
4815 "Connection: keep-alive\r\n\r\n"),
4816 };
4817
4818 MockRead data_reads2[] = {
4819 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4820 "WWW-Authenticate: Mock\r\n"
4821 "Connection: keep-alive\r\n\r\n"),
4822 };
4823
4824 MockWrite data_writes3[] = {
4825 MockWrite("GET / HTTP/1.1\r\n"
4826 "Host: www.example.org\r\n"
4827 "Connection: keep-alive\r\n"
4828 "Authorization: auth_token\r\n\r\n"),
4829 };
4830
4831 MockRead data_reads3[] = {
4832 MockRead("HTTP/1.1 200 OK\r\n"
4833 "Content-Length: 5\r\n"
4834 "Content-Type: text/plain\r\n"
4835 "Connection: keep-alive\r\n\r\n"
4836 "Hello"),
4837 };
4838
Ryan Sleevib8d7ea02018-05-07 20:01:014839 StaticSocketDataProvider data1(data_reads1, data_writes1);
asankae2257db2016-10-11 22:03:164840 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4841
Ryan Sleevib8d7ea02018-05-07 20:01:014842 StaticSocketDataProvider data2(data_reads2, data_writes2);
asankae2257db2016-10-11 22:03:164843 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4844
Ryan Sleevib8d7ea02018-05-07 20:01:014845 StaticSocketDataProvider data3(data_reads3, data_writes3);
asankae2257db2016-10-11 22:03:164846 session_deps_.socket_factory->AddSocketDataProvider(&data3);
4847
bnc87dcefc2017-05-25 12:47:584848 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194849 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
asankae2257db2016-10-11 22:03:164850
4851 TestCompletionCallback callback;
4852 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4853 EXPECT_THAT(callback.GetResult(rv), IsOk());
4854
4855 const HttpResponseInfo* response = trans->GetResponseInfo();
4856 ASSERT_TRUE(response);
4857 ASSERT_TRUE(response->headers);
4858 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4859
4860 // The following three tests assert that an authentication challenge was
4861 // received and that the stack is ready to respond to the challenge using
4862 // ambient credentials.
4863 EXPECT_EQ(401, response->headers->response_code());
4864 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4865 EXPECT_FALSE(response->auth_challenge);
4866
4867 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4868 EXPECT_THAT(callback.GetResult(rv), IsOk());
4869 response = trans->GetResponseInfo();
4870 ASSERT_TRUE(response);
4871 ASSERT_TRUE(response->headers);
4872
4873 // The following three tests assert that an authentication challenge was
4874 // received and that the stack needs explicit credentials before it is ready
4875 // to respond to the challenge.
4876 EXPECT_EQ(401, response->headers->response_code());
4877 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4878 EXPECT_TRUE(response->auth_challenge);
4879
4880 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4881 EXPECT_THAT(callback.GetResult(rv), IsOk());
4882 response = trans->GetResponseInfo();
4883 ASSERT_TRUE(response);
4884 ASSERT_TRUE(response->headers);
4885 EXPECT_EQ(200, response->headers->response_code());
4886
4887 trans.reset();
4888 session->CloseAllConnections();
4889}
4890
Matt Menked1eb6d42018-01-17 04:54:064891// Proxy resolver that returns a proxy with the same host and port for different
4892// schemes, based on the path of the URL being requests.
4893class SameProxyWithDifferentSchemesProxyResolver : public ProxyResolver {
4894 public:
4895 SameProxyWithDifferentSchemesProxyResolver() {}
4896 ~SameProxyWithDifferentSchemesProxyResolver() override {}
4897
4898 static std::string ProxyHostPortPairAsString() { return "proxy.test:10000"; }
4899
4900 static HostPortPair ProxyHostPortPair() {
4901 return HostPortPair::FromString(ProxyHostPortPairAsString());
4902 }
4903
4904 // ProxyResolver implementation.
4905 int GetProxyForURL(const GURL& url,
4906 ProxyInfo* results,
Bence Békycc5b88a2018-05-25 20:24:174907 CompletionOnceCallback callback,
Matt Menked1eb6d42018-01-17 04:54:064908 std::unique_ptr<Request>* request,
4909 const NetLogWithSource& /*net_log*/) override {
4910 *results = ProxyInfo();
Ramin Halavati921731ea2018-03-16 08:24:574911 results->set_traffic_annotation(
4912 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
Matt Menked1eb6d42018-01-17 04:54:064913 if (url.path() == "/socks4") {
4914 results->UsePacString("SOCKS " + ProxyHostPortPairAsString());
4915 return OK;
4916 }
4917 if (url.path() == "/socks5") {
4918 results->UsePacString("SOCKS5 " + ProxyHostPortPairAsString());
4919 return OK;
4920 }
4921 if (url.path() == "/http") {
4922 results->UsePacString("PROXY " + ProxyHostPortPairAsString());
4923 return OK;
4924 }
4925 if (url.path() == "/https") {
4926 results->UsePacString("HTTPS " + ProxyHostPortPairAsString());
4927 return OK;
4928 }
Matt Menkee8648fa2019-01-17 16:47:074929 if (url.path() == "/https_trusted") {
4930 results->UseProxyServer(ProxyServer(ProxyServer::SCHEME_HTTPS,
4931 ProxyHostPortPair(),
4932 true /* is_trusted_proxy */));
4933 return OK;
4934 }
Matt Menked1eb6d42018-01-17 04:54:064935 NOTREACHED();
4936 return ERR_NOT_IMPLEMENTED;
4937 }
4938
4939 private:
4940 DISALLOW_COPY_AND_ASSIGN(SameProxyWithDifferentSchemesProxyResolver);
4941};
4942
4943class SameProxyWithDifferentSchemesProxyResolverFactory
4944 : public ProxyResolverFactory {
4945 public:
4946 SameProxyWithDifferentSchemesProxyResolverFactory()
4947 : ProxyResolverFactory(false) {}
4948
Lily Houghton99597862018-03-07 16:40:424949 int CreateProxyResolver(const scoped_refptr<PacFileData>& pac_script,
4950 std::unique_ptr<ProxyResolver>* resolver,
Bence Békycc5b88a2018-05-25 20:24:174951 CompletionOnceCallback callback,
Lily Houghton99597862018-03-07 16:40:424952 std::unique_ptr<Request>* request) override {
Matt Menked1eb6d42018-01-17 04:54:064953 *resolver = std::make_unique<SameProxyWithDifferentSchemesProxyResolver>();
4954 return OK;
4955 }
4956
4957 private:
4958 DISALLOW_COPY_AND_ASSIGN(SameProxyWithDifferentSchemesProxyResolverFactory);
4959};
4960
4961// Check that when different proxy schemes are all applied to a proxy at the
Matt Menkee8648fa2019-01-17 16:47:074962// same address, the connections are not grouped together. i.e., a request to
Matt Menked1eb6d42018-01-17 04:54:064963// foo.com using proxy.com as an HTTPS proxy won't use the same socket as a
4964// request to foo.com using proxy.com as an HTTP proxy.
4965TEST_F(HttpNetworkTransactionTest, SameDestinationForDifferentProxyTypes) {
Ramin Halavatica8d5252018-03-12 05:33:494966 session_deps_.proxy_resolution_service =
4967 std::make_unique<ProxyResolutionService>(
4968 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
4969 ProxyConfig::CreateAutoDetect(), TRAFFIC_ANNOTATION_FOR_TESTS)),
4970 std::make_unique<SameProxyWithDifferentSchemesProxyResolverFactory>(),
4971 nullptr);
Matt Menked1eb6d42018-01-17 04:54:064972
4973 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4974
4975 MockWrite socks_writes[] = {
4976 MockWrite(SYNCHRONOUS, kSOCKS4OkRequestLocalHostPort80,
4977 kSOCKS4OkRequestLocalHostPort80Length),
4978 MockWrite(SYNCHRONOUS,
4979 "GET /socks4 HTTP/1.1\r\n"
4980 "Host: test\r\n"
4981 "Connection: keep-alive\r\n\r\n"),
4982 };
4983 MockRead socks_reads[] = {
4984 MockRead(SYNCHRONOUS, kSOCKS4OkReply, kSOCKS4OkReplyLength),
4985 MockRead("HTTP/1.0 200 OK\r\n"
4986 "Connection: keep-alive\r\n"
4987 "Content-Length: 15\r\n\r\n"
4988 "SOCKS4 Response"),
4989 };
Ryan Sleevib8d7ea02018-05-07 20:01:014990 StaticSocketDataProvider socks_data(socks_reads, socks_writes);
Matt Menked1eb6d42018-01-17 04:54:064991 session_deps_.socket_factory->AddSocketDataProvider(&socks_data);
4992
4993 const char kSOCKS5Request[] = {
4994 0x05, // Version
4995 0x01, // Command (CONNECT)
4996 0x00, // Reserved
4997 0x03, // Address type (DOMAINNAME)
4998 0x04, // Length of domain (4)
4999 't', 'e', 's', 't', // Domain string
5000 0x00, 0x50, // 16-bit port (80)
5001 };
5002 MockWrite socks5_writes[] = {
5003 MockWrite(ASYNC, kSOCKS5GreetRequest, kSOCKS5GreetRequestLength),
Avi Drissman4365a4782018-12-28 19:26:245004 MockWrite(ASYNC, kSOCKS5Request, base::size(kSOCKS5Request)),
Matt Menked1eb6d42018-01-17 04:54:065005 MockWrite(SYNCHRONOUS,
5006 "GET /socks5 HTTP/1.1\r\n"
5007 "Host: test\r\n"
5008 "Connection: keep-alive\r\n\r\n"),
5009 };
5010 MockRead socks5_reads[] = {
5011 MockRead(ASYNC, kSOCKS5GreetResponse, kSOCKS5GreetResponseLength),
5012 MockRead(ASYNC, kSOCKS5OkResponse, kSOCKS5OkResponseLength),
5013 MockRead("HTTP/1.0 200 OK\r\n"
5014 "Connection: keep-alive\r\n"
5015 "Content-Length: 15\r\n\r\n"
5016 "SOCKS5 Response"),
5017 };
Ryan Sleevib8d7ea02018-05-07 20:01:015018 StaticSocketDataProvider socks5_data(socks5_reads, socks5_writes);
Matt Menked1eb6d42018-01-17 04:54:065019 session_deps_.socket_factory->AddSocketDataProvider(&socks5_data);
5020
5021 MockWrite http_writes[] = {
5022 MockWrite(SYNCHRONOUS,
5023 "GET http://test/http HTTP/1.1\r\n"
5024 "Host: test\r\n"
5025 "Proxy-Connection: keep-alive\r\n\r\n"),
5026 };
5027 MockRead http_reads[] = {
5028 MockRead("HTTP/1.1 200 OK\r\n"
5029 "Proxy-Connection: keep-alive\r\n"
5030 "Content-Length: 13\r\n\r\n"
5031 "HTTP Response"),
5032 };
Ryan Sleevib8d7ea02018-05-07 20:01:015033 StaticSocketDataProvider http_data(http_reads, http_writes);
Matt Menked1eb6d42018-01-17 04:54:065034 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
5035
5036 MockWrite https_writes[] = {
5037 MockWrite(SYNCHRONOUS,
5038 "GET http://test/https HTTP/1.1\r\n"
5039 "Host: test\r\n"
5040 "Proxy-Connection: keep-alive\r\n\r\n"),
5041 };
5042 MockRead https_reads[] = {
5043 MockRead("HTTP/1.1 200 OK\r\n"
5044 "Proxy-Connection: keep-alive\r\n"
5045 "Content-Length: 14\r\n\r\n"
5046 "HTTPS Response"),
5047 };
Ryan Sleevib8d7ea02018-05-07 20:01:015048 StaticSocketDataProvider https_data(https_reads, https_writes);
Matt Menked1eb6d42018-01-17 04:54:065049 session_deps_.socket_factory->AddSocketDataProvider(&https_data);
5050 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
5051 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5052
Matt Menkee8648fa2019-01-17 16:47:075053 MockWrite https_trusted_writes[] = {
5054 MockWrite(SYNCHRONOUS,
5055 "GET http://test/https_trusted HTTP/1.1\r\n"
5056 "Host: test\r\n"
5057 "Proxy-Connection: keep-alive\r\n\r\n"),
5058 };
5059 MockRead https_trusted_reads[] = {
5060 MockRead("HTTP/1.1 200 OK\r\n"
5061 "Proxy-Connection: keep-alive\r\n"
5062 "Content-Length: 22\r\n\r\n"
5063 "HTTPS Trusted Response"),
5064 };
5065 StaticSocketDataProvider trusted_https_data(https_trusted_reads,
5066 https_trusted_writes);
5067 session_deps_.socket_factory->AddSocketDataProvider(&trusted_https_data);
5068 SSLSocketDataProvider ssl2(SYNCHRONOUS, OK);
5069 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
5070
Matt Menked1eb6d42018-01-17 04:54:065071 struct TestCase {
5072 GURL url;
5073 std::string expected_response;
Matt Menkee8648fa2019-01-17 16:47:075074 // How many idle sockets there should be in the SOCKS 4/5 proxy socket pools
Matt Menked1eb6d42018-01-17 04:54:065075 // after the test.
Matt Menkee8648fa2019-01-17 16:47:075076 int expected_idle_socks4_sockets;
5077 int expected_idle_socks5_sockets;
5078 // How many idle sockets there should be in the HTTP/HTTPS proxy socket
5079 // pools after the test.
Matt Menked1eb6d42018-01-17 04:54:065080 int expected_idle_http_sockets;
Matt Menkee8648fa2019-01-17 16:47:075081 int expected_idle_https_sockets;
5082 // How many idle sockets there should be in the HTTPS proxy socket pool with
5083 // the ProxyServer's |is_trusted_proxy| bit set after the test.
5084 int expected_idle_trusted_https_sockets;
Matt Menked1eb6d42018-01-17 04:54:065085 } const kTestCases[] = {
Matt Menkee8648fa2019-01-17 16:47:075086 {GURL("http://test/socks4"), "SOCKS4 Response", 1, 0, 0, 0, 0},
5087 {GURL("http://test/socks5"), "SOCKS5 Response", 1, 1, 0, 0, 0},
5088 {GURL("http://test/http"), "HTTP Response", 1, 1, 1, 0, 0},
5089 {GURL("http://test/https"), "HTTPS Response", 1, 1, 1, 1, 0},
5090 {GURL("http://test/https_trusted"), "HTTPS Trusted Response", 1, 1, 1, 1,
5091 1},
Matt Menked1eb6d42018-01-17 04:54:065092 };
5093
5094 for (const auto& test_case : kTestCases) {
5095 HttpRequestInfo request;
5096 request.method = "GET";
5097 request.url = test_case.url;
Ramin Halavatib5e433e2018-02-07 07:41:105098 request.traffic_annotation =
5099 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Matt Menked1eb6d42018-01-17 04:54:065100 std::unique_ptr<HttpNetworkTransaction> trans =
5101 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
5102 session.get());
5103 TestCompletionCallback callback;
5104 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
5105 EXPECT_THAT(callback.GetResult(rv), IsOk());
5106
5107 const HttpResponseInfo* response = trans->GetResponseInfo();
5108 ASSERT_TRUE(response);
5109 ASSERT_TRUE(response->headers);
5110 EXPECT_EQ(200, response->headers->response_code());
5111 std::string response_data;
5112 EXPECT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
5113 EXPECT_EQ(test_case.expected_response, response_data);
5114
5115 // Return the socket to the socket pool, so can make sure it's not used for
5116 // the next requests.
5117 trans.reset();
5118 base::RunLoop().RunUntilIdle();
5119
5120 // Check the number of idle sockets in the pool, to make sure that used
5121 // sockets are indeed being returned to the socket pool. If each request
5122 // doesn't return an idle socket to the pool, the test would incorrectly
5123 // pass.
Matt Menkee8648fa2019-01-17 16:47:075124 EXPECT_EQ(test_case.expected_idle_socks4_sockets,
5125 session
5126 ->GetSocketPoolForSOCKSProxy(
5127 HttpNetworkSession::NORMAL_SOCKET_POOL,
5128 ProxyServer(ProxyServer::SCHEME_SOCKS4,
5129 SameProxyWithDifferentSchemesProxyResolver::
5130 ProxyHostPortPair()))
5131 ->IdleSocketCount());
5132 EXPECT_EQ(test_case.expected_idle_socks5_sockets,
5133 session
5134 ->GetSocketPoolForSOCKSProxy(
5135 HttpNetworkSession::NORMAL_SOCKET_POOL,
5136 ProxyServer(ProxyServer::SCHEME_SOCKS5,
5137 SameProxyWithDifferentSchemesProxyResolver::
5138 ProxyHostPortPair()))
5139 ->IdleSocketCount());
5140 EXPECT_EQ(test_case.expected_idle_http_sockets,
5141 session
5142 ->GetSocketPoolForHTTPLikeProxy(
5143 HttpNetworkSession::NORMAL_SOCKET_POOL,
5144 ProxyServer(ProxyServer::SCHEME_HTTP,
5145 SameProxyWithDifferentSchemesProxyResolver::
5146 ProxyHostPortPair()))
5147 ->IdleSocketCount());
5148 EXPECT_EQ(test_case.expected_idle_https_sockets,
5149 session
5150 ->GetSocketPoolForHTTPLikeProxy(
5151 HttpNetworkSession::NORMAL_SOCKET_POOL,
5152 ProxyServer(ProxyServer::SCHEME_HTTPS,
5153 SameProxyWithDifferentSchemesProxyResolver::
5154 ProxyHostPortPair()))
5155 ->IdleSocketCount());
5156 EXPECT_EQ(test_case.expected_idle_trusted_https_sockets,
5157 session
5158 ->GetSocketPoolForHTTPLikeProxy(
5159 HttpNetworkSession::NORMAL_SOCKET_POOL,
5160 ProxyServer(ProxyServer::SCHEME_HTTPS,
5161 SameProxyWithDifferentSchemesProxyResolver::
5162 ProxyHostPortPair(),
5163 true /* is_trusted_proxy */))
5164 ->IdleSocketCount());
Matt Menked1eb6d42018-01-17 04:54:065165 }
5166}
5167
[email protected]029c83b62013-01-24 05:28:205168// Test the load timing for HTTPS requests with an HTTP proxy.
bncd16676a2016-07-20 16:23:015169TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:205170 HttpRequestInfo request1;
5171 request1.method = "GET";
bncce36dca22015-04-21 22:11:235172 request1.url = GURL("https://www.example.org/1");
Ramin Halavatib5e433e2018-02-07 07:41:105173 request1.traffic_annotation =
5174 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:205175
5176 HttpRequestInfo request2;
5177 request2.method = "GET";
bncce36dca22015-04-21 22:11:235178 request2.url = GURL("https://www.example.org/2");
Ramin Halavatib5e433e2018-02-07 07:41:105179 request2.traffic_annotation =
5180 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:205181
5182 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495183 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5184 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515185 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075186 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095187 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:205188
5189 // Since we have proxy, should try to establish tunnel.
5190 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:175191 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5192 "Host: www.example.org:443\r\n"
5193 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205194
rsleevidb16bb02015-11-12 23:47:175195 MockWrite("GET /1 HTTP/1.1\r\n"
5196 "Host: www.example.org\r\n"
5197 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205198
rsleevidb16bb02015-11-12 23:47:175199 MockWrite("GET /2 HTTP/1.1\r\n"
5200 "Host: www.example.org\r\n"
5201 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205202 };
5203
5204 // The proxy responds to the connect with a 407, using a persistent
5205 // connection.
5206 MockRead data_reads1[] = {
5207 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
5208
5209 MockRead("HTTP/1.1 200 OK\r\n"),
5210 MockRead("Content-Length: 1\r\n\r\n"),
5211 MockRead(SYNCHRONOUS, "1"),
5212
5213 MockRead("HTTP/1.1 200 OK\r\n"),
5214 MockRead("Content-Length: 2\r\n\r\n"),
5215 MockRead(SYNCHRONOUS, "22"),
5216 };
5217
Ryan Sleevib8d7ea02018-05-07 20:01:015218 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:075219 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:205220 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075221 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:205222
5223 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:585224 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:195225 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:205226
5227 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015228 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:205229
5230 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015231 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:205232
5233 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:525234 ASSERT_TRUE(response1);
tbansal2ecbbc72016-10-06 17:15:475235 EXPECT_TRUE(response1->proxy_server.is_http());
wezca1070932016-05-26 20:30:525236 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:205237 EXPECT_EQ(1, response1->headers->GetContentLength());
5238
5239 LoadTimingInfo load_timing_info1;
5240 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
5241 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
5242
5243 trans1.reset();
5244
5245 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:585246 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:195247 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:205248
5249 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015250 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:205251
5252 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015253 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:205254
5255 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:525256 ASSERT_TRUE(response2);
tbansal2ecbbc72016-10-06 17:15:475257 EXPECT_TRUE(response2->proxy_server.is_http());
wezca1070932016-05-26 20:30:525258 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:205259 EXPECT_EQ(2, response2->headers->GetContentLength());
5260
5261 LoadTimingInfo load_timing_info2;
5262 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5263 TestLoadTimingReused(load_timing_info2);
5264
5265 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
5266
5267 trans2.reset();
5268 session->CloseAllConnections();
5269}
5270
5271// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
bncd16676a2016-07-20 16:23:015272TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:205273 HttpRequestInfo request1;
5274 request1.method = "GET";
bncce36dca22015-04-21 22:11:235275 request1.url = GURL("https://www.example.org/1");
Ramin Halavatib5e433e2018-02-07 07:41:105276 request1.traffic_annotation =
5277 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:205278
5279 HttpRequestInfo request2;
5280 request2.method = "GET";
bncce36dca22015-04-21 22:11:235281 request2.url = GURL("https://www.example.org/2");
Ramin Halavatib5e433e2018-02-07 07:41:105282 request2.traffic_annotation =
5283 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:205284
5285 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595286 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:495287 ProxyResolutionService::CreateFixedFromPacResult(
5288 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515289 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075290 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095291 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:205292
5293 // Since we have proxy, should try to establish tunnel.
5294 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:175295 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5296 "Host: www.example.org:443\r\n"
5297 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205298
rsleevidb16bb02015-11-12 23:47:175299 MockWrite("GET /1 HTTP/1.1\r\n"
5300 "Host: www.example.org\r\n"
5301 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205302
rsleevidb16bb02015-11-12 23:47:175303 MockWrite("GET /2 HTTP/1.1\r\n"
5304 "Host: www.example.org\r\n"
5305 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205306 };
5307
5308 // The proxy responds to the connect with a 407, using a persistent
5309 // connection.
5310 MockRead data_reads1[] = {
5311 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
5312
5313 MockRead("HTTP/1.1 200 OK\r\n"),
5314 MockRead("Content-Length: 1\r\n\r\n"),
5315 MockRead(SYNCHRONOUS, "1"),
5316
5317 MockRead("HTTP/1.1 200 OK\r\n"),
5318 MockRead("Content-Length: 2\r\n\r\n"),
5319 MockRead(SYNCHRONOUS, "22"),
5320 };
5321
Ryan Sleevib8d7ea02018-05-07 20:01:015322 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:075323 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:205324 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075325 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:205326
5327 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:585328 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:195329 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:205330
5331 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015332 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:205333
5334 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015335 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:205336
5337 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:525338 ASSERT_TRUE(response1);
5339 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:205340 EXPECT_EQ(1, response1->headers->GetContentLength());
5341
5342 LoadTimingInfo load_timing_info1;
5343 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
5344 TestLoadTimingNotReusedWithPac(load_timing_info1,
5345 CONNECT_TIMING_HAS_SSL_TIMES);
5346
5347 trans1.reset();
5348
5349 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:585350 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:195351 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:205352
5353 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015354 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:205355
5356 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015357 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:205358
5359 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:525360 ASSERT_TRUE(response2);
5361 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:205362 EXPECT_EQ(2, response2->headers->GetContentLength());
5363
5364 LoadTimingInfo load_timing_info2;
5365 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5366 TestLoadTimingReusedWithPac(load_timing_info2);
5367
5368 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
5369
5370 trans2.reset();
5371 session->CloseAllConnections();
5372}
5373
[email protected]2df19bb2010-08-25 20:13:465374// Test a simple get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015375TEST_F(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:275376 HttpRequestInfo request;
5377 request.method = "GET";
bncce36dca22015-04-21 22:11:235378 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105379 request.traffic_annotation =
5380 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275381
[email protected]2df19bb2010-08-25 20:13:465382 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495383 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5384 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515385 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075386 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095387 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:465388
[email protected]2df19bb2010-08-25 20:13:465389 // Since we have proxy, should use full url
5390 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235391 MockWrite(
5392 "GET http://www.example.org/ HTTP/1.1\r\n"
5393 "Host: www.example.org\r\n"
5394 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465395 };
5396
5397 MockRead data_reads1[] = {
5398 MockRead("HTTP/1.1 200 OK\r\n"),
5399 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5400 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065401 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:465402 };
5403
Ryan Sleevib8d7ea02018-05-07 20:01:015404 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:075405 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:065406 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075407 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:465408
[email protected]49639fa2011-12-20 23:22:415409 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:465410
bnc691fda62016-08-12 00:43:165411 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505412
bnc691fda62016-08-12 00:43:165413 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015414 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465415
5416 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015417 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465418
[email protected]58e32bb2013-01-21 18:23:255419 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165420 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255421 TestLoadTimingNotReused(load_timing_info,
5422 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5423
bnc691fda62016-08-12 00:43:165424 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525425 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:465426
tbansal2ecbbc72016-10-06 17:15:475427 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:465428 EXPECT_TRUE(response->headers->IsKeepAlive());
5429 EXPECT_EQ(200, response->headers->response_code());
5430 EXPECT_EQ(100, response->headers->GetContentLength());
5431 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5432
5433 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525434 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:465435}
5436
[email protected]7642b5ae2010-09-01 20:55:175437// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015438TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:275439 HttpRequestInfo request;
5440 request.method = "GET";
bncce36dca22015-04-21 22:11:235441 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105442 request.traffic_annotation =
5443 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275444
[email protected]7642b5ae2010-09-01 20:55:175445 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495446 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5447 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515448 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075449 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095450 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:175451
bncce36dca22015-04-21 22:11:235452 // fetch http://www.example.org/ via SPDY
Ryan Hamilton0239aac2018-05-19 00:03:135453 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:455454 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415455 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]7642b5ae2010-09-01 20:55:175456
Ryan Hamilton0239aac2018-05-19 00:03:135457 spdy::SpdySerializedFrame resp(
5458 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
5459 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:175460 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415461 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]7642b5ae2010-09-01 20:55:175462 };
5463
Ryan Sleevib8d7ea02018-05-07 20:01:015464 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075465 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:175466
[email protected]8ddf8322012-02-23 18:08:065467 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365468 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075469 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:175470
[email protected]49639fa2011-12-20 23:22:415471 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:175472
bnc691fda62016-08-12 00:43:165473 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505474
bnc691fda62016-08-12 00:43:165475 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015476 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7642b5ae2010-09-01 20:55:175477
5478 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015479 EXPECT_THAT(rv, IsOk());
[email protected]7642b5ae2010-09-01 20:55:175480
[email protected]58e32bb2013-01-21 18:23:255481 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165482 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255483 TestLoadTimingNotReused(load_timing_info,
5484 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5485
bnc691fda62016-08-12 00:43:165486 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525487 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:475488 EXPECT_TRUE(response->proxy_server.is_https());
wezca1070932016-05-26 20:30:525489 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025490 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]7642b5ae2010-09-01 20:55:175491
5492 std::string response_data;
bnc691fda62016-08-12 00:43:165493 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235494 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:175495}
5496
[email protected]1c173852014-06-19 12:51:505497// Verifies that a session which races and wins against the owning transaction
5498// (completing prior to host resolution), doesn't fail the transaction.
5499// Regression test for crbug.com/334413.
bncd16676a2016-07-20 16:23:015500TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
[email protected]1c173852014-06-19 12:51:505501 HttpRequestInfo request;
5502 request.method = "GET";
bncce36dca22015-04-21 22:11:235503 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105504 request.traffic_annotation =
5505 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c173852014-06-19 12:51:505506
5507 // Configure SPDY proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495508 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5509 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515510 BoundTestNetLog log;
[email protected]1c173852014-06-19 12:51:505511 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095512 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1c173852014-06-19 12:51:505513
bncce36dca22015-04-21 22:11:235514 // Fetch http://www.example.org/ through the SPDY proxy.
Ryan Hamilton0239aac2018-05-19 00:03:135515 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:455516 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415517 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]1c173852014-06-19 12:51:505518
Ryan Hamilton0239aac2018-05-19 00:03:135519 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
5520 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]1c173852014-06-19 12:51:505521 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415522 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]1c173852014-06-19 12:51:505523 };
5524
Ryan Sleevib8d7ea02018-05-07 20:01:015525 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]1c173852014-06-19 12:51:505526 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
5527
5528 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365529 ssl.next_proto = kProtoHTTP2;
[email protected]1c173852014-06-19 12:51:505530 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5531
5532 TestCompletionCallback callback1;
5533
bnc691fda62016-08-12 00:43:165534 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1c173852014-06-19 12:51:505535
5536 // Stall the hostname resolution begun by the transaction.
[email protected]1c173852014-06-19 12:51:505537 session_deps_.host_resolver->set_ondemand_mode(true);
5538
bnc691fda62016-08-12 00:43:165539 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015540 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c173852014-06-19 12:51:505541
5542 // Race a session to the proxy, which completes first.
5543 session_deps_.host_resolver->set_ondemand_mode(false);
Paul Jensena457017a2018-01-19 23:52:045544 SpdySessionKey key(HostPortPair("proxy", 70), ProxyServer::Direct(),
Matt Menke2436b2f2018-12-11 18:07:115545 PRIVACY_MODE_DISABLED,
5546 SpdySessionKey::IsProxySession::kTrue, SocketTag());
[email protected]1c173852014-06-19 12:51:505547 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:525548 CreateSpdySession(session.get(), key, log.bound());
[email protected]1c173852014-06-19 12:51:505549
5550 // Unstall the resolution begun by the transaction.
5551 session_deps_.host_resolver->set_ondemand_mode(true);
5552 session_deps_.host_resolver->ResolveAllPending();
5553
5554 EXPECT_FALSE(callback1.have_result());
5555 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015556 EXPECT_THAT(rv, IsOk());
[email protected]1c173852014-06-19 12:51:505557
bnc691fda62016-08-12 00:43:165558 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525559 ASSERT_TRUE(response);
5560 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025561 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]1c173852014-06-19 12:51:505562
5563 std::string response_data;
bnc691fda62016-08-12 00:43:165564 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]1c173852014-06-19 12:51:505565 EXPECT_EQ(kUploadData, response_data);
5566}
5567
[email protected]dc7bd1c52010-11-12 00:01:135568// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015569TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:275570 HttpRequestInfo request;
5571 request.method = "GET";
bncce36dca22015-04-21 22:11:235572 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105573 request.traffic_annotation =
5574 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275575
[email protected]79cb5c12011-09-12 13:12:045576 // Configure against https proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495577 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5578 "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515579 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075580 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095581 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:135582
[email protected]dc7bd1c52010-11-12 00:01:135583 // The first request will be a bare GET, the second request will be a
5584 // GET with a Proxy-Authorization header.
bncb26024382016-06-29 02:39:455585 spdy_util_.set_default_url(request.url);
Ryan Hamilton0239aac2018-05-19 00:03:135586 spdy::SpdySerializedFrame req_get(
Bence Béky27ad0a12018-02-08 00:35:485587 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:385588 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]dc7bd1c52010-11-12 00:01:135589 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:465590 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:135591 };
Ryan Hamilton0239aac2018-05-19 00:03:135592 spdy::SpdySerializedFrame req_get_authorization(spdy_util_.ConstructSpdyGet(
Avi Drissman4365a4782018-12-28 19:26:245593 kExtraAuthorizationHeaders, base::size(kExtraAuthorizationHeaders) / 2, 3,
Bence Béky27ad0a12018-02-08 00:35:485594 LOWEST));
[email protected]dc7bd1c52010-11-12 00:01:135595 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415596 CreateMockWrite(req_get, 0), CreateMockWrite(req_get_authorization, 3),
[email protected]dc7bd1c52010-11-12 00:01:135597 };
5598
5599 // The first response is a 407 proxy authentication challenge, and the second
5600 // response will be a 200 response since the second request includes a valid
5601 // Authorization header.
5602 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:465603 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:135604 };
Ryan Hamilton0239aac2018-05-19 00:03:135605 spdy::SpdySerializedFrame resp_authentication(
5606 spdy_util_.ConstructSpdyReplyError(
5607 "407", kExtraAuthenticationHeaders,
Avi Drissman4365a4782018-12-28 19:26:245608 base::size(kExtraAuthenticationHeaders) / 2, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135609 spdy::SpdySerializedFrame body_authentication(
bncdf80d44fd2016-07-15 20:27:415610 spdy_util_.ConstructSpdyDataFrame(1, true));
Ryan Hamilton0239aac2018-05-19 00:03:135611 spdy::SpdySerializedFrame resp_data(
5612 spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
5613 spdy::SpdySerializedFrame body_data(
5614 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:135615 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415616 CreateMockRead(resp_authentication, 1),
bnceb9aa7112017-01-05 01:03:465617 CreateMockRead(body_authentication, 2, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415618 CreateMockRead(resp_data, 4),
5619 CreateMockRead(body_data, 5),
rch8e6c6c42015-05-01 14:05:135620 MockRead(ASYNC, 0, 6),
[email protected]dc7bd1c52010-11-12 00:01:135621 };
5622
Ryan Sleevib8d7ea02018-05-07 20:01:015623 SequencedSocketData data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075624 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:135625
[email protected]8ddf8322012-02-23 18:08:065626 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365627 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075628 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:135629
[email protected]49639fa2011-12-20 23:22:415630 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:135631
bnc691fda62016-08-12 00:43:165632 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]dc7bd1c52010-11-12 00:01:135633
bnc691fda62016-08-12 00:43:165634 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015635 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:135636
5637 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015638 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:135639
bnc691fda62016-08-12 00:43:165640 const HttpResponseInfo* const response = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:135641
wezca1070932016-05-26 20:30:525642 ASSERT_TRUE(response);
5643 ASSERT_TRUE(response->headers);
[email protected]dc7bd1c52010-11-12 00:01:135644 EXPECT_EQ(407, response->headers->response_code());
5645 EXPECT_TRUE(response->was_fetched_via_spdy);
asanka098c0092016-06-16 20:18:435646 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:135647
[email protected]49639fa2011-12-20 23:22:415648 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:135649
bnc691fda62016-08-12 00:43:165650 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015651 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:135652
5653 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015654 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:135655
bnc691fda62016-08-12 00:43:165656 const HttpResponseInfo* const response_restart = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:135657
wezca1070932016-05-26 20:30:525658 ASSERT_TRUE(response_restart);
5659 ASSERT_TRUE(response_restart->headers);
[email protected]dc7bd1c52010-11-12 00:01:135660 EXPECT_EQ(200, response_restart->headers->response_code());
5661 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525662 EXPECT_FALSE(response_restart->auth_challenge);
[email protected]dc7bd1c52010-11-12 00:01:135663}
5664
[email protected]d9da5fe2010-10-13 22:37:165665// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
bncd16676a2016-07-20 16:23:015666TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:275667 HttpRequestInfo request;
5668 request.method = "GET";
bncce36dca22015-04-21 22:11:235669 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105670 request.traffic_annotation =
5671 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275672
[email protected]d9da5fe2010-10-13 22:37:165673 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495674 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5675 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515676 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075677 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095678 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165679
bnc691fda62016-08-12 00:43:165680 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165681
bncce36dca22015-04-21 22:11:235682 // CONNECT to www.example.org:443 via SPDY
Ryan Hamilton0239aac2018-05-19 00:03:135683 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235684 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
5685 // fetch https://www.example.org/ via HTTP
[email protected]d9da5fe2010-10-13 22:37:165686
bncce36dca22015-04-21 22:11:235687 const char get[] =
5688 "GET / HTTP/1.1\r\n"
5689 "Host: www.example.org\r\n"
5690 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:135691 spdy::SpdySerializedFrame wrapped_get(
Bence Békyd74f4382018-02-20 18:26:195692 spdy_util_.ConstructSpdyDataFrame(1, get, false));
Ryan Hamilton0239aac2018-05-19 00:03:135693 spdy::SpdySerializedFrame conn_resp(
5694 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:165695 const char resp[] = "HTTP/1.1 200 OK\r\n"
5696 "Content-Length: 10\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:135697 spdy::SpdySerializedFrame wrapped_get_resp(
Bence Békyd74f4382018-02-20 18:26:195698 spdy_util_.ConstructSpdyDataFrame(1, resp, false));
Ryan Hamilton0239aac2018-05-19 00:03:135699 spdy::SpdySerializedFrame wrapped_body(
Bence Békyd74f4382018-02-20 18:26:195700 spdy_util_.ConstructSpdyDataFrame(1, "1234567890", false));
Ryan Hamilton0239aac2018-05-19 00:03:135701 spdy::SpdySerializedFrame window_update(
bncdf80d44fd2016-07-15 20:27:415702 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
[email protected]8d2f7012012-02-16 00:08:045703
5704 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415705 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
5706 CreateMockWrite(window_update, 6),
[email protected]8d2f7012012-02-16 00:08:045707 };
5708
[email protected]d9da5fe2010-10-13 22:37:165709 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415710 CreateMockRead(conn_resp, 1, ASYNC),
5711 CreateMockRead(wrapped_get_resp, 3, ASYNC),
5712 CreateMockRead(wrapped_body, 4, ASYNC),
5713 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:135714 MockRead(ASYNC, 0, 7),
[email protected]d9da5fe2010-10-13 22:37:165715 };
5716
Ryan Sleevib8d7ea02018-05-07 20:01:015717 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075718 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165719
[email protected]8ddf8322012-02-23 18:08:065720 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365721 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075722 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065723 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075724 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165725
[email protected]49639fa2011-12-20 23:22:415726 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165727
bnc691fda62016-08-12 00:43:165728 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015729 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165730
5731 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015732 ASSERT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:165733
[email protected]58e32bb2013-01-21 18:23:255734 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165735 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255736 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5737
bnc691fda62016-08-12 00:43:165738 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525739 ASSERT_TRUE(response);
5740 ASSERT_TRUE(response->headers);
[email protected]d9da5fe2010-10-13 22:37:165741 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5742
5743 std::string response_data;
bnc691fda62016-08-12 00:43:165744 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]d9da5fe2010-10-13 22:37:165745 EXPECT_EQ("1234567890", response_data);
5746}
5747
5748// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
bncd16676a2016-07-20 16:23:015749TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
5750 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:385751
[email protected]cb9bf6ca2011-01-28 13:15:275752 HttpRequestInfo request;
5753 request.method = "GET";
bncce36dca22015-04-21 22:11:235754 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105755 request.traffic_annotation =
5756 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275757
[email protected]d9da5fe2010-10-13 22:37:165758 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495759 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5760 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515761 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075762 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095763 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165764
bnc691fda62016-08-12 00:43:165765 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165766
bncce36dca22015-04-21 22:11:235767 // CONNECT to www.example.org:443 via SPDY
Ryan Hamilton0239aac2018-05-19 00:03:135768 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235769 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
5770 // fetch https://www.example.org/ via SPDY
5771 const char kMyUrl[] = "https://www.example.org/";
Ryan Hamilton0239aac2018-05-19 00:03:135772 spdy::SpdySerializedFrame get(
bnc38dcd392016-02-09 23:19:495773 spdy_util_wrapped.ConstructSpdyGet(kMyUrl, 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:135774 spdy::SpdySerializedFrame wrapped_get(
5775 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
5776 spdy::SpdySerializedFrame conn_resp(
5777 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
5778 spdy::SpdySerializedFrame get_resp(
bnc42331402016-07-25 13:36:155779 spdy_util_wrapped.ConstructSpdyGetReply(NULL, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135780 spdy::SpdySerializedFrame wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:025781 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135782 spdy::SpdySerializedFrame body(
5783 spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
5784 spdy::SpdySerializedFrame wrapped_body(
[email protected]23e482282013-06-14 16:08:025785 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135786 spdy::SpdySerializedFrame window_update_get_resp(
bncdf80d44fd2016-07-15 20:27:415787 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
Ryan Hamilton0239aac2018-05-19 00:03:135788 spdy::SpdySerializedFrame window_update_body(
bncdf80d44fd2016-07-15 20:27:415789 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
[email protected]8d2f7012012-02-16 00:08:045790
5791 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415792 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
5793 CreateMockWrite(window_update_get_resp, 6),
5794 CreateMockWrite(window_update_body, 7),
[email protected]8d2f7012012-02-16 00:08:045795 };
5796
[email protected]d9da5fe2010-10-13 22:37:165797 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415798 CreateMockRead(conn_resp, 1, ASYNC),
rch32320842015-05-16 15:57:095799 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:415800 CreateMockRead(wrapped_get_resp, 4, ASYNC),
5801 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:135802 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:165803 };
5804
Ryan Sleevib8d7ea02018-05-07 20:01:015805 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075806 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165807
[email protected]8ddf8322012-02-23 18:08:065808 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365809 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075810 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065811 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365812 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075813 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165814
[email protected]49639fa2011-12-20 23:22:415815 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165816
bnc691fda62016-08-12 00:43:165817 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015818 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165819
rch32320842015-05-16 15:57:095820 // Allow the SpdyProxyClientSocket's write callback to complete.
fdoray92e35a72016-06-10 15:54:555821 base::RunLoop().RunUntilIdle();
rch32320842015-05-16 15:57:095822 // Now allow the read of the response to complete.
mmenkee24011922015-12-17 22:12:595823 spdy_data.Resume();
[email protected]d9da5fe2010-10-13 22:37:165824 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015825 EXPECT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:165826
[email protected]58e32bb2013-01-21 18:23:255827 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165828 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255829 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5830
bnc691fda62016-08-12 00:43:165831 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525832 ASSERT_TRUE(response);
5833 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025834 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d9da5fe2010-10-13 22:37:165835
5836 std::string response_data;
bnc691fda62016-08-12 00:43:165837 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235838 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:165839}
5840
5841// Test a SPDY CONNECT failure through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015842TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:275843 HttpRequestInfo request;
5844 request.method = "GET";
bncce36dca22015-04-21 22:11:235845 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105846 request.traffic_annotation =
5847 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275848
[email protected]d9da5fe2010-10-13 22:37:165849 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495850 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5851 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515852 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075853 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095854 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165855
bnc691fda62016-08-12 00:43:165856 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165857
bncce36dca22015-04-21 22:11:235858 // CONNECT to www.example.org:443 via SPDY
Ryan Hamilton0239aac2018-05-19 00:03:135859 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235860 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:135861 spdy::SpdySerializedFrame get(
5862 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:165863
5864 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415865 CreateMockWrite(connect, 0), CreateMockWrite(get, 2),
[email protected]d9da5fe2010-10-13 22:37:165866 };
5867
Ryan Hamilton0239aac2018-05-19 00:03:135868 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(1));
5869 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:165870 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415871 CreateMockRead(resp, 1, ASYNC), MockRead(ASYNC, 0, 3),
[email protected]d9da5fe2010-10-13 22:37:165872 };
5873
Ryan Sleevib8d7ea02018-05-07 20:01:015874 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075875 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165876
[email protected]8ddf8322012-02-23 18:08:065877 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365878 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075879 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065880 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365881 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075882 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165883
[email protected]49639fa2011-12-20 23:22:415884 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165885
bnc691fda62016-08-12 00:43:165886 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015887 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165888
5889 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015890 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]d9da5fe2010-10-13 22:37:165891
ttuttle960fcbf2016-04-19 13:26:325892 // TODO(juliatuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:165893}
5894
Matt Menkecb2cd0982018-12-19 17:54:045895// Test the case where a proxied H2 session doesn't exist when an auth challenge
5896// is observed, but does exist by the time auth credentials are provided.
5897// Proxy-Connection: Close is used so that there's a second DNS lookup, which is
5898// what causes the existing H2 session to be noticed and reused.
5899TEST_F(HttpNetworkTransactionTest, ProxiedH2SessionAppearsDuringAuth) {
5900 ProxyConfig proxy_config;
5901 proxy_config.set_auto_detect(true);
5902 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
5903
5904 CapturingProxyResolver capturing_proxy_resolver;
5905 capturing_proxy_resolver.set_proxy_server(
5906 ProxyServer(ProxyServer::SCHEME_HTTP, HostPortPair("myproxy", 70)));
5907 session_deps_.proxy_resolution_service =
5908 std::make_unique<ProxyResolutionService>(
5909 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
5910 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
5911 std::make_unique<CapturingProxyResolverFactory>(
5912 &capturing_proxy_resolver),
5913 nullptr);
5914
5915 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
5916
5917 const char kMyUrl[] = "https://www.example.org/";
5918 spdy::SpdySerializedFrame get(spdy_util_.ConstructSpdyGet(kMyUrl, 1, LOWEST));
5919 spdy::SpdySerializedFrame get_resp(
5920 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
5921 spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
5922
5923 spdy_util_.UpdateWithStreamDestruction(1);
5924 spdy::SpdySerializedFrame get2(
5925 spdy_util_.ConstructSpdyGet(kMyUrl, 3, LOWEST));
5926 spdy::SpdySerializedFrame get_resp2(
5927 spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
5928 spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
5929
5930 MockWrite auth_challenge_writes[] = {
5931 MockWrite(ASYNC, 0,
5932 "CONNECT www.example.org:443 HTTP/1.1\r\n"
5933 "Host: www.example.org:443\r\n"
5934 "Proxy-Connection: keep-alive\r\n\r\n"),
5935 };
5936
5937 MockRead auth_challenge_reads[] = {
5938 MockRead(ASYNC, 1,
5939 "HTTP/1.1 407 Authentication Required\r\n"
5940 "Content-Length: 0\r\n"
5941 "Proxy-Connection: close\r\n"
5942 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
5943 };
5944
5945 MockWrite spdy_writes[] = {
5946 MockWrite(ASYNC, 0,
5947 "CONNECT www.example.org:443 HTTP/1.1\r\n"
5948 "Host: www.example.org:443\r\n"
5949 "Proxy-Connection: keep-alive\r\n"
5950 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5951 CreateMockWrite(get, 2),
5952 CreateMockWrite(get2, 5),
5953 };
5954
5955 MockRead spdy_reads[] = {
5956 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\n\r\n"),
5957 CreateMockRead(get_resp, 3, ASYNC),
5958 CreateMockRead(body, 4, ASYNC),
5959 CreateMockRead(get_resp2, 6, ASYNC),
5960 CreateMockRead(body2, 7, ASYNC),
5961
5962 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 8),
5963 };
5964
5965 SequencedSocketData auth_challenge1(auth_challenge_reads,
5966 auth_challenge_writes);
5967 session_deps_.socket_factory->AddSocketDataProvider(&auth_challenge1);
5968
5969 SequencedSocketData auth_challenge2(auth_challenge_reads,
5970 auth_challenge_writes);
5971 session_deps_.socket_factory->AddSocketDataProvider(&auth_challenge2);
5972
5973 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
5974 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
5975
5976 SSLSocketDataProvider ssl(ASYNC, OK);
5977 ssl.next_proto = kProtoHTTP2;
5978 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5979
5980 TestCompletionCallback callback;
5981 std::string response_data;
5982
5983 // Run first request until an auth challenge is observed.
5984 HttpRequestInfo request1;
5985 request1.method = "GET";
5986 request1.url = GURL(kMyUrl);
5987 request1.traffic_annotation =
5988 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5989 HttpNetworkTransaction trans1(LOWEST, session.get());
5990 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
5991 EXPECT_THAT(callback.GetResult(rv), IsOk());
5992 const HttpResponseInfo* response = trans1.GetResponseInfo();
5993 ASSERT_TRUE(response);
5994 ASSERT_TRUE(response->headers);
5995 EXPECT_EQ(407, response->headers->response_code());
5996 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5997 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
5998
5999 // Run second request until an auth challenge is observed.
6000 HttpRequestInfo request2;
6001 request2.method = "GET";
6002 request2.url = GURL(kMyUrl);
6003 request2.traffic_annotation =
6004 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6005 HttpNetworkTransaction trans2(LOWEST, session.get());
6006 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
6007 EXPECT_THAT(callback.GetResult(rv), IsOk());
6008 response = trans2.GetResponseInfo();
6009 ASSERT_TRUE(response);
6010 ASSERT_TRUE(response->headers);
6011 EXPECT_EQ(407, response->headers->response_code());
6012 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6013 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
6014
6015 // Now provide credentials for the first request, and wait for it to complete.
6016 rv = trans1.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
6017 rv = callback.GetResult(rv);
6018 EXPECT_THAT(rv, IsOk());
6019 response = trans1.GetResponseInfo();
6020 ASSERT_TRUE(response);
6021 ASSERT_TRUE(response->headers);
6022 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
6023 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
6024 EXPECT_EQ(kUploadData, response_data);
6025
6026 // Now provide credentials for the second request. It should notice the
6027 // existing session, and reuse it.
6028 rv = trans2.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
6029 EXPECT_THAT(callback.GetResult(rv), IsOk());
6030 response = trans2.GetResponseInfo();
6031 ASSERT_TRUE(response);
6032 ASSERT_TRUE(response->headers);
6033 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
6034 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
6035 EXPECT_EQ(kUploadData, response_data);
6036}
6037
[email protected]f6c63db52013-02-02 00:35:226038// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
6039// HTTPS Proxy to different servers.
bncd16676a2016-07-20 16:23:016040TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:226041 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
6042 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496043 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6044 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:516045 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076046 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:096047 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:506048 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:226049
6050 HttpRequestInfo request1;
6051 request1.method = "GET";
bncce36dca22015-04-21 22:11:236052 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:226053 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:106054 request1.traffic_annotation =
6055 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226056
6057 HttpRequestInfo request2;
6058 request2.method = "GET";
bncce36dca22015-04-21 22:11:236059 request2.url = GURL("https://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:226060 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:106061 request2.traffic_annotation =
6062 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226063
bncce36dca22015-04-21 22:11:236064 // CONNECT to www.example.org:443 via SPDY.
Ryan Hamilton0239aac2018-05-19 00:03:136065 spdy::SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:236066 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:136067 spdy::SpdySerializedFrame conn_resp1(
6068 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:226069
bncce36dca22015-04-21 22:11:236070 // Fetch https://www.example.org/ via HTTP.
6071 const char get1[] =
6072 "GET / HTTP/1.1\r\n"
6073 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:226074 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136075 spdy::SpdySerializedFrame wrapped_get1(
Bence Békyd74f4382018-02-20 18:26:196076 spdy_util_.ConstructSpdyDataFrame(1, get1, false));
[email protected]f6c63db52013-02-02 00:35:226077 const char resp1[] = "HTTP/1.1 200 OK\r\n"
6078 "Content-Length: 1\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136079 spdy::SpdySerializedFrame wrapped_get_resp1(
Bence Békyd74f4382018-02-20 18:26:196080 spdy_util_.ConstructSpdyDataFrame(1, resp1, false));
Ryan Hamilton0239aac2018-05-19 00:03:136081 spdy::SpdySerializedFrame wrapped_body1(
Bence Békyd74f4382018-02-20 18:26:196082 spdy_util_.ConstructSpdyDataFrame(1, "1", false));
Ryan Hamilton0239aac2018-05-19 00:03:136083 spdy::SpdySerializedFrame window_update(
bncdf80d44fd2016-07-15 20:27:416084 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:226085
bncce36dca22015-04-21 22:11:236086 // CONNECT to mail.example.org:443 via SPDY.
Ryan Hamilton0239aac2018-05-19 00:03:136087 spdy::SpdyHeaderBlock connect2_block;
6088 connect2_block[spdy::kHttp2MethodHeader] = "CONNECT";
6089 connect2_block[spdy::kHttp2AuthorityHeader] = "mail.example.org:443";
6090 spdy::SpdySerializedFrame connect2(spdy_util_.ConstructSpdyHeaders(
bnc42331402016-07-25 13:36:156091 3, std::move(connect2_block), LOWEST, false));
[email protected]601e03f12014-04-06 16:26:396092
Ryan Hamilton0239aac2018-05-19 00:03:136093 spdy::SpdySerializedFrame conn_resp2(
6094 spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:226095
bncce36dca22015-04-21 22:11:236096 // Fetch https://mail.example.org/ via HTTP.
6097 const char get2[] =
6098 "GET / HTTP/1.1\r\n"
6099 "Host: mail.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:226100 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136101 spdy::SpdySerializedFrame wrapped_get2(
Bence Békyd74f4382018-02-20 18:26:196102 spdy_util_.ConstructSpdyDataFrame(3, get2, false));
[email protected]f6c63db52013-02-02 00:35:226103 const char resp2[] = "HTTP/1.1 200 OK\r\n"
6104 "Content-Length: 2\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136105 spdy::SpdySerializedFrame wrapped_get_resp2(
Bence Békyd74f4382018-02-20 18:26:196106 spdy_util_.ConstructSpdyDataFrame(3, resp2, false));
Ryan Hamilton0239aac2018-05-19 00:03:136107 spdy::SpdySerializedFrame wrapped_body2(
Bence Békyd74f4382018-02-20 18:26:196108 spdy_util_.ConstructSpdyDataFrame(3, "22", false));
[email protected]f6c63db52013-02-02 00:35:226109
6110 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:416111 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
6112 CreateMockWrite(connect2, 5), CreateMockWrite(wrapped_get2, 7),
[email protected]f6c63db52013-02-02 00:35:226113 };
6114
6115 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:416116 CreateMockRead(conn_resp1, 1, ASYNC),
6117 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
6118 CreateMockRead(wrapped_body1, 4, ASYNC),
6119 CreateMockRead(conn_resp2, 6, ASYNC),
6120 CreateMockRead(wrapped_get_resp2, 8, ASYNC),
6121 CreateMockRead(wrapped_body2, 9, ASYNC),
6122 MockRead(ASYNC, 0, 10),
[email protected]f6c63db52013-02-02 00:35:226123 };
6124
Ryan Sleevib8d7ea02018-05-07 20:01:016125 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
mmenke11eb5152015-06-09 14:50:506126 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:226127
6128 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:366129 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:506130 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:226131 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:506132 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:226133 SSLSocketDataProvider ssl3(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:506134 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:226135
6136 TestCompletionCallback callback;
6137
bnc691fda62016-08-12 00:43:166138 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206139 int rv = trans.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016140 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:226141
6142 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:166143 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]f6c63db52013-02-02 00:35:226144 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
6145
bnc691fda62016-08-12 00:43:166146 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526147 ASSERT_TRUE(response);
6148 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:226149 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6150
6151 std::string response_data;
Victor Costan9c7302b2018-08-27 16:39:446152 scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(256);
bnc691fda62016-08-12 00:43:166153 rv = trans.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:506154 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:226155
bnc691fda62016-08-12 00:43:166156 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206157 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016158 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:226159
6160 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:166161 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:226162 // Even though the SPDY connection is reused, a new tunnelled connection has
6163 // to be created, so the socket's load timing looks like a fresh connection.
6164 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
6165
6166 // The requests should have different IDs, since they each are using their own
6167 // separate stream.
6168 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
6169
bnc691fda62016-08-12 00:43:166170 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:506171 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:226172}
6173
6174// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
6175// HTTPS Proxy to the same server.
bncd16676a2016-07-20 16:23:016176TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:226177 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
6178 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496179 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6180 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:516181 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076182 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:096183 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:506184 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:226185
6186 HttpRequestInfo request1;
6187 request1.method = "GET";
bncce36dca22015-04-21 22:11:236188 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:226189 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:106190 request1.traffic_annotation =
6191 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226192
6193 HttpRequestInfo request2;
6194 request2.method = "GET";
bncce36dca22015-04-21 22:11:236195 request2.url = GURL("https://www.example.org/2");
[email protected]f6c63db52013-02-02 00:35:226196 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:106197 request2.traffic_annotation =
6198 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226199
bncce36dca22015-04-21 22:11:236200 // CONNECT to www.example.org:443 via SPDY.
Ryan Hamilton0239aac2018-05-19 00:03:136201 spdy::SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:236202 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:136203 spdy::SpdySerializedFrame conn_resp1(
6204 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:226205
bncce36dca22015-04-21 22:11:236206 // Fetch https://www.example.org/ via HTTP.
6207 const char get1[] =
6208 "GET / HTTP/1.1\r\n"
6209 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:226210 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136211 spdy::SpdySerializedFrame wrapped_get1(
Bence Békyd74f4382018-02-20 18:26:196212 spdy_util_.ConstructSpdyDataFrame(1, get1, false));
[email protected]f6c63db52013-02-02 00:35:226213 const char resp1[] = "HTTP/1.1 200 OK\r\n"
6214 "Content-Length: 1\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136215 spdy::SpdySerializedFrame wrapped_get_resp1(
Bence Békyd74f4382018-02-20 18:26:196216 spdy_util_.ConstructSpdyDataFrame(1, resp1, false));
Ryan Hamilton0239aac2018-05-19 00:03:136217 spdy::SpdySerializedFrame wrapped_body1(
Bence Békyd74f4382018-02-20 18:26:196218 spdy_util_.ConstructSpdyDataFrame(1, "1", false));
Ryan Hamilton0239aac2018-05-19 00:03:136219 spdy::SpdySerializedFrame window_update(
bncdf80d44fd2016-07-15 20:27:416220 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:226221
bncce36dca22015-04-21 22:11:236222 // Fetch https://www.example.org/2 via HTTP.
6223 const char get2[] =
6224 "GET /2 HTTP/1.1\r\n"
6225 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:226226 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136227 spdy::SpdySerializedFrame wrapped_get2(
Bence Békyd74f4382018-02-20 18:26:196228 spdy_util_.ConstructSpdyDataFrame(1, get2, false));
[email protected]f6c63db52013-02-02 00:35:226229 const char resp2[] = "HTTP/1.1 200 OK\r\n"
6230 "Content-Length: 2\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136231 spdy::SpdySerializedFrame wrapped_get_resp2(
Bence Békyd74f4382018-02-20 18:26:196232 spdy_util_.ConstructSpdyDataFrame(1, resp2, false));
Ryan Hamilton0239aac2018-05-19 00:03:136233 spdy::SpdySerializedFrame wrapped_body2(
Bence Békyd74f4382018-02-20 18:26:196234 spdy_util_.ConstructSpdyDataFrame(1, "22", false));
[email protected]f6c63db52013-02-02 00:35:226235
6236 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:416237 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
6238 CreateMockWrite(wrapped_get2, 5),
[email protected]f6c63db52013-02-02 00:35:226239 };
6240
6241 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:416242 CreateMockRead(conn_resp1, 1, ASYNC),
6243 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
bnceb9aa7112017-01-05 01:03:466244 CreateMockRead(wrapped_body1, 4, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:416245 CreateMockRead(wrapped_get_resp2, 6, ASYNC),
bnceb9aa7112017-01-05 01:03:466246 CreateMockRead(wrapped_body2, 7, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:416247 MockRead(ASYNC, 0, 8),
[email protected]f6c63db52013-02-02 00:35:226248 };
6249
Ryan Sleevib8d7ea02018-05-07 20:01:016250 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
mmenke11eb5152015-06-09 14:50:506251 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:226252
6253 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:366254 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:506255 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:226256 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:506257 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:226258
6259 TestCompletionCallback callback;
6260
bnc87dcefc2017-05-25 12:47:586261 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:196262 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206263 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016264 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:226265
6266 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016267 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:226268
6269 LoadTimingInfo load_timing_info;
6270 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6271 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
6272
6273 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526274 ASSERT_TRUE(response);
6275 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:226276 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6277
6278 std::string response_data;
Victor Costan9c7302b2018-08-27 16:39:446279 scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(256);
[email protected]90499482013-06-01 00:39:506280 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:226281 trans.reset();
6282
bnc87dcefc2017-05-25 12:47:586283 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:196284 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206285 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016286 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:226287
[email protected]f6c63db52013-02-02 00:35:226288 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016289 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:226290
6291 LoadTimingInfo load_timing_info2;
6292 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
6293 TestLoadTimingReused(load_timing_info2);
6294
6295 // The requests should have the same ID.
6296 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
6297
[email protected]90499482013-06-01 00:39:506298 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:226299}
6300
6301// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
6302// Proxy to different servers.
bncd16676a2016-07-20 16:23:016303TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) {
[email protected]f6c63db52013-02-02 00:35:226304 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496305 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6306 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:516307 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076308 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:096309 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:506310 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:226311
6312 HttpRequestInfo request1;
6313 request1.method = "GET";
bncce36dca22015-04-21 22:11:236314 request1.url = GURL("http://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:226315 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:106316 request1.traffic_annotation =
6317 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226318
6319 HttpRequestInfo request2;
6320 request2.method = "GET";
bncce36dca22015-04-21 22:11:236321 request2.url = GURL("http://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:226322 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:106323 request2.traffic_annotation =
6324 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226325
bncce36dca22015-04-21 22:11:236326 // http://www.example.org/
Ryan Hamilton0239aac2018-05-19 00:03:136327 spdy::SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:236328 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
Ryan Hamilton0239aac2018-05-19 00:03:136329 spdy::SpdySerializedFrame get1(
bnc42331402016-07-25 13:36:156330 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
Ryan Hamilton0239aac2018-05-19 00:03:136331 spdy::SpdySerializedFrame get_resp1(
6332 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
6333 spdy::SpdySerializedFrame body1(
6334 spdy_util_.ConstructSpdyDataFrame(1, "1", true));
rdsmithebb50aa2015-11-12 03:44:386335 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]f6c63db52013-02-02 00:35:226336
bncce36dca22015-04-21 22:11:236337 // http://mail.example.org/
Ryan Hamilton0239aac2018-05-19 00:03:136338 spdy::SpdyHeaderBlock headers2(
bncce36dca22015-04-21 22:11:236339 spdy_util_.ConstructGetHeaderBlockForProxy("http://mail.example.org/"));
Ryan Hamilton0239aac2018-05-19 00:03:136340 spdy::SpdySerializedFrame get2(
bnc42331402016-07-25 13:36:156341 spdy_util_.ConstructSpdyHeaders(3, std::move(headers2), LOWEST, true));
Ryan Hamilton0239aac2018-05-19 00:03:136342 spdy::SpdySerializedFrame get_resp2(
6343 spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
6344 spdy::SpdySerializedFrame body2(
6345 spdy_util_.ConstructSpdyDataFrame(3, "22", true));
[email protected]f6c63db52013-02-02 00:35:226346
6347 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:416348 CreateMockWrite(get1, 0), CreateMockWrite(get2, 3),
[email protected]f6c63db52013-02-02 00:35:226349 };
6350
6351 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:416352 CreateMockRead(get_resp1, 1, ASYNC),
6353 CreateMockRead(body1, 2, ASYNC),
6354 CreateMockRead(get_resp2, 4, ASYNC),
6355 CreateMockRead(body2, 5, ASYNC),
6356 MockRead(ASYNC, 0, 6),
[email protected]f6c63db52013-02-02 00:35:226357 };
6358
Ryan Sleevib8d7ea02018-05-07 20:01:016359 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
mmenke11eb5152015-06-09 14:50:506360 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:226361
6362 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:366363 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:506364 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:226365
6366 TestCompletionCallback callback;
6367
bnc87dcefc2017-05-25 12:47:586368 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:196369 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206370 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016371 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:226372
6373 LoadTimingInfo load_timing_info;
6374 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6375 TestLoadTimingNotReused(load_timing_info,
6376 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6377
6378 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526379 ASSERT_TRUE(response);
6380 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:026381 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]f6c63db52013-02-02 00:35:226382
6383 std::string response_data;
Victor Costan9c7302b2018-08-27 16:39:446384 scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(256);
mmenke11eb5152015-06-09 14:50:506385 rv = trans->Read(buf.get(), 256, callback.callback());
6386 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:226387 // Delete the first request, so the second one can reuse the socket.
6388 trans.reset();
6389
bnc691fda62016-08-12 00:43:166390 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206391 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016392 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:226393
6394 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:166395 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:226396 TestLoadTimingReused(load_timing_info2);
6397
6398 // The requests should have the same ID.
6399 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
6400
bnc691fda62016-08-12 00:43:166401 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:506402 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:226403}
6404
Matt Menke2436b2f2018-12-11 18:07:116405// Test that an HTTP/2 CONNECT through an HTTPS Proxy to a HTTP/2 server and a
6406// direct (non-proxied) request to the proxy server are not pooled, as that
6407// would break socket pool isolation.
6408TEST_F(HttpNetworkTransactionTest, SpdyProxyIsolation1) {
6409 ProxyConfig proxy_config;
6410 proxy_config.set_auto_detect(true);
6411 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
6412
6413 CapturingProxyResolver capturing_proxy_resolver;
6414 session_deps_.proxy_resolution_service =
6415 std::make_unique<ProxyResolutionService>(
6416 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
6417 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
6418 std::make_unique<CapturingProxyResolverFactory>(
6419 &capturing_proxy_resolver),
6420 nullptr);
6421
6422 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6423
6424 SpdyTestUtil spdy_util1;
6425 // CONNECT to www.example.org:443 via HTTP/2.
6426 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
6427 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
6428 // fetch https://www.example.org/ via HTTP/2.
6429 const char kMyUrl[] = "https://www.example.org/";
6430 spdy::SpdySerializedFrame get(spdy_util1.ConstructSpdyGet(kMyUrl, 1, LOWEST));
6431 spdy::SpdySerializedFrame wrapped_get(
6432 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
6433 spdy::SpdySerializedFrame conn_resp(
6434 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
6435 spdy::SpdySerializedFrame get_resp(
6436 spdy_util1.ConstructSpdyGetReply(NULL, 0, 1));
6437 spdy::SpdySerializedFrame wrapped_get_resp(
6438 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
6439 spdy::SpdySerializedFrame body(spdy_util1.ConstructSpdyDataFrame(1, true));
6440 spdy::SpdySerializedFrame wrapped_body(
6441 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
6442 spdy::SpdySerializedFrame window_update_get_resp(
6443 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
6444 spdy::SpdySerializedFrame window_update_body(
6445 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
6446
6447 MockWrite spdy_writes1[] = {
6448 CreateMockWrite(connect, 0),
6449 CreateMockWrite(wrapped_get, 2),
6450 CreateMockWrite(window_update_get_resp, 6),
6451 CreateMockWrite(window_update_body, 7),
6452 };
6453
6454 MockRead spdy_reads1[] = {
6455 CreateMockRead(conn_resp, 1, ASYNC),
6456 MockRead(ASYNC, ERR_IO_PENDING, 3),
6457 CreateMockRead(wrapped_get_resp, 4, ASYNC),
6458 CreateMockRead(wrapped_body, 5, ASYNC),
6459 MockRead(ASYNC, 0, 8),
6460 };
6461
6462 SequencedSocketData spdy_data1(spdy_reads1, spdy_writes1);
6463 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data1);
6464
6465 // Fetch https://proxy:70/ via HTTP/2. Needs a new SpdyTestUtil, since it uses
6466 // a new pipe.
6467 SpdyTestUtil spdy_util2;
6468 spdy::SpdySerializedFrame req(
6469 spdy_util2.ConstructSpdyGet("https://proxy:70/", 1, LOWEST));
6470 MockWrite spdy_writes2[] = {CreateMockWrite(req, 0)};
6471
6472 spdy::SpdySerializedFrame resp(
6473 spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
6474 spdy::SpdySerializedFrame data(spdy_util2.ConstructSpdyDataFrame(1, true));
6475 MockRead spdy_reads2[] = {
6476 CreateMockRead(resp, 1),
6477 CreateMockRead(data, 2),
6478 MockRead(ASYNC, 0, 3),
6479 };
6480 SequencedSocketData spdy_data2(spdy_reads2, spdy_writes2);
6481 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data2);
6482
6483 SSLSocketDataProvider ssl(ASYNC, OK);
6484 ssl.next_proto = kProtoHTTP2;
6485 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6486 SSLSocketDataProvider ssl2(ASYNC, OK);
6487 ssl2.next_proto = kProtoHTTP2;
6488 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6489 SSLSocketDataProvider ssl3(ASYNC, OK);
6490 ssl3.next_proto = kProtoHTTP2;
6491 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
6492
6493 TestCompletionCallback callback;
6494 std::string response_data;
6495
6496 // Make a request using proxy:70 as a HTTP/2 proxy.
6497 capturing_proxy_resolver.set_proxy_server(
6498 ProxyServer(ProxyServer::SCHEME_HTTPS, HostPortPair("proxy", 70)));
6499 HttpRequestInfo request1;
6500 request1.method = "GET";
6501 request1.url = GURL("https://www.example.org/");
6502 request1.traffic_annotation =
6503 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6504
6505 HttpNetworkTransaction trans1(LOWEST, session.get());
6506 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
6507 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6508
6509 // Allow the SpdyProxyClientSocket's write callback to complete.
6510 base::RunLoop().RunUntilIdle();
6511 // Now allow the read of the response to complete.
6512 spdy_data1.Resume();
6513 rv = callback.WaitForResult();
6514 EXPECT_THAT(rv, IsOk());
6515
6516 const HttpResponseInfo* response = trans1.GetResponseInfo();
6517 ASSERT_TRUE(response);
6518 ASSERT_TRUE(response->headers);
6519 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
6520
6521 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
6522 EXPECT_EQ(kUploadData, response_data);
6523 RunUntilIdle();
6524
6525 // Make a direct HTTP/2 request to proxy:70.
6526 capturing_proxy_resolver.set_proxy_server(ProxyServer::Direct());
6527 HttpRequestInfo request2;
6528 request2.method = "GET";
6529 request2.url = GURL("https://proxy:70/");
6530 request2.traffic_annotation =
6531 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6532 HttpNetworkTransaction trans2(LOWEST, session.get());
6533 EXPECT_THAT(callback.GetResult(trans2.Start(&request2, callback.callback(),
6534 NetLogWithSource())),
6535 IsOk());
6536 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
6537}
6538
6539// Same as above, but reverse request order, since the code to check for an
6540// existing session is different for tunnels and direct connections.
6541TEST_F(HttpNetworkTransactionTest, SpdyProxyIsolation2) {
6542 // Configure against https proxy server "myproxy:80".
6543 ProxyConfig proxy_config;
6544 proxy_config.set_auto_detect(true);
6545 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
6546
6547 CapturingProxyResolver capturing_proxy_resolver;
6548 session_deps_.proxy_resolution_service =
6549 std::make_unique<ProxyResolutionService>(
6550 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
6551 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
6552 std::make_unique<CapturingProxyResolverFactory>(
6553 &capturing_proxy_resolver),
6554 nullptr);
6555
6556 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6557 // Fetch https://proxy:70/ via HTTP/2.
6558 SpdyTestUtil spdy_util1;
6559 spdy::SpdySerializedFrame req(
6560 spdy_util1.ConstructSpdyGet("https://proxy:70/", 1, LOWEST));
6561 MockWrite spdy_writes1[] = {CreateMockWrite(req, 0)};
6562
6563 spdy::SpdySerializedFrame resp(
6564 spdy_util1.ConstructSpdyGetReply(nullptr, 0, 1));
6565 spdy::SpdySerializedFrame data(spdy_util1.ConstructSpdyDataFrame(1, true));
6566 MockRead spdy_reads1[] = {
6567 CreateMockRead(resp, 1),
6568 CreateMockRead(data, 2),
6569 MockRead(ASYNC, 0, 3),
6570 };
6571 SequencedSocketData spdy_data1(spdy_reads1, spdy_writes1);
6572 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data1);
6573
6574 SpdyTestUtil spdy_util2;
6575 // CONNECT to www.example.org:443 via HTTP/2.
6576 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
6577 nullptr, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
6578 // fetch https://www.example.org/ via HTTP/2.
6579 const char kMyUrl[] = "https://www.example.org/";
6580 spdy::SpdySerializedFrame get(spdy_util2.ConstructSpdyGet(kMyUrl, 1, LOWEST));
6581 spdy::SpdySerializedFrame wrapped_get(
6582 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
6583 spdy::SpdySerializedFrame conn_resp(
6584 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
6585 spdy::SpdySerializedFrame get_resp(
6586 spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
6587 spdy::SpdySerializedFrame wrapped_get_resp(
6588 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
6589 spdy::SpdySerializedFrame body(spdy_util2.ConstructSpdyDataFrame(1, true));
6590 spdy::SpdySerializedFrame wrapped_body(
6591 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
6592 spdy::SpdySerializedFrame window_update_get_resp(
6593 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
6594 spdy::SpdySerializedFrame window_update_body(
6595 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
6596
6597 MockWrite spdy_writes2[] = {
6598 CreateMockWrite(connect, 0),
6599 CreateMockWrite(wrapped_get, 2),
6600 CreateMockWrite(window_update_get_resp, 6),
6601 CreateMockWrite(window_update_body, 7),
6602 };
6603
6604 MockRead spdy_reads2[] = {
6605 CreateMockRead(conn_resp, 1, ASYNC),
6606 MockRead(ASYNC, ERR_IO_PENDING, 3),
6607 CreateMockRead(wrapped_get_resp, 4, ASYNC),
6608 CreateMockRead(wrapped_body, 5, ASYNC),
6609 MockRead(ASYNC, 0, 8),
6610 };
6611
6612 SequencedSocketData spdy_data2(spdy_reads2, spdy_writes2);
6613 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data2);
6614
6615 SSLSocketDataProvider ssl(ASYNC, OK);
6616 ssl.next_proto = kProtoHTTP2;
6617 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6618 SSLSocketDataProvider ssl2(ASYNC, OK);
6619 ssl2.next_proto = kProtoHTTP2;
6620 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6621 SSLSocketDataProvider ssl3(ASYNC, OK);
6622 ssl3.next_proto = kProtoHTTP2;
6623 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
6624
6625 TestCompletionCallback callback;
6626 std::string response_data;
6627
6628 // Make a direct HTTP/2 request to proxy:70.
6629 capturing_proxy_resolver.set_proxy_server(ProxyServer::Direct());
6630 HttpRequestInfo request1;
6631 request1.method = "GET";
6632 request1.url = GURL("https://proxy:70/");
6633 request1.traffic_annotation =
6634 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6635 HttpNetworkTransaction trans1(LOWEST, session.get());
6636 EXPECT_THAT(callback.GetResult(trans1.Start(&request1, callback.callback(),
6637 NetLogWithSource())),
6638 IsOk());
6639 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
6640 RunUntilIdle();
6641
6642 // Make a request using proxy:70 as a HTTP/2 proxy.
6643 capturing_proxy_resolver.set_proxy_server(
6644 ProxyServer(ProxyServer::SCHEME_HTTPS, HostPortPair("proxy", 70)));
6645 HttpRequestInfo request2;
6646 request2.method = "GET";
6647 request2.url = GURL("https://www.example.org/");
6648 request2.traffic_annotation =
6649 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6650
6651 HttpNetworkTransaction trans2(LOWEST, session.get());
6652 int rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
6653 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6654
6655 // Allow the SpdyProxyClientSocket's write callback to complete.
6656 base::RunLoop().RunUntilIdle();
6657 // Now allow the read of the response to complete.
6658 spdy_data2.Resume();
6659 rv = callback.WaitForResult();
6660 EXPECT_THAT(rv, IsOk());
6661
6662 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
6663 ASSERT_TRUE(response2);
6664 ASSERT_TRUE(response2->headers);
6665 EXPECT_EQ("HTTP/1.1 200", response2->headers->GetStatusLine());
6666
6667 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
6668 EXPECT_EQ(kUploadData, response_data);
6669}
6670
[email protected]2df19bb2010-08-25 20:13:466671// Test the challenge-response-retry sequence through an HTTPS Proxy
bncd16676a2016-07-20 16:23:016672TEST_F(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:466673 HttpRequestInfo request;
6674 request.method = "GET";
bncce36dca22015-04-21 22:11:236675 request.url = GURL("http://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:466676 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:296677 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:106678 request.traffic_annotation =
6679 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:466680
[email protected]79cb5c12011-09-12 13:12:046681 // Configure against https proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496682 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6683 "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:516684 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076685 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:096686 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276687
[email protected]2df19bb2010-08-25 20:13:466688 // Since we have proxy, should use full url
6689 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:166690 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
6691 "Host: www.example.org\r\n"
6692 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:466693
bnc691fda62016-08-12 00:43:166694 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:236695 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:166696 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
6697 "Host: www.example.org\r\n"
6698 "Proxy-Connection: keep-alive\r\n"
6699 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:466700 };
6701
6702 // The proxy responds to the GET with a 407, using a persistent
6703 // connection.
6704 MockRead data_reads1[] = {
6705 // No credentials.
6706 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
6707 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6708 MockRead("Proxy-Connection: keep-alive\r\n"),
6709 MockRead("Content-Length: 0\r\n\r\n"),
6710
6711 MockRead("HTTP/1.1 200 OK\r\n"),
6712 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6713 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066714 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:466715 };
6716
Ryan Sleevib8d7ea02018-05-07 20:01:016717 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:076718 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:066719 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076720 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:466721
[email protected]49639fa2011-12-20 23:22:416722 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:466723
bnc691fda62016-08-12 00:43:166724 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506725
bnc691fda62016-08-12 00:43:166726 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:016727 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:466728
6729 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016730 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:466731
[email protected]58e32bb2013-01-21 18:23:256732 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:166733 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:256734 TestLoadTimingNotReused(load_timing_info,
6735 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6736
bnc691fda62016-08-12 00:43:166737 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526738 ASSERT_TRUE(response);
6739 ASSERT_TRUE(response->headers);
[email protected]2df19bb2010-08-25 20:13:466740 EXPECT_EQ(407, response->headers->response_code());
6741 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
asanka098c0092016-06-16 20:18:436742 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:466743
[email protected]49639fa2011-12-20 23:22:416744 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:466745
bnc691fda62016-08-12 00:43:166746 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:016747 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:466748
6749 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016750 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:466751
[email protected]58e32bb2013-01-21 18:23:256752 load_timing_info = LoadTimingInfo();
bnc691fda62016-08-12 00:43:166753 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:256754 // Retrying with HTTP AUTH is considered to be reusing a socket.
6755 TestLoadTimingReused(load_timing_info);
6756
bnc691fda62016-08-12 00:43:166757 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526758 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:466759
6760 EXPECT_TRUE(response->headers->IsKeepAlive());
6761 EXPECT_EQ(200, response->headers->response_code());
6762 EXPECT_EQ(100, response->headers->GetContentLength());
6763 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6764
6765 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:526766 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:466767}
6768
[email protected]23e482282013-06-14 16:08:026769void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:086770 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:426771 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:086772 request.method = "GET";
bncce36dca22015-04-21 22:11:236773 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:106774 request.traffic_annotation =
6775 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]c744cf22009-02-27 07:28:086776
[email protected]cb9bf6ca2011-01-28 13:15:276777 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496778 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6779 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:096780 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276781
[email protected]c744cf22009-02-27 07:28:086782 // Since we have proxy, should try to establish tunnel.
6783 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:176784 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
6785 "Host: www.example.org:443\r\n"
6786 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:086787 };
6788
6789 MockRead data_reads[] = {
mmenked39192ee2015-12-09 00:57:236790 status, MockRead("Content-Length: 10\r\n\r\n"),
6791 // No response body because the test stops reading here.
6792 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]c744cf22009-02-27 07:28:086793 };
6794
Ryan Sleevib8d7ea02018-05-07 20:01:016795 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:076796 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:086797
[email protected]49639fa2011-12-20 23:22:416798 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:086799
bnc691fda62016-08-12 00:43:166800 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506801
tfarina42834112016-09-22 13:38:206802 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016803 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]c744cf22009-02-27 07:28:086804
6805 rv = callback.WaitForResult();
6806 EXPECT_EQ(expected_status, rv);
6807}
6808
[email protected]23e482282013-06-14 16:08:026809void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:236810 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:086811 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:426812 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:086813}
6814
bncd16676a2016-07-20 16:23:016815TEST_F(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:086816 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
6817}
6818
bncd16676a2016-07-20 16:23:016819TEST_F(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:086820 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
6821}
6822
bncd16676a2016-07-20 16:23:016823TEST_F(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:086824 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
6825}
6826
bncd16676a2016-07-20 16:23:016827TEST_F(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:086828 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
6829}
6830
bncd16676a2016-07-20 16:23:016831TEST_F(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:086832 ConnectStatusHelper(
6833 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
6834}
6835
bncd16676a2016-07-20 16:23:016836TEST_F(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:086837 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
6838}
6839
bncd16676a2016-07-20 16:23:016840TEST_F(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:086841 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
6842}
6843
bncd16676a2016-07-20 16:23:016844TEST_F(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:086845 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
6846}
6847
bncd16676a2016-07-20 16:23:016848TEST_F(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:086849 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
6850}
6851
bncd16676a2016-07-20 16:23:016852TEST_F(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:086853 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
6854}
6855
bncd16676a2016-07-20 16:23:016856TEST_F(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:086857 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
6858}
6859
bncd16676a2016-07-20 16:23:016860TEST_F(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:086861 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
6862}
6863
bncd16676a2016-07-20 16:23:016864TEST_F(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:086865 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
6866}
6867
bncd16676a2016-07-20 16:23:016868TEST_F(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:086869 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
6870}
6871
bncd16676a2016-07-20 16:23:016872TEST_F(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:086873 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
6874}
6875
bncd16676a2016-07-20 16:23:016876TEST_F(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:086877 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
6878}
6879
bncd16676a2016-07-20 16:23:016880TEST_F(HttpNetworkTransactionTest, ConnectStatus308) {
[email protected]0a17aab32014-04-24 03:32:376881 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
6882}
6883
bncd16676a2016-07-20 16:23:016884TEST_F(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:086885 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
6886}
6887
bncd16676a2016-07-20 16:23:016888TEST_F(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:086889 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
6890}
6891
bncd16676a2016-07-20 16:23:016892TEST_F(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:086893 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
6894}
6895
bncd16676a2016-07-20 16:23:016896TEST_F(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:086897 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
6898}
6899
bncd16676a2016-07-20 16:23:016900TEST_F(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:086901 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
6902}
6903
bncd16676a2016-07-20 16:23:016904TEST_F(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:086905 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
6906}
6907
bncd16676a2016-07-20 16:23:016908TEST_F(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:086909 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
6910}
6911
bncd16676a2016-07-20 16:23:016912TEST_F(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:086913 ConnectStatusHelperWithExpectedStatus(
6914 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:546915 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:086916}
6917
bncd16676a2016-07-20 16:23:016918TEST_F(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:086919 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
6920}
6921
bncd16676a2016-07-20 16:23:016922TEST_F(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:086923 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
6924}
6925
bncd16676a2016-07-20 16:23:016926TEST_F(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:086927 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
6928}
6929
bncd16676a2016-07-20 16:23:016930TEST_F(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:086931 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
6932}
6933
bncd16676a2016-07-20 16:23:016934TEST_F(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:086935 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
6936}
6937
bncd16676a2016-07-20 16:23:016938TEST_F(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:086939 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
6940}
6941
bncd16676a2016-07-20 16:23:016942TEST_F(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:086943 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
6944}
6945
bncd16676a2016-07-20 16:23:016946TEST_F(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:086947 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
6948}
6949
bncd16676a2016-07-20 16:23:016950TEST_F(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:086951 ConnectStatusHelper(
6952 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
6953}
6954
bncd16676a2016-07-20 16:23:016955TEST_F(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:086956 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
6957}
6958
bncd16676a2016-07-20 16:23:016959TEST_F(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:086960 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
6961}
6962
bncd16676a2016-07-20 16:23:016963TEST_F(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:086964 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
6965}
6966
bncd16676a2016-07-20 16:23:016967TEST_F(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:086968 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
6969}
6970
bncd16676a2016-07-20 16:23:016971TEST_F(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:086972 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
6973}
6974
bncd16676a2016-07-20 16:23:016975TEST_F(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:086976 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
6977}
6978
bncd16676a2016-07-20 16:23:016979TEST_F(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:086980 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
6981}
6982
[email protected]038e9a32008-10-08 22:40:166983// Test the flow when both the proxy server AND origin server require
6984// authentication. Again, this uses basic auth for both since that is
6985// the simplest to mock.
bncd16676a2016-07-20 16:23:016986TEST_F(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:276987 HttpRequestInfo request;
6988 request.method = "GET";
bncce36dca22015-04-21 22:11:236989 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:106990 request.traffic_annotation =
6991 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:276992
[email protected]038e9a32008-10-08 22:40:166993 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496994 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6995 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:096996 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:076997
bnc691fda62016-08-12 00:43:166998 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]038e9a32008-10-08 22:40:166999
[email protected]f9ee6b52008-11-08 06:46:237000 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237001 MockWrite(
7002 "GET http://www.example.org/ HTTP/1.1\r\n"
7003 "Host: www.example.org\r\n"
7004 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237005 };
7006
[email protected]038e9a32008-10-08 22:40:167007 MockRead data_reads1[] = {
7008 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
7009 // Give a couple authenticate options (only the middle one is actually
7010 // supported).
[email protected]22927ad2009-09-21 19:56:197011 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:167012 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7013 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
7014 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7015 // Large content-length -- won't matter, as connection will be reset.
7016 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067017 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:167018 };
7019
bnc691fda62016-08-12 00:43:167020 // After calling trans.RestartWithAuth() the first time, this is the
[email protected]038e9a32008-10-08 22:40:167021 // request we should be issuing -- the final header line contains the
7022 // proxy's credentials.
7023 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237024 MockWrite(
7025 "GET http://www.example.org/ HTTP/1.1\r\n"
7026 "Host: www.example.org\r\n"
7027 "Proxy-Connection: keep-alive\r\n"
7028 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:167029 };
7030
7031 // Now the proxy server lets the request pass through to origin server.
7032 // The origin server responds with a 401.
7033 MockRead data_reads2[] = {
7034 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7035 // Note: We are using the same realm-name as the proxy server. This is
7036 // completely valid, as realms are unique across hosts.
7037 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7038 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7039 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067040 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:167041 };
7042
bnc691fda62016-08-12 00:43:167043 // After calling trans.RestartWithAuth() the second time, we should send
[email protected]038e9a32008-10-08 22:40:167044 // the credentials for both the proxy and origin server.
7045 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237046 MockWrite(
7047 "GET http://www.example.org/ HTTP/1.1\r\n"
7048 "Host: www.example.org\r\n"
7049 "Proxy-Connection: keep-alive\r\n"
7050 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
7051 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:167052 };
7053
7054 // Lastly we get the desired content.
7055 MockRead data_reads3[] = {
7056 MockRead("HTTP/1.0 200 OK\r\n"),
7057 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7058 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067059 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:167060 };
7061
Ryan Sleevib8d7ea02018-05-07 20:01:017062 StaticSocketDataProvider data1(data_reads1, data_writes1);
7063 StaticSocketDataProvider data2(data_reads2, data_writes2);
7064 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]bb88e1d32013-05-03 23:11:077065 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7066 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7067 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:167068
[email protected]49639fa2011-12-20 23:22:417069 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:167070
tfarina42834112016-09-22 13:38:207071 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017072 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:167073
7074 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017075 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:167076
bnc691fda62016-08-12 00:43:167077 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527078 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047079 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:167080
[email protected]49639fa2011-12-20 23:22:417081 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:167082
bnc691fda62016-08-12 00:43:167083 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:017084 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:167085
7086 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017087 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:167088
bnc691fda62016-08-12 00:43:167089 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527090 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047091 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:167092
[email protected]49639fa2011-12-20 23:22:417093 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:167094
bnc691fda62016-08-12 00:43:167095 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
7096 callback3.callback());
robpercival214763f2016-07-01 23:27:017097 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:167098
7099 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017100 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:167101
bnc691fda62016-08-12 00:43:167102 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527103 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:167104 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:167105}
[email protected]4ddaf2502008-10-23 18:26:197106
[email protected]ea9dc9a2009-09-05 00:43:327107// For the NTLM implementation using SSPI, we skip the NTLM tests since we
7108// can't hook into its internals to cause it to generate predictable NTLM
7109// authorization headers.
7110#if defined(NTLM_PORTABLE)
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377111// The NTLM authentication unit tests are based on known test data from the
7112// [MS-NLMP] Specification [1]. These tests are primarily of the authentication
7113// flow rather than the implementation of the NTLM protocol. See net/ntlm
7114// for the implementation and testing of the protocol.
7115//
7116// [1] https://msdn.microsoft.com/en-us/library/cc236621.aspx
[email protected]385a4672009-03-11 22:21:297117
7118// Enter the correct password and authenticate successfully.
Zentaro Kavanagh1890a3d2018-01-29 19:52:557119TEST_F(HttpNetworkTransactionTest, NTLMAuthV2) {
[email protected]1c773ea12009-04-28 19:58:427120 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:247121 request.method = "GET";
Zentaro Kavanagh1890a3d2018-01-29 19:52:557122 request.url = GURL("https://server/kids/login.aspx");
Ramin Halavatib5e433e2018-02-07 07:41:107123 request.traffic_annotation =
7124 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2217aa22013-10-11 03:03:547125
7126 // Ensure load is not disrupted by flags which suppress behaviour specific
7127 // to other auth schemes.
7128 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:247129
Zentaro Kavanagh6ccee512017-09-28 18:34:097130 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
7131 MockGetMSTime, MockGenerateRandom, MockGetHostName);
danakj1fd259a02016-04-16 03:17:097132 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277133
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377134 // Generate the NTLM messages based on known test data.
7135 std::string negotiate_msg;
7136 std::string challenge_msg;
7137 std::string authenticate_msg;
7138 base::Base64Encode(
7139 base::StringPiece(
7140 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
Avi Drissman4365a4782018-12-28 19:26:247141 base::size(ntlm::test::kExpectedNegotiateMsg)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377142 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:557143 base::Base64Encode(
7144 base::StringPiece(
7145 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
Avi Drissman4365a4782018-12-28 19:26:247146 base::size(ntlm::test::kChallengeMsgFromSpecV2)),
Zentaro Kavanagh1890a3d2018-01-29 19:52:557147 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377148 base::Base64Encode(
7149 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:097150 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557151 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
Avi Drissman4365a4782018-12-28 19:26:247152 base::size(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557153 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377154 &authenticate_msg);
7155
[email protected]3f918782009-02-28 01:29:247156 MockWrite data_writes1[] = {
Zentaro Kavanagh1890a3d2018-01-29 19:52:557157 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
7158 "Host: server\r\n"
7159 "Connection: keep-alive\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:247160 };
7161
7162 MockRead data_reads1[] = {
7163 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:047164 // Negotiate and NTLM are often requested together. However, we only want
7165 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
7166 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:247167 MockRead("WWW-Authenticate: NTLM\r\n"),
7168 MockRead("Connection: close\r\n"),
7169 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:367170 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:247171 // Missing content -- won't matter, as connection will be reset.
[email protected]3f918782009-02-28 01:29:247172 };
7173
7174 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:167175 // After restarting with a null identity, this is the
7176 // request we should be issuing -- the final header line contains a Type
7177 // 1 message.
7178 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557179 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167180 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377181 "Authorization: NTLM "),
7182 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:247183
bnc691fda62016-08-12 00:43:167184 // After calling trans.RestartWithAuth(), we should send a Type 3 message
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377185 // (using correct credentials). The second request continues on the
7186 // same connection.
bnc691fda62016-08-12 00:43:167187 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557188 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167189 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377190 "Authorization: NTLM "),
7191 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:247192 };
7193
7194 MockRead data_reads2[] = {
Bence Béky1e4ef192017-09-18 19:58:027195 // The origin server responds with a Type 2 message.
7196 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377197 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
7198 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky1e4ef192017-09-18 19:58:027199 MockRead("Content-Type: text/html\r\n\r\n"),
7200 MockRead("You are not authorized to view this page\r\n"),
[email protected]3f918782009-02-28 01:29:247201
Bence Béky1e4ef192017-09-18 19:58:027202 // Lastly we get the desired content.
7203 MockRead("HTTP/1.1 200 OK\r\n"),
7204 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
7205 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
[email protected]3f918782009-02-28 01:29:247206 };
7207
Ryan Sleevib8d7ea02018-05-07 20:01:017208 StaticSocketDataProvider data1(data_reads1, data_writes1);
7209 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:077210 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7211 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:247212
Bence Béky83eb3512017-09-05 12:56:097213 SSLSocketDataProvider ssl1(ASYNC, OK);
7214 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
7215 SSLSocketDataProvider ssl2(ASYNC, OK);
7216 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
7217
[email protected]49639fa2011-12-20 23:22:417218 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:247219
bnc691fda62016-08-12 00:43:167220 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:507221
tfarina42834112016-09-22 13:38:207222 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017223 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:247224
7225 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017226 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:247227
bnc691fda62016-08-12 00:43:167228 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227229
bnc691fda62016-08-12 00:43:167230 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527231 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047232 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:247233
[email protected]49639fa2011-12-20 23:22:417234 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:257235
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377236 rv = trans.RestartWithAuth(
7237 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
7238 callback2.callback());
robpercival214763f2016-07-01 23:27:017239 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:257240
7241 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017242 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:257243
bnc691fda62016-08-12 00:43:167244 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:257245
bnc691fda62016-08-12 00:43:167246 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527247 ASSERT_TRUE(response);
7248 EXPECT_FALSE(response->auth_challenge);
[email protected]10af5fe72011-01-31 16:17:257249
[email protected]49639fa2011-12-20 23:22:417250 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:247251
bnc691fda62016-08-12 00:43:167252 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:017253 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:247254
[email protected]0757e7702009-03-27 04:00:227255 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017256 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:247257
bnc691fda62016-08-12 00:43:167258 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527259 ASSERT_TRUE(response);
7260 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:027261 EXPECT_EQ(14, response->headers->GetContentLength());
7262
7263 std::string response_data;
7264 rv = ReadTransaction(&trans, &response_data);
7265 EXPECT_THAT(rv, IsOk());
7266 EXPECT_EQ("Please Login\r\n", response_data);
7267
7268 EXPECT_TRUE(data1.AllReadDataConsumed());
7269 EXPECT_TRUE(data1.AllWriteDataConsumed());
7270 EXPECT_TRUE(data2.AllReadDataConsumed());
7271 EXPECT_TRUE(data2.AllWriteDataConsumed());
[email protected]3f918782009-02-28 01:29:247272}
7273
[email protected]385a4672009-03-11 22:21:297274// Enter a wrong password, and then the correct one.
Zentaro Kavanagh1890a3d2018-01-29 19:52:557275TEST_F(HttpNetworkTransactionTest, NTLMAuthV2WrongThenRightPassword) {
[email protected]1c773ea12009-04-28 19:58:427276 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:297277 request.method = "GET";
Zentaro Kavanagh1890a3d2018-01-29 19:52:557278 request.url = GURL("https://server/kids/login.aspx");
Ramin Halavatib5e433e2018-02-07 07:41:107279 request.traffic_annotation =
7280 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]385a4672009-03-11 22:21:297281
Zentaro Kavanagh6ccee512017-09-28 18:34:097282 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
7283 MockGetMSTime, MockGenerateRandom, MockGetHostName);
danakj1fd259a02016-04-16 03:17:097284 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277285
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377286 // Generate the NTLM messages based on known test data.
7287 std::string negotiate_msg;
7288 std::string challenge_msg;
7289 std::string authenticate_msg;
7290 base::Base64Encode(
7291 base::StringPiece(
7292 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
Avi Drissman4365a4782018-12-28 19:26:247293 base::size(ntlm::test::kExpectedNegotiateMsg)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377294 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:557295 base::Base64Encode(
7296 base::StringPiece(
7297 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
Avi Drissman4365a4782018-12-28 19:26:247298 base::size(ntlm::test::kChallengeMsgFromSpecV2)),
Zentaro Kavanagh1890a3d2018-01-29 19:52:557299 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377300 base::Base64Encode(
7301 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:097302 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557303 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
Avi Drissman4365a4782018-12-28 19:26:247304 base::size(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557305 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377306 &authenticate_msg);
7307
7308 // The authenticate message when |kWrongPassword| is sent.
7309 std::string wrong_password_authenticate_msg(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557310 "TlRMTVNTUAADAAAAGAAYAFgAAACKAIoAcAAAAAwADAD6AAAACAAIAAYBAAAQABAADgEAAAAA"
7311 "AABYAAAAA4IIAAAAAAAAAAAAAPknEYqtJQtusopDRSfYzAAAAAAAAAAAAAAAAAAAAAAAAAAA"
7312 "AAAAAOtVz38osnFdRRggUQHUJ3EBAQAAAAAAAIALyP0A1NIBqqqqqqqqqqoAAAAAAgAMAEQA"
7313 "bwBtAGEAaQBuAAEADABTAGUAcgB2AGUAcgAGAAQAAgAAAAoAEAAAAAAAAAAAAAAAAAAAAAAA"
7314 "CQAWAEgAVABUAFAALwBzAGUAcgB2AGUAcgAAAAAAAAAAAEQAbwBtAGEAaQBuAFUAcwBlAHIA"
7315 "QwBPAE0AUABVAFQARQBSAA==");
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377316
Zentaro Kavanagh1890a3d2018-01-29 19:52:557317 // Sanity check that it's the same length as the correct authenticate message
7318 // and that it's different.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377319 ASSERT_EQ(authenticate_msg.length(),
7320 wrong_password_authenticate_msg.length());
Zentaro Kavanagh1890a3d2018-01-29 19:52:557321 ASSERT_NE(authenticate_msg, wrong_password_authenticate_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377322
[email protected]385a4672009-03-11 22:21:297323 MockWrite data_writes1[] = {
Zentaro Kavanagh1890a3d2018-01-29 19:52:557324 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
7325 "Host: server\r\n"
7326 "Connection: keep-alive\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297327 };
7328
7329 MockRead data_reads1[] = {
7330 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:047331 // Negotiate and NTLM are often requested together. However, we only want
7332 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
7333 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:297334 MockRead("WWW-Authenticate: NTLM\r\n"),
7335 MockRead("Connection: close\r\n"),
7336 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:367337 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297338 // Missing content -- won't matter, as connection will be reset.
[email protected]385a4672009-03-11 22:21:297339 };
7340
7341 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:167342 // After restarting with a null identity, this is the
7343 // request we should be issuing -- the final header line contains a Type
7344 // 1 message.
7345 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557346 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167347 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377348 "Authorization: NTLM "),
7349 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297350
bnc691fda62016-08-12 00:43:167351 // After calling trans.RestartWithAuth(), we should send a Type 3 message
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377352 // (using incorrect credentials). The second request continues on the
7353 // same connection.
bnc691fda62016-08-12 00:43:167354 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557355 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167356 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377357 "Authorization: NTLM "),
7358 MockWrite(wrong_password_authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297359 };
7360
7361 MockRead data_reads2[] = {
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377362 // The origin server responds with a Type 2 message.
7363 MockRead("HTTP/1.1 401 Access Denied\r\n"),
7364 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
7365 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
7366 MockRead("Content-Type: text/html\r\n\r\n"),
7367 MockRead("You are not authorized to view this page\r\n"),
[email protected]385a4672009-03-11 22:21:297368
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377369 // Wrong password.
7370 MockRead("HTTP/1.1 401 Access Denied\r\n"),
7371 MockRead("WWW-Authenticate: NTLM\r\n"), MockRead("Connection: close\r\n"),
7372 MockRead("Content-Length: 42\r\n"),
7373 MockRead("Content-Type: text/html\r\n\r\n"),
7374 // Missing content -- won't matter, as connection will be reset.
[email protected]385a4672009-03-11 22:21:297375 };
7376
7377 MockWrite data_writes3[] = {
bnc691fda62016-08-12 00:43:167378 // After restarting with a null identity, this is the
7379 // request we should be issuing -- the final header line contains a Type
7380 // 1 message.
7381 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557382 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167383 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377384 "Authorization: NTLM "),
7385 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297386
bnc691fda62016-08-12 00:43:167387 // After calling trans.RestartWithAuth(), we should send a Type 3 message
7388 // (the credentials for the origin server). The second request continues
7389 // on the same connection.
7390 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557391 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167392 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377393 "Authorization: NTLM "),
7394 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297395 };
7396
7397 MockRead data_reads3[] = {
Bence Béky1e4ef192017-09-18 19:58:027398 // The origin server responds with a Type 2 message.
7399 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377400 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
7401 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky1e4ef192017-09-18 19:58:027402 MockRead("Content-Type: text/html\r\n\r\n"),
7403 MockRead("You are not authorized to view this page\r\n"),
[email protected]385a4672009-03-11 22:21:297404
Bence Béky1e4ef192017-09-18 19:58:027405 // Lastly we get the desired content.
7406 MockRead("HTTP/1.1 200 OK\r\n"),
7407 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
7408 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
[email protected]385a4672009-03-11 22:21:297409 };
7410
Ryan Sleevib8d7ea02018-05-07 20:01:017411 StaticSocketDataProvider data1(data_reads1, data_writes1);
7412 StaticSocketDataProvider data2(data_reads2, data_writes2);
7413 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]bb88e1d32013-05-03 23:11:077414 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7415 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7416 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:297417
Bence Béky83eb3512017-09-05 12:56:097418 SSLSocketDataProvider ssl1(ASYNC, OK);
7419 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
7420 SSLSocketDataProvider ssl2(ASYNC, OK);
7421 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
7422 SSLSocketDataProvider ssl3(ASYNC, OK);
7423 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
7424
[email protected]49639fa2011-12-20 23:22:417425 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:297426
bnc691fda62016-08-12 00:43:167427 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:507428
tfarina42834112016-09-22 13:38:207429 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017430 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:297431
7432 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017433 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:297434
bnc691fda62016-08-12 00:43:167435 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:297436
bnc691fda62016-08-12 00:43:167437 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527438 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047439 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:297440
[email protected]49639fa2011-12-20 23:22:417441 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:297442
[email protected]0757e7702009-03-27 04:00:227443 // Enter the wrong password.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377444 rv = trans.RestartWithAuth(
7445 AuthCredentials(ntlm::test::kDomainUserCombined, kWrongPassword),
7446 callback2.callback());
robpercival214763f2016-07-01 23:27:017447 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:297448
[email protected]10af5fe72011-01-31 16:17:257449 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017450 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:297451
bnc691fda62016-08-12 00:43:167452 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:417453 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:167454 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:017455 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:257456 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017457 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167458 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227459
bnc691fda62016-08-12 00:43:167460 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527461 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047462 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:227463
[email protected]49639fa2011-12-20 23:22:417464 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:227465
7466 // Now enter the right password.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377467 rv = trans.RestartWithAuth(
7468 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
7469 callback4.callback());
robpercival214763f2016-07-01 23:27:017470 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:257471
7472 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:017473 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:257474
bnc691fda62016-08-12 00:43:167475 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:257476
[email protected]49639fa2011-12-20 23:22:417477 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:257478
7479 // One more roundtrip
bnc691fda62016-08-12 00:43:167480 rv = trans.RestartWithAuth(AuthCredentials(), callback5.callback());
robpercival214763f2016-07-01 23:27:017481 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:227482
7483 rv = callback5.WaitForResult();
robpercival214763f2016-07-01 23:27:017484 EXPECT_THAT(rv, IsOk());
[email protected]0757e7702009-03-27 04:00:227485
bnc691fda62016-08-12 00:43:167486 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527487 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:027488 EXPECT_EQ(14, response->headers->GetContentLength());
7489
7490 std::string response_data;
7491 rv = ReadTransaction(&trans, &response_data);
7492 EXPECT_THAT(rv, IsOk());
7493 EXPECT_EQ("Please Login\r\n", response_data);
7494
7495 EXPECT_TRUE(data1.AllReadDataConsumed());
7496 EXPECT_TRUE(data1.AllWriteDataConsumed());
7497 EXPECT_TRUE(data2.AllReadDataConsumed());
7498 EXPECT_TRUE(data2.AllWriteDataConsumed());
7499 EXPECT_TRUE(data3.AllReadDataConsumed());
7500 EXPECT_TRUE(data3.AllWriteDataConsumed());
[email protected]385a4672009-03-11 22:21:297501}
Bence Béky83eb3512017-09-05 12:56:097502
Bence Béky3238f2e12017-09-22 22:44:497503// Server requests NTLM authentication, which is not supported over HTTP/2.
7504// Subsequent request with authorization header should be sent over HTTP/1.1.
Bence Béky83eb3512017-09-05 12:56:097505TEST_F(HttpNetworkTransactionTest, NTLMOverHttp2) {
Zentaro Kavanagh6ccee512017-09-28 18:34:097506 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
7507 MockGetMSTime, MockGenerateRandom, MockGetHostName);
Bence Béky83eb3512017-09-05 12:56:097508
Zentaro Kavanagh1890a3d2018-01-29 19:52:557509 const char* kUrl = "https://server/kids/login.aspx";
Bence Béky83eb3512017-09-05 12:56:097510
7511 HttpRequestInfo request;
7512 request.method = "GET";
7513 request.url = GURL(kUrl);
Ramin Halavatib5e433e2018-02-07 07:41:107514 request.traffic_annotation =
7515 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Béky83eb3512017-09-05 12:56:097516
7517 // First request without credentials.
Ryan Hamilton0239aac2018-05-19 00:03:137518 spdy::SpdyHeaderBlock request_headers0(
7519 spdy_util_.ConstructGetHeaderBlock(kUrl));
7520 spdy::SpdySerializedFrame request0(spdy_util_.ConstructSpdyHeaders(
Bence Béky83eb3512017-09-05 12:56:097521 1, std::move(request_headers0), LOWEST, true));
7522
Ryan Hamilton0239aac2018-05-19 00:03:137523 spdy::SpdyHeaderBlock response_headers0;
7524 response_headers0[spdy::kHttp2StatusHeader] = "401";
Bence Béky83eb3512017-09-05 12:56:097525 response_headers0["www-authenticate"] = "NTLM";
Ryan Hamilton0239aac2018-05-19 00:03:137526 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyResponseHeaders(
Bence Béky83eb3512017-09-05 12:56:097527 1, std::move(response_headers0), true));
7528
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377529 // Stream 1 is closed.
7530 spdy_util_.UpdateWithStreamDestruction(1);
7531
7532 // Generate the NTLM messages based on known test data.
7533 std::string negotiate_msg;
7534 std::string challenge_msg;
7535 std::string authenticate_msg;
7536 base::Base64Encode(
7537 base::StringPiece(
7538 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
Avi Drissman4365a4782018-12-28 19:26:247539 base::size(ntlm::test::kExpectedNegotiateMsg)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377540 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:557541 base::Base64Encode(
7542 base::StringPiece(
7543 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
Avi Drissman4365a4782018-12-28 19:26:247544 base::size(ntlm::test::kChallengeMsgFromSpecV2)),
Zentaro Kavanagh1890a3d2018-01-29 19:52:557545 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377546 base::Base64Encode(
7547 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:097548 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557549 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
Avi Drissman4365a4782018-12-28 19:26:247550 base::size(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557551 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377552 &authenticate_msg);
7553
7554 // Retry with authorization header.
Ryan Hamilton0239aac2018-05-19 00:03:137555 spdy::SpdyHeaderBlock request_headers1(
7556 spdy_util_.ConstructGetHeaderBlock(kUrl));
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377557 request_headers1["authorization"] = std::string("NTLM ") + negotiate_msg;
Ryan Hamilton0239aac2018-05-19 00:03:137558 spdy::SpdySerializedFrame request1(spdy_util_.ConstructSpdyHeaders(
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377559 3, std::move(request_headers1), LOWEST, true));
7560
Ryan Hamilton0239aac2018-05-19 00:03:137561 spdy::SpdySerializedFrame rst(
7562 spdy_util_.ConstructSpdyRstStream(3, spdy::ERROR_CODE_HTTP_1_1_REQUIRED));
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377563
Bence Béky3238f2e12017-09-22 22:44:497564 MockWrite writes0[] = {CreateMockWrite(request0, 0)};
7565 MockRead reads0[] = {CreateMockRead(resp, 1), MockRead(ASYNC, 0, 2)};
Bence Béky83eb3512017-09-05 12:56:097566
7567 // Retry yet again using HTTP/1.1.
7568 MockWrite writes1[] = {
7569 // After restarting with a null identity, this is the
7570 // request we should be issuing -- the final header line contains a Type
7571 // 1 message.
7572 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557573 "Host: server\r\n"
Bence Béky83eb3512017-09-05 12:56:097574 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377575 "Authorization: NTLM "),
7576 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
Bence Béky83eb3512017-09-05 12:56:097577
7578 // After calling trans.RestartWithAuth(), we should send a Type 3 message
7579 // (the credentials for the origin server). The second request continues
7580 // on the same connection.
7581 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557582 "Host: server\r\n"
Bence Béky83eb3512017-09-05 12:56:097583 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377584 "Authorization: NTLM "),
7585 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
Bence Béky83eb3512017-09-05 12:56:097586 };
7587
7588 MockRead reads1[] = {
7589 // The origin server responds with a Type 2 message.
7590 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377591 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
7592 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky83eb3512017-09-05 12:56:097593 MockRead("Content-Type: text/html\r\n\r\n"),
7594 MockRead("You are not authorized to view this page\r\n"),
7595
7596 // Lastly we get the desired content.
7597 MockRead("HTTP/1.1 200 OK\r\n"),
7598 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
Bence Béky1e4ef192017-09-18 19:58:027599 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
Bence Béky83eb3512017-09-05 12:56:097600 };
Ryan Sleevib8d7ea02018-05-07 20:01:017601 SequencedSocketData data0(reads0, writes0);
7602 StaticSocketDataProvider data1(reads1, writes1);
Bence Béky83eb3512017-09-05 12:56:097603 session_deps_.socket_factory->AddSocketDataProvider(&data0);
7604 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7605
7606 SSLSocketDataProvider ssl0(ASYNC, OK);
7607 ssl0.next_proto = kProtoHTTP2;
7608 SSLSocketDataProvider ssl1(ASYNC, OK);
7609 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl0);
7610 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
7611
7612 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7613 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
7614
7615 TestCompletionCallback callback1;
7616 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
7617 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7618
7619 rv = callback1.WaitForResult();
7620 EXPECT_THAT(rv, IsOk());
7621
7622 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
7623
7624 const HttpResponseInfo* response = trans.GetResponseInfo();
7625 ASSERT_TRUE(response);
7626 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
7627
7628 TestCompletionCallback callback2;
7629
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377630 rv = trans.RestartWithAuth(
7631 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
7632 callback2.callback());
Bence Béky83eb3512017-09-05 12:56:097633 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7634
7635 rv = callback2.WaitForResult();
7636 EXPECT_THAT(rv, IsOk());
7637
7638 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
7639
7640 response = trans.GetResponseInfo();
7641 ASSERT_TRUE(response);
7642 EXPECT_FALSE(response->auth_challenge);
7643
7644 TestCompletionCallback callback3;
7645
7646 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
7647 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7648
7649 rv = callback3.WaitForResult();
7650 EXPECT_THAT(rv, IsOk());
7651
7652 response = trans.GetResponseInfo();
7653 ASSERT_TRUE(response);
7654 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:027655 EXPECT_EQ(14, response->headers->GetContentLength());
7656
7657 std::string response_data;
7658 rv = ReadTransaction(&trans, &response_data);
7659 EXPECT_THAT(rv, IsOk());
7660 EXPECT_EQ("Please Login\r\n", response_data);
7661
7662 EXPECT_TRUE(data0.AllReadDataConsumed());
7663 EXPECT_TRUE(data0.AllWriteDataConsumed());
7664 EXPECT_TRUE(data1.AllReadDataConsumed());
7665 EXPECT_TRUE(data1.AllWriteDataConsumed());
Bence Béky83eb3512017-09-05 12:56:097666}
David Benjamin5cb91132018-04-06 05:54:497667
7668// Test that, if we have an NTLM proxy and the origin resets the connection, we
7669// do no retry forever checking for TLS version interference. This is a
7670// regression test for https://crbug.com/823387.
7671TEST_F(HttpNetworkTransactionTest, NTLMProxyTLSHandshakeReset) {
7672 // The NTLM test data expects the proxy to be named 'server'. The origin is
7673 // https://origin/.
7674 session_deps_.proxy_resolution_service =
7675 ProxyResolutionService::CreateFixedFromPacResult(
7676 "PROXY server", TRAFFIC_ANNOTATION_FOR_TESTS);
7677
7678 SSLConfig config;
David Benjamin5cb91132018-04-06 05:54:497679 session_deps_.ssl_config_service =
Ryan Sleevib8449e02018-07-15 04:31:077680 std::make_unique<TestSSLConfigService>(config);
David Benjamin5cb91132018-04-06 05:54:497681
7682 HttpRequestInfo request;
7683 request.method = "GET";
7684 request.url = GURL("https://origin/");
7685 request.traffic_annotation =
7686 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7687
7688 // Ensure load is not disrupted by flags which suppress behaviour specific
7689 // to other auth schemes.
7690 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
7691
7692 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
7693 MockGetMSTime, MockGenerateRandom, MockGetHostName);
7694 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7695
7696 // Generate the NTLM messages based on known test data.
7697 std::string negotiate_msg;
7698 std::string challenge_msg;
7699 std::string authenticate_msg;
7700 base::Base64Encode(
7701 base::StringPiece(
7702 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
Avi Drissman4365a4782018-12-28 19:26:247703 base::size(ntlm::test::kExpectedNegotiateMsg)),
David Benjamin5cb91132018-04-06 05:54:497704 &negotiate_msg);
7705 base::Base64Encode(
7706 base::StringPiece(
7707 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
Avi Drissman4365a4782018-12-28 19:26:247708 base::size(ntlm::test::kChallengeMsgFromSpecV2)),
David Benjamin5cb91132018-04-06 05:54:497709 &challenge_msg);
7710 base::Base64Encode(
7711 base::StringPiece(
7712 reinterpret_cast<const char*>(
7713 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
Avi Drissman4365a4782018-12-28 19:26:247714 base::size(
David Benjamin5cb91132018-04-06 05:54:497715 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
7716 &authenticate_msg);
7717
7718 MockWrite data_writes[] = {
7719 // The initial CONNECT request.
7720 MockWrite("CONNECT origin:443 HTTP/1.1\r\n"
7721 "Host: origin:443\r\n"
7722 "Proxy-Connection: keep-alive\r\n\r\n"),
7723
7724 // After restarting with an identity.
7725 MockWrite("CONNECT origin:443 HTTP/1.1\r\n"
7726 "Host: origin:443\r\n"
7727 "Proxy-Connection: keep-alive\r\n"
7728 "Proxy-Authorization: NTLM "),
7729 MockWrite(negotiate_msg.c_str()),
7730 // End headers.
7731 MockWrite("\r\n\r\n"),
7732
7733 // The second restart.
7734 MockWrite("CONNECT origin:443 HTTP/1.1\r\n"
7735 "Host: origin:443\r\n"
7736 "Proxy-Connection: keep-alive\r\n"
7737 "Proxy-Authorization: NTLM "),
7738 MockWrite(authenticate_msg.c_str()),
7739 // End headers.
7740 MockWrite("\r\n\r\n"),
7741 };
7742
7743 MockRead data_reads[] = {
7744 // The initial NTLM response.
7745 MockRead("HTTP/1.1 407 Access Denied\r\n"
7746 "Content-Length: 0\r\n"
7747 "Proxy-Authenticate: NTLM\r\n\r\n"),
7748
7749 // The NTLM challenge message.
7750 MockRead("HTTP/1.1 407 Access Denied\r\n"
7751 "Content-Length: 0\r\n"
7752 "Proxy-Authenticate: NTLM "),
7753 MockRead(challenge_msg.c_str()),
7754 // End headers.
7755 MockRead("\r\n\r\n"),
7756
7757 // Finally the tunnel is established.
7758 MockRead("HTTP/1.1 200 Connected\r\n\r\n"),
7759 };
7760
Ryan Sleevib8d7ea02018-05-07 20:01:017761 StaticSocketDataProvider data(data_reads, data_writes);
David Benjamin5cb91132018-04-06 05:54:497762 SSLSocketDataProvider data_ssl(ASYNC, ERR_CONNECTION_RESET);
Ryan Sleevib8d7ea02018-05-07 20:01:017763 StaticSocketDataProvider data2(data_reads, data_writes);
David Benjamin5cb91132018-04-06 05:54:497764 SSLSocketDataProvider data_ssl2(ASYNC, ERR_CONNECTION_RESET);
Steven Valdez0ef94d02018-11-19 23:28:137765 data_ssl2.expected_ssl_version_max = SSL_PROTOCOL_VERSION_TLS1_2;
David Benjamin5cb91132018-04-06 05:54:497766 session_deps_.socket_factory->AddSocketDataProvider(&data);
7767 session_deps_.socket_factory->AddSSLSocketDataProvider(&data_ssl);
7768 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7769 session_deps_.socket_factory->AddSSLSocketDataProvider(&data_ssl2);
7770
7771 // Start the transaction. The proxy responds with an NTLM authentication
7772 // request.
7773 TestCompletionCallback callback;
7774 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
7775 int rv = callback.GetResult(
7776 trans.Start(&request, callback.callback(), NetLogWithSource()));
7777
7778 EXPECT_THAT(rv, IsOk());
7779 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
7780 const HttpResponseInfo* response = trans.GetResponseInfo();
7781 ASSERT_TRUE(response);
7782 EXPECT_TRUE(CheckNTLMProxyAuth(response->auth_challenge.get()));
7783
7784 // Configure credentials. The proxy responds with the challenge message.
7785 rv = callback.GetResult(trans.RestartWithAuth(
7786 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
7787 callback.callback()));
7788 EXPECT_THAT(rv, IsOk());
7789 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
7790 response = trans.GetResponseInfo();
7791 ASSERT_TRUE(response);
7792 EXPECT_FALSE(response->auth_challenge);
7793
7794 // Restart once more. The tunnel will be established and the the SSL handshake
7795 // will reset. The TLS 1.3 version interference probe will then kick in and
7796 // restart the process. The proxy responds with another NTLM authentiation
7797 // request, but we don't need to provide credentials as the cached ones work/
7798 rv = callback.GetResult(
7799 trans.RestartWithAuth(AuthCredentials(), callback.callback()));
7800 EXPECT_THAT(rv, IsOk());
7801 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
7802 response = trans.GetResponseInfo();
7803 ASSERT_TRUE(response);
7804 EXPECT_FALSE(response->auth_challenge);
7805
7806 // The proxy responds with the NTLM challenge message.
7807 rv = callback.GetResult(
7808 trans.RestartWithAuth(AuthCredentials(), callback.callback()));
7809 EXPECT_THAT(rv, IsOk());
7810 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
7811 response = trans.GetResponseInfo();
7812 ASSERT_TRUE(response);
7813 EXPECT_FALSE(response->auth_challenge);
7814
7815 // Send the NTLM authenticate message. The tunnel is established and the
7816 // handshake resets again. We should not retry again.
7817 rv = callback.GetResult(
7818 trans.RestartWithAuth(AuthCredentials(), callback.callback()));
7819 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
7820}
7821
[email protected]ea9dc9a2009-09-05 00:43:327822#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:297823
[email protected]4ddaf2502008-10-23 18:26:197824// Test reading a server response which has only headers, and no body.
7825// After some maximum number of bytes is consumed, the transaction should
7826// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
bncd16676a2016-07-20 16:23:017827TEST_F(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:427828 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:197829 request.method = "GET";
bncce36dca22015-04-21 22:11:237830 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:107831 request.traffic_annotation =
7832 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]4ddaf2502008-10-23 18:26:197833
danakj1fd259a02016-04-16 03:17:097834 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167835 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277836
[email protected]b75b7b2f2009-10-06 00:54:537837 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:437838 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:537839 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:197840
7841 MockRead data_reads[] = {
7842 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:067843 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:197844 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:067845 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:197846 };
Ryan Sleevib8d7ea02018-05-07 20:01:017847 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:077848 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:197849
[email protected]49639fa2011-12-20 23:22:417850 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:197851
tfarina42834112016-09-22 13:38:207852 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017853 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]4ddaf2502008-10-23 18:26:197854
7855 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017856 EXPECT_THAT(rv, IsError(ERR_RESPONSE_HEADERS_TOO_BIG));
[email protected]4ddaf2502008-10-23 18:26:197857}
[email protected]f4e426b2008-11-05 00:24:497858
7859// Make sure that we don't try to reuse a TCPClientSocket when failing to
7860// establish tunnel.
7861// http://code.google.com/p/chromium/issues/detail?id=3772
bncd16676a2016-07-20 16:23:017862TEST_F(HttpNetworkTransactionTest, DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:277863 HttpRequestInfo request;
7864 request.method = "GET";
bncce36dca22015-04-21 22:11:237865 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:107866 request.traffic_annotation =
7867 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:277868
[email protected]f4e426b2008-11-05 00:24:497869 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:497870 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
7871 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]db8f44c2008-12-13 04:52:017872
danakj1fd259a02016-04-16 03:17:097873 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:497874
bnc87dcefc2017-05-25 12:47:587875 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:197876 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]f4e426b2008-11-05 00:24:497877
[email protected]f4e426b2008-11-05 00:24:497878 // Since we have proxy, should try to establish tunnel.
7879 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:177880 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7881 "Host: www.example.org:443\r\n"
7882 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:497883 };
7884
[email protected]77848d12008-11-14 00:00:227885 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:497886 // connection. Usually a proxy would return 501 (not implemented),
7887 // or 200 (tunnel established).
7888 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:237889 MockRead("HTTP/1.1 404 Not Found\r\n"),
7890 MockRead("Content-Length: 10\r\n\r\n"),
7891 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]f4e426b2008-11-05 00:24:497892 };
7893
Ryan Sleevib8d7ea02018-05-07 20:01:017894 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:077895 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:497896
[email protected]49639fa2011-12-20 23:22:417897 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:497898
tfarina42834112016-09-22 13:38:207899 int rv = trans->Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017900 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f4e426b2008-11-05 00:24:497901
7902 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017903 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]f4e426b2008-11-05 00:24:497904
[email protected]b4404c02009-04-10 16:38:527905 // Empty the current queue. This is necessary because idle sockets are
7906 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557907 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:527908
[email protected]f4e426b2008-11-05 00:24:497909 // We now check to make sure the TCPClientSocket was not added back to
7910 // the pool.
[email protected]90499482013-06-01 00:39:507911 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:497912 trans.reset();
fdoray92e35a72016-06-10 15:54:557913 base::RunLoop().RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:497914 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:507915 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:497916}
[email protected]372d34a2008-11-05 21:30:517917
[email protected]1b157c02009-04-21 01:55:407918// Make sure that we recycle a socket after reading all of the response body.
bncd16676a2016-07-20 16:23:017919TEST_F(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:427920 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:407921 request.method = "GET";
bncce36dca22015-04-21 22:11:237922 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:107923 request.traffic_annotation =
7924 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1b157c02009-04-21 01:55:407925
danakj1fd259a02016-04-16 03:17:097926 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277927
bnc691fda62016-08-12 00:43:167928 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277929
[email protected]1b157c02009-04-21 01:55:407930 MockRead data_reads[] = {
7931 // A part of the response body is received with the response headers.
7932 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
7933 // The rest of the response body is received in two parts.
7934 MockRead("lo"),
7935 MockRead(" world"),
7936 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:067937 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:407938 };
7939
Ryan Sleevib8d7ea02018-05-07 20:01:017940 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:077941 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:407942
[email protected]49639fa2011-12-20 23:22:417943 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:407944
tfarina42834112016-09-22 13:38:207945 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017946 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1b157c02009-04-21 01:55:407947
7948 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017949 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:407950
bnc691fda62016-08-12 00:43:167951 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527952 ASSERT_TRUE(response);
[email protected]1b157c02009-04-21 01:55:407953
wezca1070932016-05-26 20:30:527954 EXPECT_TRUE(response->headers);
[email protected]1b157c02009-04-21 01:55:407955 std::string status_line = response->headers->GetStatusLine();
7956 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
7957
[email protected]90499482013-06-01 00:39:507958 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:407959
7960 std::string response_data;
bnc691fda62016-08-12 00:43:167961 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017962 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:407963 EXPECT_EQ("hello world", response_data);
7964
7965 // Empty the current queue. This is necessary because idle sockets are
7966 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557967 base::RunLoop().RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:407968
7969 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507970 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:407971}
7972
[email protected]76a505b2010-08-25 06:23:007973// Make sure that we recycle a SSL socket after reading all of the response
7974// body.
bncd16676a2016-07-20 16:23:017975TEST_F(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:007976 HttpRequestInfo request;
7977 request.method = "GET";
bncce36dca22015-04-21 22:11:237978 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:107979 request.traffic_annotation =
7980 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:007981
7982 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237983 MockWrite(
7984 "GET / HTTP/1.1\r\n"
7985 "Host: www.example.org\r\n"
7986 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:007987 };
7988
7989 MockRead data_reads[] = {
7990 MockRead("HTTP/1.1 200 OK\r\n"),
7991 MockRead("Content-Length: 11\r\n\r\n"),
7992 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:067993 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:007994 };
7995
[email protected]8ddf8322012-02-23 18:08:067996 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077997 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:007998
Ryan Sleevib8d7ea02018-05-07 20:01:017999 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:078000 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:008001
[email protected]49639fa2011-12-20 23:22:418002 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:008003
danakj1fd259a02016-04-16 03:17:098004 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168005 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:008006
tfarina42834112016-09-22 13:38:208007 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:008008
robpercival214763f2016-07-01 23:27:018009 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8010 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:008011
bnc691fda62016-08-12 00:43:168012 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528013 ASSERT_TRUE(response);
8014 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:008015 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8016
[email protected]90499482013-06-01 00:39:508017 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008018
8019 std::string response_data;
bnc691fda62016-08-12 00:43:168020 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:018021 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:008022 EXPECT_EQ("hello world", response_data);
8023
8024 // Empty the current queue. This is necessary because idle sockets are
8025 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:558026 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:008027
8028 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:508029 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008030}
8031
8032// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
8033// from the pool and make sure that we recover okay.
bncd16676a2016-07-20 16:23:018034TEST_F(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:008035 HttpRequestInfo request;
8036 request.method = "GET";
bncce36dca22015-04-21 22:11:238037 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:108038 request.traffic_annotation =
8039 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:008040
8041 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238042 MockWrite(
8043 "GET / HTTP/1.1\r\n"
8044 "Host: www.example.org\r\n"
8045 "Connection: keep-alive\r\n\r\n"),
8046 MockWrite(
8047 "GET / HTTP/1.1\r\n"
8048 "Host: www.example.org\r\n"
8049 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:008050 };
8051
8052 MockRead data_reads[] = {
mmenke911ee0222015-12-04 03:58:428053 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
8054 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
[email protected]76a505b2010-08-25 06:23:008055
[email protected]8ddf8322012-02-23 18:08:068056 SSLSocketDataProvider ssl(ASYNC, OK);
8057 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078058 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8059 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:008060
Ryan Sleevib8d7ea02018-05-07 20:01:018061 StaticSocketDataProvider data(data_reads, data_writes);
8062 StaticSocketDataProvider data2(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:078063 session_deps_.socket_factory->AddSocketDataProvider(&data);
8064 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:008065
[email protected]49639fa2011-12-20 23:22:418066 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:008067
danakj1fd259a02016-04-16 03:17:098068 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:588069 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:198070 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:008071
tfarina42834112016-09-22 13:38:208072 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:008073
robpercival214763f2016-07-01 23:27:018074 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8075 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:008076
8077 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528078 ASSERT_TRUE(response);
8079 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:008080 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8081
[email protected]90499482013-06-01 00:39:508082 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008083
8084 std::string response_data;
8085 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018086 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:008087 EXPECT_EQ("hello world", response_data);
8088
8089 // Empty the current queue. This is necessary because idle sockets are
8090 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:558091 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:008092
8093 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:508094 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008095
8096 // Now start the second transaction, which should reuse the previous socket.
8097
bnc87dcefc2017-05-25 12:47:588098 trans =
Jeremy Roman0579ed62017-08-29 15:56:198099 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:008100
tfarina42834112016-09-22 13:38:208101 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:008102
robpercival214763f2016-07-01 23:27:018103 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8104 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:008105
8106 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528107 ASSERT_TRUE(response);
8108 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:008109 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8110
[email protected]90499482013-06-01 00:39:508111 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008112
8113 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018114 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:008115 EXPECT_EQ("hello world", response_data);
8116
8117 // Empty the current queue. This is necessary because idle sockets are
8118 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:558119 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:008120
8121 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:508122 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008123}
8124
maksim.sisov0adf8592016-07-15 06:25:568125// Grab a socket, use it, and put it back into the pool. Then, make
8126// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:018127TEST_F(HttpNetworkTransactionTest, FlushSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:568128 HttpRequestInfo request;
8129 request.method = "GET";
8130 request.url = GURL("http://www.example.org/");
8131 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:108132 request.traffic_annotation =
8133 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
maksim.sisov0adf8592016-07-15 06:25:568134
8135 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8136
bnc691fda62016-08-12 00:43:168137 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:568138
8139 MockRead data_reads[] = {
8140 // A part of the response body is received with the response headers.
8141 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
8142 // The rest of the response body is received in two parts.
8143 MockRead("lo"), MockRead(" world"),
8144 MockRead("junk"), // Should not be read!!
8145 MockRead(SYNCHRONOUS, OK),
8146 };
8147
Ryan Sleevib8d7ea02018-05-07 20:01:018148 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
maksim.sisov0adf8592016-07-15 06:25:568149 session_deps_.socket_factory->AddSocketDataProvider(&data);
8150
8151 TestCompletionCallback callback;
8152
tfarina42834112016-09-22 13:38:208153 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:568154 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8155
8156 EXPECT_THAT(callback.GetResult(rv), IsOk());
8157
bnc691fda62016-08-12 00:43:168158 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:568159 ASSERT_TRUE(response);
8160 EXPECT_TRUE(response->headers);
8161 std::string status_line = response->headers->GetStatusLine();
8162 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
8163
8164 // Make memory critical notification and ensure the transaction still has been
8165 // operating right.
8166 base::MemoryPressureListener::NotifyMemoryPressure(
8167 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8168 base::RunLoop().RunUntilIdle();
8169
8170 // Socket should not be flushed as long as it is not idle.
8171 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
8172
8173 std::string response_data;
bnc691fda62016-08-12 00:43:168174 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:568175 EXPECT_THAT(rv, IsOk());
8176 EXPECT_EQ("hello world", response_data);
8177
8178 // Empty the current queue. This is necessary because idle sockets are
8179 // added to the connection pool asynchronously with a PostTask.
8180 base::RunLoop().RunUntilIdle();
8181
8182 // We now check to make sure the socket was added back to the pool.
8183 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
8184
8185 // Idle sockets should be flushed now.
8186 base::MemoryPressureListener::NotifyMemoryPressure(
8187 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8188 base::RunLoop().RunUntilIdle();
8189
8190 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
8191}
8192
yucliu48f235d2018-01-11 00:59:558193// Disable idle socket closing on memory pressure.
8194// Grab a socket, use it, and put it back into the pool. Then, make
8195// low memory notification and ensure the socket pool is NOT flushed.
8196TEST_F(HttpNetworkTransactionTest, NoFlushSocketPoolOnLowMemoryNotifications) {
8197 HttpRequestInfo request;
8198 request.method = "GET";
8199 request.url = GURL("http://www.example.org/");
8200 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:108201 request.traffic_annotation =
8202 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
yucliu48f235d2018-01-11 00:59:558203
8204 // Disable idle socket closing on memory pressure.
8205 session_deps_.disable_idle_sockets_close_on_memory_pressure = true;
8206 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8207
8208 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
8209
8210 MockRead data_reads[] = {
8211 // A part of the response body is received with the response headers.
8212 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
8213 // The rest of the response body is received in two parts.
8214 MockRead("lo"), MockRead(" world"),
8215 MockRead("junk"), // Should not be read!!
8216 MockRead(SYNCHRONOUS, OK),
8217 };
8218
Ryan Sleevib8d7ea02018-05-07 20:01:018219 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
yucliu48f235d2018-01-11 00:59:558220 session_deps_.socket_factory->AddSocketDataProvider(&data);
8221
8222 TestCompletionCallback callback;
8223
8224 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
8225 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8226
8227 EXPECT_THAT(callback.GetResult(rv), IsOk());
8228
8229 const HttpResponseInfo* response = trans.GetResponseInfo();
8230 ASSERT_TRUE(response);
8231 EXPECT_TRUE(response->headers);
8232 std::string status_line = response->headers->GetStatusLine();
8233 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
8234
8235 // Make memory critical notification and ensure the transaction still has been
8236 // operating right.
8237 base::MemoryPressureListener::NotifyMemoryPressure(
8238 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8239 base::RunLoop().RunUntilIdle();
8240
8241 // Socket should not be flushed as long as it is not idle.
8242 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
8243
8244 std::string response_data;
8245 rv = ReadTransaction(&trans, &response_data);
8246 EXPECT_THAT(rv, IsOk());
8247 EXPECT_EQ("hello world", response_data);
8248
8249 // Empty the current queue. This is necessary because idle sockets are
8250 // added to the connection pool asynchronously with a PostTask.
8251 base::RunLoop().RunUntilIdle();
8252
8253 // We now check to make sure the socket was added back to the pool.
8254 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
8255
8256 // Idle sockets should NOT be flushed on moderate memory pressure.
8257 base::MemoryPressureListener::NotifyMemoryPressure(
8258 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE);
8259 base::RunLoop().RunUntilIdle();
8260
8261 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
8262
8263 // Idle sockets should NOT be flushed on critical memory pressure.
8264 base::MemoryPressureListener::NotifyMemoryPressure(
8265 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8266 base::RunLoop().RunUntilIdle();
8267
8268 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
8269}
8270
maksim.sisov0adf8592016-07-15 06:25:568271// Grab an SSL socket, use it, and put it back into the pool. Then, make
8272// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:018273TEST_F(HttpNetworkTransactionTest, FlushSSLSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:568274 HttpRequestInfo request;
8275 request.method = "GET";
8276 request.url = GURL("https://www.example.org/");
8277 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:108278 request.traffic_annotation =
8279 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
maksim.sisov0adf8592016-07-15 06:25:568280
8281 MockWrite data_writes[] = {
8282 MockWrite("GET / HTTP/1.1\r\n"
8283 "Host: www.example.org\r\n"
8284 "Connection: keep-alive\r\n\r\n"),
8285 };
8286
8287 MockRead data_reads[] = {
8288 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
8289 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
8290
8291 SSLSocketDataProvider ssl(ASYNC, OK);
8292 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8293
Ryan Sleevib8d7ea02018-05-07 20:01:018294 StaticSocketDataProvider data(data_reads, data_writes);
maksim.sisov0adf8592016-07-15 06:25:568295 session_deps_.socket_factory->AddSocketDataProvider(&data);
8296
8297 TestCompletionCallback callback;
8298
8299 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168300 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:568301
8302 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
tfarina42834112016-09-22 13:38:208303 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:568304
8305 EXPECT_THAT(callback.GetResult(rv), IsOk());
8306
bnc691fda62016-08-12 00:43:168307 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:568308 ASSERT_TRUE(response);
8309 ASSERT_TRUE(response->headers);
8310 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8311
8312 // Make memory critical notification and ensure the transaction still has been
8313 // operating right.
8314 base::MemoryPressureListener::NotifyMemoryPressure(
8315 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8316 base::RunLoop().RunUntilIdle();
8317
8318 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
8319
8320 std::string response_data;
bnc691fda62016-08-12 00:43:168321 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:568322 EXPECT_THAT(rv, IsOk());
8323 EXPECT_EQ("hello world", response_data);
8324
8325 // Empty the current queue. This is necessary because idle sockets are
8326 // added to the connection pool asynchronously with a PostTask.
8327 base::RunLoop().RunUntilIdle();
8328
8329 // We now check to make sure the socket was added back to the pool.
8330 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
8331
8332 // Make memory notification once again and ensure idle socket is closed.
8333 base::MemoryPressureListener::NotifyMemoryPressure(
8334 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8335 base::RunLoop().RunUntilIdle();
8336
8337 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
8338}
8339
[email protected]b4404c02009-04-10 16:38:528340// Make sure that we recycle a socket after a zero-length response.
8341// http://crbug.com/9880
bncd16676a2016-07-20 16:23:018342TEST_F(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:428343 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:528344 request.method = "GET";
bncce36dca22015-04-21 22:11:238345 request.url = GURL(
8346 "http://www.example.org/csi?v=3&s=web&action=&"
8347 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
8348 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
8349 "rt=prt.2642,ol.2649,xjs.2951");
Ramin Halavatib5e433e2018-02-07 07:41:108350 request.traffic_annotation =
8351 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]b4404c02009-04-10 16:38:528352
danakj1fd259a02016-04-16 03:17:098353 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:278354
[email protected]b4404c02009-04-10 16:38:528355 MockRead data_reads[] = {
8356 MockRead("HTTP/1.1 204 No Content\r\n"
8357 "Content-Length: 0\r\n"
8358 "Content-Type: text/html\r\n\r\n"),
8359 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:068360 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:528361 };
8362
Ryan Sleevib8d7ea02018-05-07 20:01:018363 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:078364 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:528365
mmenkecc2298e2015-12-07 18:20:188366 // Transaction must be created after the MockReads, so it's destroyed before
8367 // them.
bnc691fda62016-08-12 00:43:168368 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkecc2298e2015-12-07 18:20:188369
[email protected]49639fa2011-12-20 23:22:418370 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:528371
tfarina42834112016-09-22 13:38:208372 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018373 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]b4404c02009-04-10 16:38:528374
8375 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018376 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:528377
bnc691fda62016-08-12 00:43:168378 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528379 ASSERT_TRUE(response);
[email protected]b4404c02009-04-10 16:38:528380
wezca1070932016-05-26 20:30:528381 EXPECT_TRUE(response->headers);
[email protected]b4404c02009-04-10 16:38:528382 std::string status_line = response->headers->GetStatusLine();
8383 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
8384
[email protected]90499482013-06-01 00:39:508385 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:528386
8387 std::string response_data;
bnc691fda62016-08-12 00:43:168388 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:018389 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:528390 EXPECT_EQ("", response_data);
8391
8392 // Empty the current queue. This is necessary because idle sockets are
8393 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:558394 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:528395
8396 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:508397 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:528398}
8399
bncd16676a2016-07-20 16:23:018400TEST_F(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
danakj1fd259a02016-04-16 03:17:098401 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:228402 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:198403 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:228404 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:278405
[email protected]1c773ea12009-04-28 19:58:428406 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:518407 // Transaction 1: a GET request that succeeds. The socket is recycled
8408 // after use.
8409 request[0].method = "GET";
8410 request[0].url = GURL("http://www.google.com/");
8411 request[0].load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:108412 request[0].traffic_annotation =
8413 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]372d34a2008-11-05 21:30:518414 // Transaction 2: a POST request. Reuses the socket kept alive from
8415 // transaction 1. The first attempts fails when writing the POST data.
8416 // This causes the transaction to retry with a new socket. The second
8417 // attempt succeeds.
8418 request[1].method = "POST";
8419 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:278420 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:518421 request[1].load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:108422 request[1].traffic_annotation =
8423 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]372d34a2008-11-05 21:30:518424
danakj1fd259a02016-04-16 03:17:098425 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:518426
8427 // The first socket is used for transaction 1 and the first attempt of
8428 // transaction 2.
8429
8430 // The response of transaction 1.
8431 MockRead data_reads1[] = {
8432 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
8433 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068434 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:518435 };
8436 // The mock write results of transaction 1 and the first attempt of
8437 // transaction 2.
8438 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:068439 MockWrite(SYNCHRONOUS, 64), // GET
8440 MockWrite(SYNCHRONOUS, 93), // POST
8441 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:518442 };
Ryan Sleevib8d7ea02018-05-07 20:01:018443 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]372d34a2008-11-05 21:30:518444
8445 // The second socket is used for the second attempt of transaction 2.
8446
8447 // The response of transaction 2.
8448 MockRead data_reads2[] = {
8449 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
8450 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:068451 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:518452 };
8453 // The mock write results of the second attempt of transaction 2.
8454 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:068455 MockWrite(SYNCHRONOUS, 93), // POST
8456 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:518457 };
Ryan Sleevib8d7ea02018-05-07 20:01:018458 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]372d34a2008-11-05 21:30:518459
[email protected]bb88e1d32013-05-03 23:11:078460 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8461 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:518462
thestig9d3bb0c2015-01-24 00:49:518463 const char* const kExpectedResponseData[] = {
[email protected]372d34a2008-11-05 21:30:518464 "hello world", "welcome"
8465 };
8466
8467 for (int i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:168468 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]372d34a2008-11-05 21:30:518469
[email protected]49639fa2011-12-20 23:22:418470 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:518471
tfarina42834112016-09-22 13:38:208472 int rv = trans.Start(&request[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018473 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]372d34a2008-11-05 21:30:518474
8475 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018476 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:518477
bnc691fda62016-08-12 00:43:168478 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528479 ASSERT_TRUE(response);
[email protected]372d34a2008-11-05 21:30:518480
wezca1070932016-05-26 20:30:528481 EXPECT_TRUE(response->headers);
[email protected]372d34a2008-11-05 21:30:518482 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8483
8484 std::string response_data;
bnc691fda62016-08-12 00:43:168485 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:018486 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:518487 EXPECT_EQ(kExpectedResponseData[i], response_data);
8488 }
8489}
[email protected]f9ee6b52008-11-08 06:46:238490
8491// Test the request-challenge-retry sequence for basic auth when there is
8492// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:168493// it fails the identity from the URL is used to answer the challenge.
bncd16676a2016-07-20 16:23:018494TEST_F(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:428495 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238496 request.method = "GET";
bncce36dca22015-04-21 22:11:238497 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:418498 request.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:108499 request.traffic_annotation =
8500 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]a97cca42009-08-14 01:00:298501
danakj1fd259a02016-04-16 03:17:098502 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168503 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278504
[email protected]a97cca42009-08-14 01:00:298505 // The password contains an escaped character -- for this test to pass it
8506 // will need to be unescaped by HttpNetworkTransaction.
8507 EXPECT_EQ("b%40r", request.url.password());
8508
[email protected]f9ee6b52008-11-08 06:46:238509 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238510 MockWrite(
8511 "GET / HTTP/1.1\r\n"
8512 "Host: www.example.org\r\n"
8513 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238514 };
8515
8516 MockRead data_reads1[] = {
8517 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8518 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8519 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068520 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238521 };
8522
[email protected]2262e3a2012-05-22 16:08:168523 // After the challenge above, the transaction will be restarted using the
8524 // identity from the url (foo, b@r) to answer the challenge.
8525 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238526 MockWrite(
8527 "GET / HTTP/1.1\r\n"
8528 "Host: www.example.org\r\n"
8529 "Connection: keep-alive\r\n"
8530 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:168531 };
8532
8533 MockRead data_reads2[] = {
8534 MockRead("HTTP/1.0 200 OK\r\n"),
8535 MockRead("Content-Length: 100\r\n\r\n"),
8536 MockRead(SYNCHRONOUS, OK),
8537 };
8538
Ryan Sleevib8d7ea02018-05-07 20:01:018539 StaticSocketDataProvider data1(data_reads1, data_writes1);
8540 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:078541 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8542 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:238543
[email protected]49639fa2011-12-20 23:22:418544 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:208545 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018546 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238547 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018548 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168549 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:168550
8551 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:168552 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:018553 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:168554 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018555 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168556 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:228557
bnc691fda62016-08-12 00:43:168558 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528559 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:168560
8561 // There is no challenge info, since the identity in URL worked.
wezca1070932016-05-26 20:30:528562 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:168563
8564 EXPECT_EQ(100, response->headers->GetContentLength());
8565
8566 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:558567 base::RunLoop().RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:168568}
8569
8570// Test the request-challenge-retry sequence for basic auth when there is an
8571// incorrect identity in the URL. The identity from the URL should be used only
8572// once.
bncd16676a2016-07-20 16:23:018573TEST_F(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:168574 HttpRequestInfo request;
8575 request.method = "GET";
8576 // Note: the URL has a username:password in it. The password "baz" is
8577 // wrong (should be "bar").
bncce36dca22015-04-21 22:11:238578 request.url = GURL("http://foo:[email protected]/");
[email protected]2262e3a2012-05-22 16:08:168579
8580 request.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:108581 request.traffic_annotation =
8582 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2262e3a2012-05-22 16:08:168583
danakj1fd259a02016-04-16 03:17:098584 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168585 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2262e3a2012-05-22 16:08:168586
8587 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238588 MockWrite(
8589 "GET / HTTP/1.1\r\n"
8590 "Host: www.example.org\r\n"
8591 "Connection: keep-alive\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:168592 };
8593
8594 MockRead data_reads1[] = {
8595 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8596 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8597 MockRead("Content-Length: 10\r\n\r\n"),
8598 MockRead(SYNCHRONOUS, ERR_FAILED),
8599 };
8600
8601 // After the challenge above, the transaction will be restarted using the
8602 // identity from the url (foo, baz) to answer the challenge.
8603 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238604 MockWrite(
8605 "GET / HTTP/1.1\r\n"
8606 "Host: www.example.org\r\n"
8607 "Connection: keep-alive\r\n"
8608 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:168609 };
8610
8611 MockRead data_reads2[] = {
8612 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8613 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8614 MockRead("Content-Length: 10\r\n\r\n"),
8615 MockRead(SYNCHRONOUS, ERR_FAILED),
8616 };
8617
8618 // After the challenge above, the transaction will be restarted using the
8619 // identity supplied by the user (foo, bar) to answer the challenge.
8620 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:238621 MockWrite(
8622 "GET / HTTP/1.1\r\n"
8623 "Host: www.example.org\r\n"
8624 "Connection: keep-alive\r\n"
8625 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:168626 };
8627
8628 MockRead data_reads3[] = {
8629 MockRead("HTTP/1.0 200 OK\r\n"),
8630 MockRead("Content-Length: 100\r\n\r\n"),
8631 MockRead(SYNCHRONOUS, OK),
8632 };
8633
Ryan Sleevib8d7ea02018-05-07 20:01:018634 StaticSocketDataProvider data1(data_reads1, data_writes1);
8635 StaticSocketDataProvider data2(data_reads2, data_writes2);
8636 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]bb88e1d32013-05-03 23:11:078637 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8638 session_deps_.socket_factory->AddSocketDataProvider(&data2);
8639 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:168640
8641 TestCompletionCallback callback1;
8642
tfarina42834112016-09-22 13:38:208643 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018644 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:168645
8646 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018647 EXPECT_THAT(rv, IsOk());
[email protected]2262e3a2012-05-22 16:08:168648
bnc691fda62016-08-12 00:43:168649 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:168650 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:168651 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:018652 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:168653 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018654 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168655 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:168656
bnc691fda62016-08-12 00:43:168657 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528658 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:168659 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
8660
8661 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:168662 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:018663 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:168664 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:018665 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168666 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:168667
bnc691fda62016-08-12 00:43:168668 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528669 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:168670
8671 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:528672 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:168673
8674 EXPECT_EQ(100, response->headers->GetContentLength());
8675
[email protected]ea9dc9a2009-09-05 00:43:328676 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:558677 base::RunLoop().RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:328678}
8679
[email protected]2217aa22013-10-11 03:03:548680
8681// Test the request-challenge-retry sequence for basic auth when there is a
8682// correct identity in the URL, but its use is being suppressed. The identity
8683// from the URL should never be used.
bncd16676a2016-07-20 16:23:018684TEST_F(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
[email protected]2217aa22013-10-11 03:03:548685 HttpRequestInfo request;
8686 request.method = "GET";
bncce36dca22015-04-21 22:11:238687 request.url = GURL("http://foo:[email protected]/");
[email protected]2217aa22013-10-11 03:03:548688 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
Ramin Halavatib5e433e2018-02-07 07:41:108689 request.traffic_annotation =
8690 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2217aa22013-10-11 03:03:548691
danakj1fd259a02016-04-16 03:17:098692 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168693 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2217aa22013-10-11 03:03:548694
8695 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238696 MockWrite(
8697 "GET / HTTP/1.1\r\n"
8698 "Host: www.example.org\r\n"
8699 "Connection: keep-alive\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:548700 };
8701
8702 MockRead data_reads1[] = {
8703 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8704 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8705 MockRead("Content-Length: 10\r\n\r\n"),
8706 MockRead(SYNCHRONOUS, ERR_FAILED),
8707 };
8708
8709 // After the challenge above, the transaction will be restarted using the
8710 // identity supplied by the user, not the one in the URL, to answer the
8711 // challenge.
8712 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:238713 MockWrite(
8714 "GET / HTTP/1.1\r\n"
8715 "Host: www.example.org\r\n"
8716 "Connection: keep-alive\r\n"
8717 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:548718 };
8719
8720 MockRead data_reads3[] = {
8721 MockRead("HTTP/1.0 200 OK\r\n"),
8722 MockRead("Content-Length: 100\r\n\r\n"),
8723 MockRead(SYNCHRONOUS, OK),
8724 };
8725
Ryan Sleevib8d7ea02018-05-07 20:01:018726 StaticSocketDataProvider data1(data_reads1, data_writes1);
8727 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]2217aa22013-10-11 03:03:548728 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8729 session_deps_.socket_factory->AddSocketDataProvider(&data3);
8730
8731 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:208732 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018733 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:548734 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018735 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168736 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:548737
bnc691fda62016-08-12 00:43:168738 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528739 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:548740 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
8741
8742 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:168743 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:018744 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:548745 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:018746 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168747 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:548748
bnc691fda62016-08-12 00:43:168749 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528750 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:548751
8752 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:528753 EXPECT_FALSE(response->auth_challenge);
[email protected]2217aa22013-10-11 03:03:548754 EXPECT_EQ(100, response->headers->GetContentLength());
8755
8756 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:558757 base::RunLoop().RunUntilIdle();
[email protected]2217aa22013-10-11 03:03:548758}
8759
[email protected]f9ee6b52008-11-08 06:46:238760// Test that previously tried username/passwords for a realm get re-used.
bncd16676a2016-07-20 16:23:018761TEST_F(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
danakj1fd259a02016-04-16 03:17:098762 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:238763
8764 // Transaction 1: authenticate (foo, bar) on MyRealm1
8765 {
[email protected]1c773ea12009-04-28 19:58:428766 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238767 request.method = "GET";
bncce36dca22015-04-21 22:11:238768 request.url = GURL("http://www.example.org/x/y/z");
Ramin Halavatib5e433e2018-02-07 07:41:108769 request.traffic_annotation =
8770 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238771
bnc691fda62016-08-12 00:43:168772 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278773
[email protected]f9ee6b52008-11-08 06:46:238774 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238775 MockWrite(
8776 "GET /x/y/z HTTP/1.1\r\n"
8777 "Host: www.example.org\r\n"
8778 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238779 };
8780
8781 MockRead data_reads1[] = {
8782 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8783 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8784 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068785 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238786 };
8787
8788 // Resend with authorization (username=foo, password=bar)
8789 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238790 MockWrite(
8791 "GET /x/y/z HTTP/1.1\r\n"
8792 "Host: www.example.org\r\n"
8793 "Connection: keep-alive\r\n"
8794 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238795 };
8796
8797 // Sever accepts the authorization.
8798 MockRead data_reads2[] = {
8799 MockRead("HTTP/1.0 200 OK\r\n"),
8800 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068801 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238802 };
8803
Ryan Sleevib8d7ea02018-05-07 20:01:018804 StaticSocketDataProvider data1(data_reads1, data_writes1);
8805 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:078806 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8807 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:238808
[email protected]49639fa2011-12-20 23:22:418809 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238810
tfarina42834112016-09-22 13:38:208811 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018812 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238813
8814 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018815 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238816
bnc691fda62016-08-12 00:43:168817 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528818 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:048819 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:238820
[email protected]49639fa2011-12-20 23:22:418821 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:238822
bnc691fda62016-08-12 00:43:168823 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
8824 callback2.callback());
robpercival214763f2016-07-01 23:27:018825 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238826
8827 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018828 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238829
bnc691fda62016-08-12 00:43:168830 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528831 ASSERT_TRUE(response);
8832 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238833 EXPECT_EQ(100, response->headers->GetContentLength());
8834 }
8835
8836 // ------------------------------------------------------------------------
8837
8838 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
8839 {
[email protected]1c773ea12009-04-28 19:58:428840 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238841 request.method = "GET";
8842 // Note that Transaction 1 was at /x/y/z, so this is in the same
8843 // protection space as MyRealm1.
bncce36dca22015-04-21 22:11:238844 request.url = GURL("http://www.example.org/x/y/a/b");
Ramin Halavatib5e433e2018-02-07 07:41:108845 request.traffic_annotation =
8846 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238847
bnc691fda62016-08-12 00:43:168848 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278849
[email protected]f9ee6b52008-11-08 06:46:238850 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238851 MockWrite(
8852 "GET /x/y/a/b HTTP/1.1\r\n"
8853 "Host: www.example.org\r\n"
8854 "Connection: keep-alive\r\n"
8855 // Send preemptive authorization for MyRealm1
8856 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238857 };
8858
8859 // The server didn't like the preemptive authorization, and
8860 // challenges us for a different realm (MyRealm2).
8861 MockRead data_reads1[] = {
8862 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8863 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
8864 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068865 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238866 };
8867
8868 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
8869 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238870 MockWrite(
8871 "GET /x/y/a/b HTTP/1.1\r\n"
8872 "Host: www.example.org\r\n"
8873 "Connection: keep-alive\r\n"
8874 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238875 };
8876
8877 // Sever accepts the authorization.
8878 MockRead data_reads2[] = {
8879 MockRead("HTTP/1.0 200 OK\r\n"),
8880 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068881 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238882 };
8883
Ryan Sleevib8d7ea02018-05-07 20:01:018884 StaticSocketDataProvider data1(data_reads1, data_writes1);
8885 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:078886 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8887 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:238888
[email protected]49639fa2011-12-20 23:22:418889 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238890
tfarina42834112016-09-22 13:38:208891 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018892 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238893
8894 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018895 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238896
bnc691fda62016-08-12 00:43:168897 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528898 ASSERT_TRUE(response);
8899 ASSERT_TRUE(response->auth_challenge);
[email protected]79cb5c12011-09-12 13:12:048900 EXPECT_FALSE(response->auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:438901 EXPECT_EQ("http://www.example.org",
8902 response->auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:048903 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
aberentbba302d2015-12-03 10:20:198904 EXPECT_EQ(kBasicAuthScheme, response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:238905
[email protected]49639fa2011-12-20 23:22:418906 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:238907
bnc691fda62016-08-12 00:43:168908 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
8909 callback2.callback());
robpercival214763f2016-07-01 23:27:018910 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238911
8912 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018913 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238914
bnc691fda62016-08-12 00:43:168915 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528916 ASSERT_TRUE(response);
8917 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238918 EXPECT_EQ(100, response->headers->GetContentLength());
8919 }
8920
8921 // ------------------------------------------------------------------------
8922
8923 // Transaction 3: Resend a request in MyRealm's protection space --
8924 // succeed with preemptive authorization.
8925 {
[email protected]1c773ea12009-04-28 19:58:428926 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238927 request.method = "GET";
bncce36dca22015-04-21 22:11:238928 request.url = GURL("http://www.example.org/x/y/z2");
Ramin Halavatib5e433e2018-02-07 07:41:108929 request.traffic_annotation =
8930 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238931
bnc691fda62016-08-12 00:43:168932 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278933
[email protected]f9ee6b52008-11-08 06:46:238934 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238935 MockWrite(
8936 "GET /x/y/z2 HTTP/1.1\r\n"
8937 "Host: www.example.org\r\n"
8938 "Connection: keep-alive\r\n"
8939 // The authorization for MyRealm1 gets sent preemptively
8940 // (since the url is in the same protection space)
8941 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238942 };
8943
8944 // Sever accepts the preemptive authorization
8945 MockRead data_reads1[] = {
8946 MockRead("HTTP/1.0 200 OK\r\n"),
8947 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068948 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238949 };
8950
Ryan Sleevib8d7ea02018-05-07 20:01:018951 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:078952 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:238953
[email protected]49639fa2011-12-20 23:22:418954 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238955
tfarina42834112016-09-22 13:38:208956 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018957 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238958
8959 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018960 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238961
bnc691fda62016-08-12 00:43:168962 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528963 ASSERT_TRUE(response);
[email protected]f9ee6b52008-11-08 06:46:238964
wezca1070932016-05-26 20:30:528965 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238966 EXPECT_EQ(100, response->headers->GetContentLength());
8967 }
8968
8969 // ------------------------------------------------------------------------
8970
8971 // Transaction 4: request another URL in MyRealm (however the
8972 // url is not known to belong to the protection space, so no pre-auth).
8973 {
[email protected]1c773ea12009-04-28 19:58:428974 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238975 request.method = "GET";
bncce36dca22015-04-21 22:11:238976 request.url = GURL("http://www.example.org/x/1");
Ramin Halavatib5e433e2018-02-07 07:41:108977 request.traffic_annotation =
8978 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238979
bnc691fda62016-08-12 00:43:168980 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278981
[email protected]f9ee6b52008-11-08 06:46:238982 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238983 MockWrite(
8984 "GET /x/1 HTTP/1.1\r\n"
8985 "Host: www.example.org\r\n"
8986 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238987 };
8988
8989 MockRead data_reads1[] = {
8990 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8991 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8992 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068993 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238994 };
8995
8996 // Resend with authorization from MyRealm's cache.
8997 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238998 MockWrite(
8999 "GET /x/1 HTTP/1.1\r\n"
9000 "Host: www.example.org\r\n"
9001 "Connection: keep-alive\r\n"
9002 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:239003 };
9004
9005 // Sever accepts the authorization.
9006 MockRead data_reads2[] = {
9007 MockRead("HTTP/1.0 200 OK\r\n"),
9008 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069009 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:239010 };
9011
Ryan Sleevib8d7ea02018-05-07 20:01:019012 StaticSocketDataProvider data1(data_reads1, data_writes1);
9013 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:079014 session_deps_.socket_factory->AddSocketDataProvider(&data1);
9015 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:239016
[email protected]49639fa2011-12-20 23:22:419017 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:239018
tfarina42834112016-09-22 13:38:209019 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019020 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:239021
9022 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019023 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:239024
bnc691fda62016-08-12 00:43:169025 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:419026 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:169027 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:019028 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:229029 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:019030 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:169031 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:229032
bnc691fda62016-08-12 00:43:169033 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529034 ASSERT_TRUE(response);
9035 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:239036 EXPECT_EQ(100, response->headers->GetContentLength());
9037 }
9038
9039 // ------------------------------------------------------------------------
9040
9041 // Transaction 5: request a URL in MyRealm, but the server rejects the
9042 // cached identity. Should invalidate and re-prompt.
9043 {
[email protected]1c773ea12009-04-28 19:58:429044 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:239045 request.method = "GET";
bncce36dca22015-04-21 22:11:239046 request.url = GURL("http://www.example.org/p/q/t");
Ramin Halavatib5e433e2018-02-07 07:41:109047 request.traffic_annotation =
9048 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:239049
bnc691fda62016-08-12 00:43:169050 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279051
[email protected]f9ee6b52008-11-08 06:46:239052 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239053 MockWrite(
9054 "GET /p/q/t HTTP/1.1\r\n"
9055 "Host: www.example.org\r\n"
9056 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:239057 };
9058
9059 MockRead data_reads1[] = {
9060 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
9061 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9062 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069063 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:239064 };
9065
9066 // Resend with authorization from cache for MyRealm.
9067 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:239068 MockWrite(
9069 "GET /p/q/t HTTP/1.1\r\n"
9070 "Host: www.example.org\r\n"
9071 "Connection: keep-alive\r\n"
9072 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:239073 };
9074
9075 // Sever rejects the authorization.
9076 MockRead data_reads2[] = {
9077 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
9078 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9079 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069080 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:239081 };
9082
9083 // At this point we should prompt for new credentials for MyRealm.
9084 // Restart with username=foo3, password=foo4.
9085 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:239086 MockWrite(
9087 "GET /p/q/t HTTP/1.1\r\n"
9088 "Host: www.example.org\r\n"
9089 "Connection: keep-alive\r\n"
9090 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:239091 };
9092
9093 // Sever accepts the authorization.
9094 MockRead data_reads3[] = {
9095 MockRead("HTTP/1.0 200 OK\r\n"),
9096 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069097 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:239098 };
9099
Ryan Sleevib8d7ea02018-05-07 20:01:019100 StaticSocketDataProvider data1(data_reads1, data_writes1);
9101 StaticSocketDataProvider data2(data_reads2, data_writes2);
9102 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]bb88e1d32013-05-03 23:11:079103 session_deps_.socket_factory->AddSocketDataProvider(&data1);
9104 session_deps_.socket_factory->AddSocketDataProvider(&data2);
9105 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:239106
[email protected]49639fa2011-12-20 23:22:419107 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:239108
tfarina42834112016-09-22 13:38:209109 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019110 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:239111
9112 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019113 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:239114
bnc691fda62016-08-12 00:43:169115 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:419116 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:169117 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:019118 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:229119 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:019120 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:169121 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:229122
bnc691fda62016-08-12 00:43:169123 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529124 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:049125 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:239126
[email protected]49639fa2011-12-20 23:22:419127 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:239128
bnc691fda62016-08-12 00:43:169129 rv = trans.RestartWithAuth(AuthCredentials(kFoo3, kBar3),
9130 callback3.callback());
robpercival214763f2016-07-01 23:27:019131 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:239132
[email protected]0757e7702009-03-27 04:00:229133 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:019134 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:239135
bnc691fda62016-08-12 00:43:169136 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529137 ASSERT_TRUE(response);
9138 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:239139 EXPECT_EQ(100, response->headers->GetContentLength());
9140 }
9141}
[email protected]89ceba9a2009-03-21 03:46:069142
[email protected]3c32c5f2010-05-18 15:18:129143// Tests that nonce count increments when multiple auth attempts
9144// are started with the same nonce.
bncd16676a2016-07-20 16:23:019145TEST_F(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:449146 HttpAuthHandlerDigest::Factory* digest_factory =
9147 new HttpAuthHandlerDigest::Factory();
9148 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
9149 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
9150 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:079151 session_deps_.http_auth_handler_factory.reset(digest_factory);
danakj1fd259a02016-04-16 03:17:099152 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:129153
9154 // Transaction 1: authenticate (foo, bar) on MyRealm1
9155 {
[email protected]3c32c5f2010-05-18 15:18:129156 HttpRequestInfo request;
9157 request.method = "GET";
bncce36dca22015-04-21 22:11:239158 request.url = GURL("http://www.example.org/x/y/z");
Ramin Halavatib5e433e2018-02-07 07:41:109159 request.traffic_annotation =
9160 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3c32c5f2010-05-18 15:18:129161
bnc691fda62016-08-12 00:43:169162 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279163
[email protected]3c32c5f2010-05-18 15:18:129164 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239165 MockWrite(
9166 "GET /x/y/z HTTP/1.1\r\n"
9167 "Host: www.example.org\r\n"
9168 "Connection: keep-alive\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:129169 };
9170
9171 MockRead data_reads1[] = {
9172 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
9173 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
9174 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069175 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:129176 };
9177
9178 // Resend with authorization (username=foo, password=bar)
9179 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:239180 MockWrite(
9181 "GET /x/y/z HTTP/1.1\r\n"
9182 "Host: www.example.org\r\n"
9183 "Connection: keep-alive\r\n"
9184 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
9185 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
9186 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
9187 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:129188 };
9189
9190 // Sever accepts the authorization.
9191 MockRead data_reads2[] = {
zmo9528c9f42015-08-04 22:12:089192 MockRead("HTTP/1.0 200 OK\r\n"),
9193 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:129194 };
9195
Ryan Sleevib8d7ea02018-05-07 20:01:019196 StaticSocketDataProvider data1(data_reads1, data_writes1);
9197 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:079198 session_deps_.socket_factory->AddSocketDataProvider(&data1);
9199 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:129200
[email protected]49639fa2011-12-20 23:22:419201 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:129202
tfarina42834112016-09-22 13:38:209203 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019204 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:129205
9206 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019207 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:129208
bnc691fda62016-08-12 00:43:169209 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529210 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:049211 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:129212
[email protected]49639fa2011-12-20 23:22:419213 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:129214
bnc691fda62016-08-12 00:43:169215 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
9216 callback2.callback());
robpercival214763f2016-07-01 23:27:019217 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:129218
9219 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:019220 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:129221
bnc691fda62016-08-12 00:43:169222 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529223 ASSERT_TRUE(response);
9224 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:129225 }
9226
9227 // ------------------------------------------------------------------------
9228
9229 // Transaction 2: Request another resource in digestive's protection space.
9230 // This will preemptively add an Authorization header which should have an
9231 // "nc" value of 2 (as compared to 1 in the first use.
9232 {
[email protected]3c32c5f2010-05-18 15:18:129233 HttpRequestInfo request;
9234 request.method = "GET";
9235 // Note that Transaction 1 was at /x/y/z, so this is in the same
9236 // protection space as digest.
bncce36dca22015-04-21 22:11:239237 request.url = GURL("http://www.example.org/x/y/a/b");
Ramin Halavatib5e433e2018-02-07 07:41:109238 request.traffic_annotation =
9239 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3c32c5f2010-05-18 15:18:129240
bnc691fda62016-08-12 00:43:169241 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279242
[email protected]3c32c5f2010-05-18 15:18:129243 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239244 MockWrite(
9245 "GET /x/y/a/b HTTP/1.1\r\n"
9246 "Host: www.example.org\r\n"
9247 "Connection: keep-alive\r\n"
9248 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
9249 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
9250 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
9251 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:129252 };
9253
9254 // Sever accepts the authorization.
9255 MockRead data_reads1[] = {
9256 MockRead("HTTP/1.0 200 OK\r\n"),
9257 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069258 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:129259 };
9260
Ryan Sleevib8d7ea02018-05-07 20:01:019261 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:079262 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:129263
[email protected]49639fa2011-12-20 23:22:419264 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:129265
tfarina42834112016-09-22 13:38:209266 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019267 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:129268
9269 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019270 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:129271
bnc691fda62016-08-12 00:43:169272 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529273 ASSERT_TRUE(response);
9274 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:129275 }
9276}
9277
[email protected]89ceba9a2009-03-21 03:46:069278// Test the ResetStateForRestart() private method.
bncd16676a2016-07-20 16:23:019279TEST_F(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:069280 // Create a transaction (the dependencies aren't important).
danakj1fd259a02016-04-16 03:17:099281 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169282 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]89ceba9a2009-03-21 03:46:069283
9284 // Setup some state (which we expect ResetStateForRestart() will clear).
Victor Costan9c7302b2018-08-27 16:39:449285 trans.read_buf_ = base::MakeRefCounted<IOBuffer>(15);
bnc691fda62016-08-12 00:43:169286 trans.read_buf_len_ = 15;
9287 trans.request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:069288
9289 // Setup state in response_
bnc691fda62016-08-12 00:43:169290 HttpResponseInfo* response = &trans.response_;
[email protected]0877e3d2009-10-17 22:29:579291 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:089292 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:579293 response->response_time = base::Time::Now();
9294 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:069295
9296 { // Setup state for response_.vary_data
9297 HttpRequestInfo request;
9298 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
9299 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:279300 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:439301 request.extra_headers.SetHeader("Foo", "1");
9302 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:509303 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:069304 }
9305
9306 // Cause the above state to be reset.
bnc691fda62016-08-12 00:43:169307 trans.ResetStateForRestart();
[email protected]89ceba9a2009-03-21 03:46:069308
9309 // Verify that the state that needed to be reset, has been reset.
bnc691fda62016-08-12 00:43:169310 EXPECT_FALSE(trans.read_buf_);
9311 EXPECT_EQ(0, trans.read_buf_len_);
9312 EXPECT_TRUE(trans.request_headers_.IsEmpty());
wezca1070932016-05-26 20:30:529313 EXPECT_FALSE(response->auth_challenge);
9314 EXPECT_FALSE(response->headers);
[email protected]34f40942010-10-04 00:34:049315 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:089316 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:579317 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:069318}
9319
[email protected]bacff652009-03-31 17:50:339320// Test HTTPS connections to a site with a bad certificate
bncd16676a2016-07-20 16:23:019321TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:339322 HttpRequestInfo request;
9323 request.method = "GET";
bncce36dca22015-04-21 22:11:239324 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109325 request.traffic_annotation =
9326 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]bacff652009-03-31 17:50:339327
danakj1fd259a02016-04-16 03:17:099328 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169329 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279330
[email protected]bacff652009-03-31 17:50:339331 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239332 MockWrite(
9333 "GET / HTTP/1.1\r\n"
9334 "Host: www.example.org\r\n"
9335 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:339336 };
9337
9338 MockRead data_reads[] = {
9339 MockRead("HTTP/1.0 200 OK\r\n"),
9340 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9341 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069342 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:339343 };
9344
[email protected]5ecc992a42009-11-11 01:41:599345 StaticSocketDataProvider ssl_bad_certificate;
Ryan Sleevib8d7ea02018-05-07 20:01:019346 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069347 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
9348 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:339349
[email protected]bb88e1d32013-05-03 23:11:079350 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
9351 session_deps_.socket_factory->AddSocketDataProvider(&data);
9352 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
9353 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:339354
[email protected]49639fa2011-12-20 23:22:419355 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:339356
tfarina42834112016-09-22 13:38:209357 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019358 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:339359
9360 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019361 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:339362
bnc691fda62016-08-12 00:43:169363 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:019364 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:339365
9366 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019367 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:339368
bnc691fda62016-08-12 00:43:169369 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:339370
wezca1070932016-05-26 20:30:529371 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:339372 EXPECT_EQ(100, response->headers->GetContentLength());
9373}
9374
9375// Test HTTPS connections to a site with a bad certificate, going through a
9376// proxy
bncd16676a2016-07-20 16:23:019377TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
Ramin Halavatica8d5252018-03-12 05:33:499378 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9379 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]bacff652009-03-31 17:50:339380
9381 HttpRequestInfo request;
9382 request.method = "GET";
bncce36dca22015-04-21 22:11:239383 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109384 request.traffic_annotation =
9385 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]bacff652009-03-31 17:50:339386
9387 MockWrite proxy_writes[] = {
rsleevidb16bb02015-11-12 23:47:179388 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9389 "Host: www.example.org:443\r\n"
9390 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:339391 };
9392
9393 MockRead proxy_reads[] = {
9394 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069395 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:339396 };
9397
9398 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179399 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9400 "Host: www.example.org:443\r\n"
9401 "Proxy-Connection: keep-alive\r\n\r\n"),
9402 MockWrite("GET / HTTP/1.1\r\n"
9403 "Host: www.example.org\r\n"
9404 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:339405 };
9406
9407 MockRead data_reads[] = {
9408 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
9409 MockRead("HTTP/1.0 200 OK\r\n"),
9410 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9411 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069412 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:339413 };
9414
Ryan Sleevib8d7ea02018-05-07 20:01:019415 StaticSocketDataProvider ssl_bad_certificate(proxy_reads, proxy_writes);
9416 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069417 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
9418 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:339419
[email protected]bb88e1d32013-05-03 23:11:079420 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
9421 session_deps_.socket_factory->AddSocketDataProvider(&data);
9422 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
9423 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:339424
[email protected]49639fa2011-12-20 23:22:419425 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:339426
9427 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:079428 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:339429
danakj1fd259a02016-04-16 03:17:099430 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169431 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bacff652009-03-31 17:50:339432
tfarina42834112016-09-22 13:38:209433 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019434 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:339435
9436 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019437 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:339438
bnc691fda62016-08-12 00:43:169439 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:019440 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:339441
9442 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019443 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:339444
bnc691fda62016-08-12 00:43:169445 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:339446
wezca1070932016-05-26 20:30:529447 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:339448 EXPECT_EQ(100, response->headers->GetContentLength());
9449 }
9450}
9451
[email protected]2df19bb2010-08-25 20:13:469452
9453// Test HTTPS connections to a site, going through an HTTPS proxy
bncd16676a2016-07-20 16:23:019454TEST_F(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:599455 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499456 ProxyResolutionService::CreateFixedFromPacResult(
9457 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519458 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079459 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:469460
9461 HttpRequestInfo request;
9462 request.method = "GET";
bncce36dca22015-04-21 22:11:239463 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109464 request.traffic_annotation =
9465 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:469466
9467 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179468 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9469 "Host: www.example.org:443\r\n"
9470 "Proxy-Connection: keep-alive\r\n\r\n"),
9471 MockWrite("GET / HTTP/1.1\r\n"
9472 "Host: www.example.org\r\n"
9473 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:469474 };
9475
9476 MockRead data_reads[] = {
9477 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
9478 MockRead("HTTP/1.1 200 OK\r\n"),
9479 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9480 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069481 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:469482 };
9483
Ryan Sleevib8d7ea02018-05-07 20:01:019484 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069485 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
9486 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:469487
[email protected]bb88e1d32013-05-03 23:11:079488 session_deps_.socket_factory->AddSocketDataProvider(&data);
9489 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
9490 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:469491
[email protected]49639fa2011-12-20 23:22:419492 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:469493
danakj1fd259a02016-04-16 03:17:099494 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169495 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:469496
tfarina42834112016-09-22 13:38:209497 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019498 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:469499
9500 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019501 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:169502 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:469503
wezca1070932016-05-26 20:30:529504 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:469505
tbansal2ecbbc72016-10-06 17:15:479506 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:469507 EXPECT_TRUE(response->headers->IsKeepAlive());
9508 EXPECT_EQ(200, response->headers->response_code());
9509 EXPECT_EQ(100, response->headers->GetContentLength());
9510 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:209511
9512 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169513 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209514 TestLoadTimingNotReusedWithPac(load_timing_info,
9515 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:469516}
9517
[email protected]511f6f52010-12-17 03:58:299518// Test an HTTPS Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:019519TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:599520 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499521 ProxyResolutionService::CreateFixedFromPacResult(
9522 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519523 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079524 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:299525
9526 HttpRequestInfo request;
9527 request.method = "GET";
bncce36dca22015-04-21 22:11:239528 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109529 request.traffic_annotation =
9530 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299531
9532 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179533 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9534 "Host: www.example.org:443\r\n"
9535 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:299536 };
9537
9538 MockRead data_reads[] = {
9539 MockRead("HTTP/1.1 302 Redirect\r\n"),
9540 MockRead("Location: http://login.example.com/\r\n"),
9541 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069542 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:299543 };
9544
Ryan Sleevib8d7ea02018-05-07 20:01:019545 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069546 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:299547
[email protected]bb88e1d32013-05-03 23:11:079548 session_deps_.socket_factory->AddSocketDataProvider(&data);
9549 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:299550
[email protected]49639fa2011-12-20 23:22:419551 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:299552
danakj1fd259a02016-04-16 03:17:099553 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169554 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:299555
tfarina42834112016-09-22 13:38:209556 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019557 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:299558
9559 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019560 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:169561 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:299562
wezca1070932016-05-26 20:30:529563 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:299564
9565 EXPECT_EQ(302, response->headers->response_code());
9566 std::string url;
9567 EXPECT_TRUE(response->headers->IsRedirect(&url));
9568 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:209569
9570 // In the case of redirects from proxies, HttpNetworkTransaction returns
9571 // timing for the proxy connection instead of the connection to the host,
9572 // and no send / receive times.
9573 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
9574 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169575 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209576
9577 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:199578 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:209579
9580 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
9581 EXPECT_LE(load_timing_info.proxy_resolve_start,
9582 load_timing_info.proxy_resolve_end);
9583 EXPECT_LE(load_timing_info.proxy_resolve_end,
9584 load_timing_info.connect_timing.connect_start);
9585 ExpectConnectTimingHasTimes(
9586 load_timing_info.connect_timing,
9587 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
9588
9589 EXPECT_TRUE(load_timing_info.send_start.is_null());
9590 EXPECT_TRUE(load_timing_info.send_end.is_null());
9591 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:299592}
9593
9594// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:019595TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
Ramin Halavatica8d5252018-03-12 05:33:499596 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9597 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299598
9599 HttpRequestInfo request;
9600 request.method = "GET";
bncce36dca22015-04-21 22:11:239601 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109602 request.traffic_annotation =
9603 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299604
Ryan Hamilton0239aac2018-05-19 00:03:139605 spdy::SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:239606 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:139607 spdy::SpdySerializedFrame goaway(
9608 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:299609 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:419610 CreateMockWrite(conn, 0, SYNCHRONOUS),
9611 CreateMockWrite(goaway, 2, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:299612 };
9613
9614 static const char* const kExtraHeaders[] = {
9615 "location",
9616 "http://login.example.com/",
9617 };
Ryan Hamilton0239aac2018-05-19 00:03:139618 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
Avi Drissman4365a4782018-12-28 19:26:249619 "302", kExtraHeaders, base::size(kExtraHeaders) / 2, 1));
[email protected]511f6f52010-12-17 03:58:299620 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:419621 CreateMockRead(resp, 1), MockRead(ASYNC, 0, 3), // EOF
[email protected]511f6f52010-12-17 03:58:299622 };
9623
Ryan Sleevib8d7ea02018-05-07 20:01:019624 SequencedSocketData data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069625 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:369626 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:299627
[email protected]bb88e1d32013-05-03 23:11:079628 session_deps_.socket_factory->AddSocketDataProvider(&data);
9629 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:299630
[email protected]49639fa2011-12-20 23:22:419631 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:299632
danakj1fd259a02016-04-16 03:17:099633 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169634 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:299635
tfarina42834112016-09-22 13:38:209636 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019637 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:299638
9639 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019640 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:169641 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:299642
wezca1070932016-05-26 20:30:529643 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:299644
9645 EXPECT_EQ(302, response->headers->response_code());
9646 std::string url;
9647 EXPECT_TRUE(response->headers->IsRedirect(&url));
9648 EXPECT_EQ("http://login.example.com/", url);
9649}
9650
[email protected]4eddbc732012-08-09 05:40:179651// Test that an HTTPS proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:019652TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaHttpsProxy) {
Ramin Halavatica8d5252018-03-12 05:33:499653 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9654 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299655
9656 HttpRequestInfo request;
9657 request.method = "GET";
bncce36dca22015-04-21 22:11:239658 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109659 request.traffic_annotation =
9660 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299661
9662 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179663 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9664 "Host: www.example.org:443\r\n"
9665 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:299666 };
9667
9668 MockRead data_reads[] = {
9669 MockRead("HTTP/1.1 404 Not Found\r\n"),
9670 MockRead("Content-Length: 23\r\n\r\n"),
9671 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:069672 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:299673 };
9674
Ryan Sleevib8d7ea02018-05-07 20:01:019675 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069676 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:299677
[email protected]bb88e1d32013-05-03 23:11:079678 session_deps_.socket_factory->AddSocketDataProvider(&data);
9679 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:299680
[email protected]49639fa2011-12-20 23:22:419681 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:299682
danakj1fd259a02016-04-16 03:17:099683 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169684 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:299685
tfarina42834112016-09-22 13:38:209686 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019687 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:299688
9689 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019690 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:299691
ttuttle960fcbf2016-04-19 13:26:329692 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:299693}
9694
[email protected]4eddbc732012-08-09 05:40:179695// Test that a SPDY proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:019696TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaSpdyProxy) {
Ramin Halavatica8d5252018-03-12 05:33:499697 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9698 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299699
9700 HttpRequestInfo request;
9701 request.method = "GET";
bncce36dca22015-04-21 22:11:239702 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109703 request.traffic_annotation =
9704 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299705
Ryan Hamilton0239aac2018-05-19 00:03:139706 spdy::SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:239707 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:139708 spdy::SpdySerializedFrame rst(
9709 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:299710 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:419711 CreateMockWrite(conn, 0), CreateMockWrite(rst, 3),
[email protected]511f6f52010-12-17 03:58:299712 };
9713
9714 static const char* const kExtraHeaders[] = {
9715 "location",
9716 "http://login.example.com/",
9717 };
Ryan Hamilton0239aac2018-05-19 00:03:139718 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
Avi Drissman4365a4782018-12-28 19:26:249719 "404", kExtraHeaders, base::size(kExtraHeaders) / 2, 1));
Ryan Hamilton0239aac2018-05-19 00:03:139720 spdy::SpdySerializedFrame body(
Bence Békyd74f4382018-02-20 18:26:199721 spdy_util_.ConstructSpdyDataFrame(1, "The host does not exist", true));
[email protected]511f6f52010-12-17 03:58:299722 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:419723 CreateMockRead(resp, 1), CreateMockRead(body, 2),
rch8e6c6c42015-05-01 14:05:139724 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:299725 };
9726
Ryan Sleevib8d7ea02018-05-07 20:01:019727 SequencedSocketData data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069728 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:369729 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:299730
[email protected]bb88e1d32013-05-03 23:11:079731 session_deps_.socket_factory->AddSocketDataProvider(&data);
9732 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:299733
[email protected]49639fa2011-12-20 23:22:419734 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:299735
danakj1fd259a02016-04-16 03:17:099736 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169737 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:299738
tfarina42834112016-09-22 13:38:209739 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019740 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:299741
9742 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019743 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:299744
ttuttle960fcbf2016-04-19 13:26:329745 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:299746}
9747
[email protected]0c5fb722012-02-28 11:50:359748// Test the request-challenge-retry sequence for basic auth, through
9749// a SPDY proxy over a single SPDY session.
bncd16676a2016-07-20 16:23:019750TEST_F(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:359751 HttpRequestInfo request;
9752 request.method = "GET";
bncce36dca22015-04-21 22:11:239753 request.url = GURL("https://www.example.org/");
[email protected]0c5fb722012-02-28 11:50:359754 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:299755 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:109756 request.traffic_annotation =
9757 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0c5fb722012-02-28 11:50:359758
9759 // Configure against https proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:599760 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499761 ProxyResolutionService::CreateFixedFromPacResult(
9762 "HTTPS myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519763 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:079764 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:099765 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:359766
9767 // Since we have proxy, should try to establish tunnel.
Ryan Hamilton0239aac2018-05-19 00:03:139768 spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:239769 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:139770 spdy::SpdySerializedFrame rst(
9771 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
rdsmithebb50aa2015-11-12 03:44:389772 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]0c5fb722012-02-28 11:50:359773
bnc691fda62016-08-12 00:43:169774 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0c5fb722012-02-28 11:50:359775 // be issuing -- the final header line contains the credentials.
9776 const char* const kAuthCredentials[] = {
9777 "proxy-authorization", "Basic Zm9vOmJhcg==",
9778 };
Ryan Hamilton0239aac2018-05-19 00:03:139779 spdy::SpdySerializedFrame connect2(spdy_util_.ConstructSpdyConnect(
Avi Drissman4365a4782018-12-28 19:26:249780 kAuthCredentials, base::size(kAuthCredentials) / 2, 3, LOWEST,
bncce36dca22015-04-21 22:11:239781 HostPortPair("www.example.org", 443)));
9782 // fetch https://www.example.org/ via HTTP
9783 const char get[] =
9784 "GET / HTTP/1.1\r\n"
9785 "Host: www.example.org\r\n"
9786 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:139787 spdy::SpdySerializedFrame wrapped_get(
Bence Békyd74f4382018-02-20 18:26:199788 spdy_util_.ConstructSpdyDataFrame(3, get, false));
[email protected]0c5fb722012-02-28 11:50:359789
9790 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:419791 CreateMockWrite(req, 0, ASYNC), CreateMockWrite(rst, 2, ASYNC),
9792 CreateMockWrite(connect2, 3), CreateMockWrite(wrapped_get, 5),
[email protected]0c5fb722012-02-28 11:50:359793 };
9794
9795 // The proxy responds to the connect with a 407, using a persistent
9796 // connection.
thestig9d3bb0c2015-01-24 00:49:519797 const char kAuthStatus[] = "407";
[email protected]0c5fb722012-02-28 11:50:359798 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:359799 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
9800 };
Ryan Hamilton0239aac2018-05-19 00:03:139801 spdy::SpdySerializedFrame conn_auth_resp(spdy_util_.ConstructSpdyReplyError(
Avi Drissman4365a4782018-12-28 19:26:249802 kAuthStatus, kAuthChallenge, base::size(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:359803
Ryan Hamilton0239aac2018-05-19 00:03:139804 spdy::SpdySerializedFrame conn_resp(
9805 spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:359806 const char resp[] = "HTTP/1.1 200 OK\r\n"
9807 "Content-Length: 5\r\n\r\n";
9808
Ryan Hamilton0239aac2018-05-19 00:03:139809 spdy::SpdySerializedFrame wrapped_get_resp(
Bence Békyd74f4382018-02-20 18:26:199810 spdy_util_.ConstructSpdyDataFrame(3, resp, false));
Ryan Hamilton0239aac2018-05-19 00:03:139811 spdy::SpdySerializedFrame wrapped_body(
Bence Békyd74f4382018-02-20 18:26:199812 spdy_util_.ConstructSpdyDataFrame(3, "hello", false));
[email protected]0c5fb722012-02-28 11:50:359813 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:419814 CreateMockRead(conn_auth_resp, 1, ASYNC),
9815 CreateMockRead(conn_resp, 4, ASYNC),
9816 CreateMockRead(wrapped_get_resp, 6, ASYNC),
9817 CreateMockRead(wrapped_body, 7, ASYNC),
rch8e6c6c42015-05-01 14:05:139818 MockRead(ASYNC, OK, 8), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:359819 };
9820
Ryan Sleevib8d7ea02018-05-07 20:01:019821 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:079822 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:359823 // Negotiate SPDY to the proxy
9824 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:369825 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:079826 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:359827 // Vanilla SSL to the server
9828 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:079829 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:359830
9831 TestCompletionCallback callback1;
9832
bnc87dcefc2017-05-25 12:47:589833 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:199834 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0c5fb722012-02-28 11:50:359835
9836 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:019837 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:359838
9839 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019840 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:469841 TestNetLogEntry::List entries;
[email protected]0c5fb722012-02-28 11:50:359842 log.GetEntries(&entries);
9843 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:009844 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
9845 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:359846 ExpectLogContainsSomewhere(
9847 entries, pos,
mikecirone8b85c432016-09-08 19:11:009848 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
9849 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:359850
9851 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529852 ASSERT_TRUE(response);
9853 ASSERT_TRUE(response->headers);
[email protected]0c5fb722012-02-28 11:50:359854 EXPECT_EQ(407, response->headers->response_code());
9855 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
wezca1070932016-05-26 20:30:529856 EXPECT_TRUE(response->auth_challenge);
asanka098c0092016-06-16 20:18:439857 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]0c5fb722012-02-28 11:50:359858
9859 TestCompletionCallback callback2;
9860
9861 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
9862 callback2.callback());
robpercival214763f2016-07-01 23:27:019863 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:359864
9865 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:019866 EXPECT_THAT(rv, IsOk());
[email protected]0c5fb722012-02-28 11:50:359867
9868 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529869 ASSERT_TRUE(response);
[email protected]0c5fb722012-02-28 11:50:359870
9871 EXPECT_TRUE(response->headers->IsKeepAlive());
9872 EXPECT_EQ(200, response->headers->response_code());
9873 EXPECT_EQ(5, response->headers->GetContentLength());
9874 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
9875
9876 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:529877 EXPECT_FALSE(response->auth_challenge);
[email protected]0c5fb722012-02-28 11:50:359878
[email protected]029c83b62013-01-24 05:28:209879 LoadTimingInfo load_timing_info;
9880 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
9881 TestLoadTimingNotReusedWithPac(load_timing_info,
9882 CONNECT_TIMING_HAS_SSL_TIMES);
9883
[email protected]0c5fb722012-02-28 11:50:359884 trans.reset();
9885 session->CloseAllConnections();
9886}
9887
[email protected]7c6f7ba2012-04-03 04:09:299888// Test that an explicitly trusted SPDY proxy can push a resource from an
9889// origin that is different from that of its associated resource.
bncd16676a2016-07-20 16:23:019890TEST_F(HttpNetworkTransactionTest, CrossOriginSPDYProxyPush) {
tbansal28e68f82016-02-04 02:56:159891 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:199892 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:159893 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
9894 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]7c6f7ba2012-04-03 04:09:299895 HttpRequestInfo request;
9896 HttpRequestInfo push_request;
Ramin Halavatib5e433e2018-02-07 07:41:109897 request.traffic_annotation =
9898 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7c6f7ba2012-04-03 04:09:299899
[email protected]7c6f7ba2012-04-03 04:09:299900 request.method = "GET";
bncce36dca22015-04-21 22:11:239901 request.url = GURL("http://www.example.org/");
[email protected]7c6f7ba2012-04-03 04:09:299902 push_request.method = "GET";
9903 push_request.url = GURL("http://www.another-origin.com/foo.dat");
Ramin Halavatib5e433e2018-02-07 07:41:109904 push_request.traffic_annotation =
9905 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7c6f7ba2012-04-03 04:09:299906
tbansal28e68f82016-02-04 02:56:159907 // Configure against https proxy server "myproxy:443".
Lily Houghton8c2f97d2018-01-22 05:06:599908 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499909 ProxyResolutionService::CreateFixedFromPacResult(
9910 "HTTPS myproxy:443", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519911 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:079912 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:509913
Eric Roman3d8546a2018-09-10 17:00:529914 session_deps_.proxy_resolution_service->SetProxyDelegate(
9915 proxy_delegate.get());
[email protected]61b4efc2012-04-27 18:12:509916
danakj1fd259a02016-04-16 03:17:099917 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:299918
Ryan Hamilton0239aac2018-05-19 00:03:139919 spdy::SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:459920 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:139921 spdy::SpdySerializedFrame stream2_priority(
tombergan5d22c182017-01-11 02:05:359922 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
[email protected]7c6f7ba2012-04-03 04:09:299923
9924 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:419925 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:359926 CreateMockWrite(stream2_priority, 3, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:299927 };
9928
Ryan Hamilton0239aac2018-05-19 00:03:139929 spdy::SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
Bence Béky7bf94362018-01-10 13:19:369930 NULL, 0, 2, 1, "http://www.another-origin.com/foo.dat"));
9931
Ryan Hamilton0239aac2018-05-19 00:03:139932 spdy::SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:159933 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:299934
Ryan Hamilton0239aac2018-05-19 00:03:139935 spdy::SpdySerializedFrame stream1_body(
9936 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:299937
Ryan Hamilton0239aac2018-05-19 00:03:139938 spdy::SpdySerializedFrame stream2_body(
Bence Békyd74f4382018-02-20 18:26:199939 spdy_util_.ConstructSpdyDataFrame(2, "pushed", true));
[email protected]7c6f7ba2012-04-03 04:09:299940
9941 MockRead spdy_reads[] = {
Bence Béky7bf94362018-01-10 13:19:369942 CreateMockRead(stream2_syn, 1, ASYNC),
9943 CreateMockRead(stream1_reply, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:359944 CreateMockRead(stream1_body, 4, ASYNC),
9945 CreateMockRead(stream2_body, 5, ASYNC),
9946 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
[email protected]7c6f7ba2012-04-03 04:09:299947 };
9948
Ryan Sleevib8d7ea02018-05-07 20:01:019949 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:079950 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:299951 // Negotiate SPDY to the proxy
9952 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:369953 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:079954 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:299955
bnc87dcefc2017-05-25 12:47:589956 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:199957 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7c6f7ba2012-04-03 04:09:299958 TestCompletionCallback callback;
9959 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:019960 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:299961
9962 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019963 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:299964 const HttpResponseInfo* response = trans->GetResponseInfo();
9965
bnc87dcefc2017-05-25 12:47:589966 auto push_trans =
Jeremy Roman0579ed62017-08-29 15:56:199967 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]90499482013-06-01 00:39:509968 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:019969 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:299970
9971 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019972 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:299973 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
9974
wezca1070932016-05-26 20:30:529975 ASSERT_TRUE(response);
[email protected]7c6f7ba2012-04-03 04:09:299976 EXPECT_TRUE(response->headers->IsKeepAlive());
9977
9978 EXPECT_EQ(200, response->headers->response_code());
9979 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
9980
9981 std::string response_data;
9982 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:019983 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:299984 EXPECT_EQ("hello!", response_data);
9985
[email protected]029c83b62013-01-24 05:28:209986 LoadTimingInfo load_timing_info;
9987 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
9988 TestLoadTimingNotReusedWithPac(load_timing_info,
9989 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9990
[email protected]7c6f7ba2012-04-03 04:09:299991 // Verify the pushed stream.
wezca1070932016-05-26 20:30:529992 EXPECT_TRUE(push_response->headers);
[email protected]7c6f7ba2012-04-03 04:09:299993 EXPECT_EQ(200, push_response->headers->response_code());
9994
9995 rv = ReadTransaction(push_trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:019996 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:299997 EXPECT_EQ("pushed", response_data);
9998
[email protected]029c83b62013-01-24 05:28:209999 LoadTimingInfo push_load_timing_info;
10000 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
10001 TestLoadTimingReusedWithPac(push_load_timing_info);
10002 // The transactions should share a socket ID, despite being for different
10003 // origins.
10004 EXPECT_EQ(load_timing_info.socket_log_id,
10005 push_load_timing_info.socket_log_id);
10006
[email protected]7c6f7ba2012-04-03 04:09:2910007 trans.reset();
10008 push_trans.reset();
10009 session->CloseAllConnections();
10010}
10011
[email protected]8c843192012-04-05 07:15:0010012// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
bncd16676a2016-07-20 16:23:0110013TEST_F(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:1510014 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:1910015 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:1510016 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
10017 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]8c843192012-04-05 07:15:0010018 HttpRequestInfo request;
10019
10020 request.method = "GET";
bncce36dca22015-04-21 22:11:2310021 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010022 request.traffic_annotation =
10023 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c843192012-04-05 07:15:0010024
Ramin Halavatica8d5252018-03-12 05:33:4910025 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
10026 "https://myproxy:443", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110027 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710028 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:5010029
10030 // Enable cross-origin push.
Eric Roman3d8546a2018-09-10 17:00:5210031 session_deps_.proxy_resolution_service->SetProxyDelegate(
10032 proxy_delegate.get());
[email protected]61b4efc2012-04-27 18:12:5010033
danakj1fd259a02016-04-16 03:17:0910034 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:0010035
Ryan Hamilton0239aac2018-05-19 00:03:1310036 spdy::SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:4510037 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
[email protected]8c843192012-04-05 07:15:0010038
Ryan Hamilton0239aac2018-05-19 00:03:1310039 spdy::SpdySerializedFrame push_rst(
10040 spdy_util_.ConstructSpdyRstStream(2, spdy::ERROR_CODE_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:0010041
10042 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4110043 CreateMockWrite(stream1_syn, 0, ASYNC), CreateMockWrite(push_rst, 3),
[email protected]8c843192012-04-05 07:15:0010044 };
10045
Ryan Hamilton0239aac2018-05-19 00:03:1310046 spdy::SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:1510047 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:0010048
Ryan Hamilton0239aac2018-05-19 00:03:1310049 spdy::SpdySerializedFrame stream1_body(
10050 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]8c843192012-04-05 07:15:0010051
Ryan Hamilton0239aac2018-05-19 00:03:1310052 spdy::SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
bncb03b1092016-04-06 11:19:5510053 NULL, 0, 2, 1, "https://www.another-origin.com/foo.dat"));
[email protected]8c843192012-04-05 07:15:0010054
10055 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4110056 CreateMockRead(stream1_reply, 1, ASYNC),
10057 CreateMockRead(stream2_syn, 2, ASYNC),
10058 CreateMockRead(stream1_body, 4, ASYNC),
mmenkee24011922015-12-17 22:12:5910059 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
[email protected]8c843192012-04-05 07:15:0010060 };
10061
Ryan Sleevib8d7ea02018-05-07 20:01:0110062 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0710063 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:0010064 // Negotiate SPDY to the proxy
10065 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610066 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0710067 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:0010068
bnc87dcefc2017-05-25 12:47:5810069 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1910070 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]8c843192012-04-05 07:15:0010071 TestCompletionCallback callback;
10072 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0110073 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c843192012-04-05 07:15:0010074
10075 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110076 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:0010077 const HttpResponseInfo* response = trans->GetResponseInfo();
10078
wezca1070932016-05-26 20:30:5210079 ASSERT_TRUE(response);
[email protected]8c843192012-04-05 07:15:0010080 EXPECT_TRUE(response->headers->IsKeepAlive());
10081
10082 EXPECT_EQ(200, response->headers->response_code());
10083 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10084
10085 std::string response_data;
10086 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:0110087 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:0010088 EXPECT_EQ("hello!", response_data);
10089
10090 trans.reset();
10091 session->CloseAllConnections();
10092}
10093
tbansal8ef1d3e2016-02-03 04:05:4210094// Test that an explicitly trusted SPDY proxy can push same-origin HTTPS
10095// resources.
bncd16676a2016-07-20 16:23:0110096TEST_F(HttpNetworkTransactionTest, SameOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:1510097 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:1910098 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:1510099 proxy_delegate->set_trusted_spdy_proxy(
10100 net::ProxyServer::FromURI("myproxy:70", net::ProxyServer::SCHEME_HTTP));
10101
tbansal8ef1d3e2016-02-03 04:05:4210102 HttpRequestInfo request;
10103
10104 request.method = "GET";
10105 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010106 request.traffic_annotation =
10107 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal8ef1d3e2016-02-03 04:05:4210108
10109 // Configure against https proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:4910110 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
10111 "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal8ef1d3e2016-02-03 04:05:4210112 BoundTestNetLog log;
10113 session_deps_.net_log = log.bound().net_log();
10114
10115 // Enable cross-origin push.
Eric Roman3d8546a2018-09-10 17:00:5210116 session_deps_.proxy_resolution_service->SetProxyDelegate(
10117 proxy_delegate.get());
tbansal8ef1d3e2016-02-03 04:05:4210118
danakj1fd259a02016-04-16 03:17:0910119 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
tbansal8ef1d3e2016-02-03 04:05:4210120
Ryan Hamilton0239aac2018-05-19 00:03:1310121 spdy::SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:4510122 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1310123 spdy::SpdySerializedFrame stream2_priority(
tombergan5d22c182017-01-11 02:05:3510124 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
tbansal8ef1d3e2016-02-03 04:05:4210125
10126 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4110127 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:3510128 CreateMockWrite(stream2_priority, 3, ASYNC),
tbansal8ef1d3e2016-02-03 04:05:4210129 };
10130
Ryan Hamilton0239aac2018-05-19 00:03:1310131 spdy::SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:1510132 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:4210133
Ryan Hamilton0239aac2018-05-19 00:03:1310134 spdy::SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
Bence Béky096cf052017-08-08 23:55:3310135 nullptr, 0, 2, 1, "http://www.example.org/foo.dat"));
bnc38dcd392016-02-09 23:19:4910136
Ryan Hamilton0239aac2018-05-19 00:03:1310137 spdy::SpdySerializedFrame stream1_body(
10138 spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:4210139
Ryan Hamilton0239aac2018-05-19 00:03:1310140 spdy::SpdySerializedFrame stream2_reply(
bnc42331402016-07-25 13:36:1510141 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:4210142
Ryan Hamilton0239aac2018-05-19 00:03:1310143 spdy::SpdySerializedFrame stream2_body(
10144 spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:4210145
10146 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4110147 CreateMockRead(stream1_reply, 1, ASYNC),
10148 CreateMockRead(stream2_syn, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:3510149 CreateMockRead(stream1_body, 4, ASYNC),
10150 CreateMockRead(stream2_body, 5, ASYNC),
10151 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
tbansal8ef1d3e2016-02-03 04:05:4210152 };
10153
Ryan Sleevib8d7ea02018-05-07 20:01:0110154 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
tbansal8ef1d3e2016-02-03 04:05:4210155 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
10156 // Negotiate SPDY to the proxy
10157 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610158 proxy.next_proto = kProtoHTTP2;
tbansal8ef1d3e2016-02-03 04:05:4210159 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
10160
bnc87dcefc2017-05-25 12:47:5810161 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1910162 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tbansal8ef1d3e2016-02-03 04:05:4210163 TestCompletionCallback callback;
10164 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0110165 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
tbansal8ef1d3e2016-02-03 04:05:4210166
10167 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110168 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:4210169 const HttpResponseInfo* response = trans->GetResponseInfo();
10170
wezca1070932016-05-26 20:30:5210171 ASSERT_TRUE(response);
tbansal8ef1d3e2016-02-03 04:05:4210172 EXPECT_TRUE(response->headers->IsKeepAlive());
10173
10174 EXPECT_EQ(200, response->headers->response_code());
10175 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10176
10177 std::string response_data;
10178 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:0110179 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:4210180 EXPECT_EQ("hello!", response_data);
10181
10182 trans.reset();
10183 session->CloseAllConnections();
10184}
10185
[email protected]2df19bb2010-08-25 20:13:4610186// Test HTTPS connections to a site with a bad certificate, going through an
10187// HTTPS proxy
bncd16676a2016-07-20 16:23:0110188TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
Ramin Halavatica8d5252018-03-12 05:33:4910189 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
10190 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:4610191
10192 HttpRequestInfo request;
10193 request.method = "GET";
bncce36dca22015-04-21 22:11:2310194 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010195 request.traffic_annotation =
10196 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:4610197
10198 // Attempt to fetch the URL from a server with a bad cert
10199 MockWrite bad_cert_writes[] = {
rsleevidb16bb02015-11-12 23:47:1710200 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
10201 "Host: www.example.org:443\r\n"
10202 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:4610203 };
10204
10205 MockRead bad_cert_reads[] = {
10206 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610207 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:4610208 };
10209
10210 // Attempt to fetch the URL with a good cert
10211 MockWrite good_data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1710212 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
10213 "Host: www.example.org:443\r\n"
10214 "Proxy-Connection: keep-alive\r\n\r\n"),
10215 MockWrite("GET / HTTP/1.1\r\n"
10216 "Host: www.example.org\r\n"
10217 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:4610218 };
10219
10220 MockRead good_cert_reads[] = {
10221 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
10222 MockRead("HTTP/1.0 200 OK\r\n"),
10223 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10224 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610225 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:4610226 };
10227
Ryan Sleevib8d7ea02018-05-07 20:01:0110228 StaticSocketDataProvider ssl_bad_certificate(bad_cert_reads, bad_cert_writes);
10229 StaticSocketDataProvider data(good_cert_reads, good_data_writes);
[email protected]8ddf8322012-02-23 18:08:0610230 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
10231 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:4610232
10233 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:0710234 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10235 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
10236 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:4610237
10238 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:0710239 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10240 session_deps_.socket_factory->AddSocketDataProvider(&data);
10241 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:4610242
[email protected]49639fa2011-12-20 23:22:4110243 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:4610244
danakj1fd259a02016-04-16 03:17:0910245 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610246 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:4610247
tfarina42834112016-09-22 13:38:2010248 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110249 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:4610250
10251 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110252 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]2df19bb2010-08-25 20:13:4610253
bnc691fda62016-08-12 00:43:1610254 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:0110255 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:4610256
10257 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110258 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:4610259
bnc691fda62016-08-12 00:43:1610260 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:4610261
wezca1070932016-05-26 20:30:5210262 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:4610263 EXPECT_EQ(100, response->headers->GetContentLength());
10264}
10265
bncd16676a2016-07-20 16:23:0110266TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:4210267 HttpRequestInfo request;
10268 request.method = "GET";
bncce36dca22015-04-21 22:11:2310269 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:4310270 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
10271 "Chromium Ultra Awesome X Edition");
Ramin Halavatib5e433e2018-02-07 07:41:1010272 request.traffic_annotation =
10273 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210274
danakj1fd259a02016-04-16 03:17:0910275 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610276 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710277
[email protected]1c773ea12009-04-28 19:58:4210278 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310279 MockWrite(
10280 "GET / HTTP/1.1\r\n"
10281 "Host: www.example.org\r\n"
10282 "Connection: keep-alive\r\n"
10283 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210284 };
10285
10286 // Lastly, the server responds with the actual content.
10287 MockRead data_reads[] = {
10288 MockRead("HTTP/1.0 200 OK\r\n"),
10289 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10290 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610291 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210292 };
10293
Ryan Sleevib8d7ea02018-05-07 20:01:0110294 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710295 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210296
[email protected]49639fa2011-12-20 23:22:4110297 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210298
tfarina42834112016-09-22 13:38:2010299 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110300 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210301
10302 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110303 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210304}
10305
bncd16676a2016-07-20 16:23:0110306TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:2910307 HttpRequestInfo request;
10308 request.method = "GET";
bncce36dca22015-04-21 22:11:2310309 request.url = GURL("https://www.example.org/");
[email protected]da81f132010-08-18 23:39:2910310 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
10311 "Chromium Ultra Awesome X Edition");
Ramin Halavatib5e433e2018-02-07 07:41:1010312 request.traffic_annotation =
10313 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]da81f132010-08-18 23:39:2910314
Ramin Halavatica8d5252018-03-12 05:33:4910315 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
10316 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:0910317 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610318 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710319
[email protected]da81f132010-08-18 23:39:2910320 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1710321 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
10322 "Host: www.example.org:443\r\n"
10323 "Proxy-Connection: keep-alive\r\n"
10324 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]da81f132010-08-18 23:39:2910325 };
10326 MockRead data_reads[] = {
10327 // Return an error, so the transaction stops here (this test isn't
10328 // interested in the rest).
10329 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
10330 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
10331 MockRead("Proxy-Connection: close\r\n\r\n"),
10332 };
10333
Ryan Sleevib8d7ea02018-05-07 20:01:0110334 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710335 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:2910336
[email protected]49639fa2011-12-20 23:22:4110337 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:2910338
tfarina42834112016-09-22 13:38:2010339 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110340 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]da81f132010-08-18 23:39:2910341
10342 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110343 EXPECT_THAT(rv, IsOk());
[email protected]da81f132010-08-18 23:39:2910344}
10345
bncd16676a2016-07-20 16:23:0110346TEST_F(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:4210347 HttpRequestInfo request;
10348 request.method = "GET";
bncce36dca22015-04-21 22:11:2310349 request.url = GURL("http://www.example.org/");
[email protected]c10450102011-06-27 09:06:1610350 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
10351 "http://the.previous.site.com/");
Ramin Halavatib5e433e2018-02-07 07:41:1010352 request.traffic_annotation =
10353 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210354
danakj1fd259a02016-04-16 03:17:0910355 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610356 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710357
[email protected]1c773ea12009-04-28 19:58:4210358 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310359 MockWrite(
10360 "GET / HTTP/1.1\r\n"
10361 "Host: www.example.org\r\n"
10362 "Connection: keep-alive\r\n"
10363 "Referer: http://the.previous.site.com/\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210364 };
10365
10366 // Lastly, the server responds with the actual content.
10367 MockRead data_reads[] = {
10368 MockRead("HTTP/1.0 200 OK\r\n"),
10369 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10370 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610371 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210372 };
10373
Ryan Sleevib8d7ea02018-05-07 20:01:0110374 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710375 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210376
[email protected]49639fa2011-12-20 23:22:4110377 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210378
tfarina42834112016-09-22 13:38:2010379 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110380 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210381
10382 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110383 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210384}
10385
bncd16676a2016-07-20 16:23:0110386TEST_F(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:4210387 HttpRequestInfo request;
10388 request.method = "POST";
bncce36dca22015-04-21 22:11:2310389 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010390 request.traffic_annotation =
10391 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210392
danakj1fd259a02016-04-16 03:17:0910393 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610394 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710395
[email protected]1c773ea12009-04-28 19:58:4210396 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310397 MockWrite(
10398 "POST / HTTP/1.1\r\n"
10399 "Host: www.example.org\r\n"
10400 "Connection: keep-alive\r\n"
10401 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210402 };
10403
10404 // Lastly, the server responds with the actual content.
10405 MockRead data_reads[] = {
10406 MockRead("HTTP/1.0 200 OK\r\n"),
10407 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10408 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610409 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210410 };
10411
Ryan Sleevib8d7ea02018-05-07 20:01:0110412 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710413 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210414
[email protected]49639fa2011-12-20 23:22:4110415 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210416
tfarina42834112016-09-22 13:38:2010417 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110418 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210419
10420 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110421 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210422}
10423
bncd16676a2016-07-20 16:23:0110424TEST_F(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:4210425 HttpRequestInfo request;
10426 request.method = "PUT";
bncce36dca22015-04-21 22:11:2310427 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010428 request.traffic_annotation =
10429 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210430
danakj1fd259a02016-04-16 03:17:0910431 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610432 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710433
[email protected]1c773ea12009-04-28 19:58:4210434 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310435 MockWrite(
10436 "PUT / HTTP/1.1\r\n"
10437 "Host: www.example.org\r\n"
10438 "Connection: keep-alive\r\n"
10439 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210440 };
10441
10442 // Lastly, the server responds with the actual content.
10443 MockRead data_reads[] = {
10444 MockRead("HTTP/1.0 200 OK\r\n"),
10445 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10446 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610447 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210448 };
10449
Ryan Sleevib8d7ea02018-05-07 20:01:0110450 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710451 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210452
[email protected]49639fa2011-12-20 23:22:4110453 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210454
tfarina42834112016-09-22 13:38:2010455 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110456 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210457
10458 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110459 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210460}
10461
bncd16676a2016-07-20 16:23:0110462TEST_F(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:4210463 HttpRequestInfo request;
10464 request.method = "HEAD";
bncce36dca22015-04-21 22:11:2310465 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010466 request.traffic_annotation =
10467 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210468
danakj1fd259a02016-04-16 03:17:0910469 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610470 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710471
[email protected]1c773ea12009-04-28 19:58:4210472 MockWrite data_writes[] = {
csharrisonf473dd192015-08-18 13:54:1310473 MockWrite("HEAD / HTTP/1.1\r\n"
10474 "Host: www.example.org\r\n"
10475 "Connection: keep-alive\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210476 };
10477
10478 // Lastly, the server responds with the actual content.
10479 MockRead data_reads[] = {
10480 MockRead("HTTP/1.0 200 OK\r\n"),
10481 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10482 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610483 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210484 };
10485
Ryan Sleevib8d7ea02018-05-07 20:01:0110486 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710487 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210488
[email protected]49639fa2011-12-20 23:22:4110489 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210490
tfarina42834112016-09-22 13:38:2010491 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110492 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210493
10494 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110495 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210496}
10497
bncd16676a2016-07-20 16:23:0110498TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:4210499 HttpRequestInfo request;
10500 request.method = "GET";
bncce36dca22015-04-21 22:11:2310501 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:4210502 request.load_flags = LOAD_BYPASS_CACHE;
Ramin Halavatib5e433e2018-02-07 07:41:1010503 request.traffic_annotation =
10504 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210505
danakj1fd259a02016-04-16 03:17:0910506 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610507 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710508
[email protected]1c773ea12009-04-28 19:58:4210509 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310510 MockWrite(
10511 "GET / HTTP/1.1\r\n"
10512 "Host: www.example.org\r\n"
10513 "Connection: keep-alive\r\n"
10514 "Pragma: no-cache\r\n"
10515 "Cache-Control: no-cache\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210516 };
10517
10518 // Lastly, the server responds with the actual content.
10519 MockRead data_reads[] = {
10520 MockRead("HTTP/1.0 200 OK\r\n"),
10521 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10522 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610523 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210524 };
10525
Ryan Sleevib8d7ea02018-05-07 20:01:0110526 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710527 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210528
[email protected]49639fa2011-12-20 23:22:4110529 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210530
tfarina42834112016-09-22 13:38:2010531 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110532 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210533
10534 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110535 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210536}
10537
bncd16676a2016-07-20 16:23:0110538TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:4210539 HttpRequestInfo request;
10540 request.method = "GET";
bncce36dca22015-04-21 22:11:2310541 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:4210542 request.load_flags = LOAD_VALIDATE_CACHE;
Ramin Halavatib5e433e2018-02-07 07:41:1010543 request.traffic_annotation =
10544 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210545
danakj1fd259a02016-04-16 03:17:0910546 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610547 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710548
[email protected]1c773ea12009-04-28 19:58:4210549 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310550 MockWrite(
10551 "GET / HTTP/1.1\r\n"
10552 "Host: www.example.org\r\n"
10553 "Connection: keep-alive\r\n"
10554 "Cache-Control: max-age=0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210555 };
10556
10557 // Lastly, the server responds with the actual content.
10558 MockRead data_reads[] = {
10559 MockRead("HTTP/1.0 200 OK\r\n"),
10560 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10561 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610562 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210563 };
10564
Ryan Sleevib8d7ea02018-05-07 20:01:0110565 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710566 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210567
[email protected]49639fa2011-12-20 23:22:4110568 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210569
tfarina42834112016-09-22 13:38:2010570 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110571 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210572
10573 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110574 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210575}
10576
bncd16676a2016-07-20 16:23:0110577TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:4210578 HttpRequestInfo request;
10579 request.method = "GET";
bncce36dca22015-04-21 22:11:2310580 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:4310581 request.extra_headers.SetHeader("FooHeader", "Bar");
Ramin Halavatib5e433e2018-02-07 07:41:1010582 request.traffic_annotation =
10583 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210584
danakj1fd259a02016-04-16 03:17:0910585 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610586 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710587
[email protected]1c773ea12009-04-28 19:58:4210588 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310589 MockWrite(
10590 "GET / HTTP/1.1\r\n"
10591 "Host: www.example.org\r\n"
10592 "Connection: keep-alive\r\n"
10593 "FooHeader: Bar\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210594 };
10595
10596 // Lastly, the server responds with the actual content.
10597 MockRead data_reads[] = {
10598 MockRead("HTTP/1.0 200 OK\r\n"),
10599 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10600 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610601 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210602 };
10603
Ryan Sleevib8d7ea02018-05-07 20:01:0110604 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710605 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210606
[email protected]49639fa2011-12-20 23:22:4110607 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210608
tfarina42834112016-09-22 13:38:2010609 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110610 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210611
10612 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110613 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210614}
10615
bncd16676a2016-07-20 16:23:0110616TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:4710617 HttpRequestInfo request;
10618 request.method = "GET";
bncce36dca22015-04-21 22:11:2310619 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:4310620 request.extra_headers.SetHeader("referer", "www.foo.com");
10621 request.extra_headers.SetHeader("hEllo", "Kitty");
10622 request.extra_headers.SetHeader("FoO", "bar");
Ramin Halavatib5e433e2018-02-07 07:41:1010623 request.traffic_annotation =
10624 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]270c6412010-03-29 22:02:4710625
danakj1fd259a02016-04-16 03:17:0910626 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610627 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710628
[email protected]270c6412010-03-29 22:02:4710629 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310630 MockWrite(
10631 "GET / HTTP/1.1\r\n"
10632 "Host: www.example.org\r\n"
10633 "Connection: keep-alive\r\n"
10634 "referer: www.foo.com\r\n"
10635 "hEllo: Kitty\r\n"
10636 "FoO: bar\r\n\r\n"),
[email protected]270c6412010-03-29 22:02:4710637 };
10638
10639 // Lastly, the server responds with the actual content.
10640 MockRead data_reads[] = {
10641 MockRead("HTTP/1.0 200 OK\r\n"),
10642 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10643 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610644 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:4710645 };
10646
Ryan Sleevib8d7ea02018-05-07 20:01:0110647 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710648 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:4710649
[email protected]49639fa2011-12-20 23:22:4110650 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:4710651
tfarina42834112016-09-22 13:38:2010652 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110653 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]270c6412010-03-29 22:02:4710654
10655 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110656 EXPECT_THAT(rv, IsOk());
[email protected]270c6412010-03-29 22:02:4710657}
10658
bncd16676a2016-07-20 16:23:0110659TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:2710660 HttpRequestInfo request;
10661 request.method = "GET";
bncce36dca22015-04-21 22:11:2310662 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010663 request.traffic_annotation =
10664 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710665
Lily Houghton8c2f97d2018-01-22 05:06:5910666 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910667 ProxyResolutionService::CreateFixedFromPacResult(
10668 "SOCKS myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110669 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710670 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:0210671
danakj1fd259a02016-04-16 03:17:0910672 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610673 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:0210674
[email protected]3cd17242009-06-23 02:59:0210675 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
10676 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
10677
10678 MockWrite data_writes[] = {
Avi Drissman4365a4782018-12-28 19:26:2410679 MockWrite(ASYNC, write_buffer, base::size(write_buffer)),
10680 MockWrite("GET / HTTP/1.1\r\n"
10681 "Host: www.example.org\r\n"
10682 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:0210683
10684 MockRead data_reads[] = {
Avi Drissman4365a4782018-12-28 19:26:2410685 MockRead(ASYNC, read_buffer, base::size(read_buffer)),
10686 MockRead("HTTP/1.0 200 OK\r\n"),
10687 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
10688 MockRead("Payload"), MockRead(SYNCHRONOUS, OK)};
[email protected]3cd17242009-06-23 02:59:0210689
Ryan Sleevib8d7ea02018-05-07 20:01:0110690 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710691 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:0210692
[email protected]49639fa2011-12-20 23:22:4110693 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:0210694
tfarina42834112016-09-22 13:38:2010695 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110696 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:0210697
10698 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110699 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0210700
bnc691fda62016-08-12 00:43:1610701 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210702 ASSERT_TRUE(response);
[email protected]3cd17242009-06-23 02:59:0210703
tbansal2ecbbc72016-10-06 17:15:4710704 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]029c83b62013-01-24 05:28:2010705 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1610706 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2010707 TestLoadTimingNotReusedWithPac(load_timing_info,
10708 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
10709
[email protected]3cd17242009-06-23 02:59:0210710 std::string response_text;
bnc691fda62016-08-12 00:43:1610711 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0110712 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0210713 EXPECT_EQ("Payload", response_text);
10714}
10715
bncd16676a2016-07-20 16:23:0110716TEST_F(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:2710717 HttpRequestInfo request;
10718 request.method = "GET";
bncce36dca22015-04-21 22:11:2310719 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010720 request.traffic_annotation =
10721 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710722
Lily Houghton8c2f97d2018-01-22 05:06:5910723 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910724 ProxyResolutionService::CreateFixedFromPacResult(
10725 "SOCKS myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110726 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710727 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:0210728
danakj1fd259a02016-04-16 03:17:0910729 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610730 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:0210731
[email protected]3cd17242009-06-23 02:59:0210732 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
10733 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
10734
10735 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310736 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
Avi Drissman4365a4782018-12-28 19:26:2410737 base::size(write_buffer)),
10738 MockWrite("GET / HTTP/1.1\r\n"
10739 "Host: www.example.org\r\n"
10740 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:0210741
10742 MockRead data_reads[] = {
Avi Drissman4365a4782018-12-28 19:26:2410743 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
10744 base::size(read_buffer)),
10745 MockRead("HTTP/1.0 200 OK\r\n"),
10746 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
10747 MockRead("Payload"), MockRead(SYNCHRONOUS, OK)};
[email protected]e0c27be2009-07-15 13:09:3510748
Ryan Sleevib8d7ea02018-05-07 20:01:0110749 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710750 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:3510751
[email protected]8ddf8322012-02-23 18:08:0610752 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710753 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:3510754
[email protected]49639fa2011-12-20 23:22:4110755 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:3510756
tfarina42834112016-09-22 13:38:2010757 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110758 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:3510759
10760 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110761 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3510762
[email protected]029c83b62013-01-24 05:28:2010763 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1610764 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2010765 TestLoadTimingNotReusedWithPac(load_timing_info,
10766 CONNECT_TIMING_HAS_SSL_TIMES);
10767
bnc691fda62016-08-12 00:43:1610768 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210769 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:4710770 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:3510771
10772 std::string response_text;
bnc691fda62016-08-12 00:43:1610773 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0110774 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3510775 EXPECT_EQ("Payload", response_text);
10776}
10777
bncd16676a2016-07-20 16:23:0110778TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:2010779 HttpRequestInfo request;
10780 request.method = "GET";
bncce36dca22015-04-21 22:11:2310781 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010782 request.traffic_annotation =
10783 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:2010784
Ramin Halavatica8d5252018-03-12 05:33:4910785 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
10786 "socks4://myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110787 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710788 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:2010789
danakj1fd259a02016-04-16 03:17:0910790 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610791 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:2010792
10793 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
10794 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
10795
10796 MockWrite data_writes[] = {
Avi Drissman4365a4782018-12-28 19:26:2410797 MockWrite(ASYNC, write_buffer, base::size(write_buffer)),
10798 MockWrite("GET / HTTP/1.1\r\n"
10799 "Host: www.example.org\r\n"
10800 "Connection: keep-alive\r\n\r\n")};
[email protected]029c83b62013-01-24 05:28:2010801
10802 MockRead data_reads[] = {
Avi Drissman4365a4782018-12-28 19:26:2410803 MockRead(ASYNC, read_buffer, base::size(read_buffer)),
10804 MockRead("HTTP/1.0 200 OK\r\n"),
10805 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
10806 MockRead("Payload"), MockRead(SYNCHRONOUS, OK)};
[email protected]029c83b62013-01-24 05:28:2010807
Ryan Sleevib8d7ea02018-05-07 20:01:0110808 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710809 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:2010810
10811 TestCompletionCallback callback;
10812
tfarina42834112016-09-22 13:38:2010813 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110814 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:2010815
10816 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110817 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:2010818
bnc691fda62016-08-12 00:43:1610819 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210820 ASSERT_TRUE(response);
[email protected]029c83b62013-01-24 05:28:2010821
10822 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1610823 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2010824 TestLoadTimingNotReused(load_timing_info,
10825 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
10826
10827 std::string response_text;
bnc691fda62016-08-12 00:43:1610828 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0110829 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:2010830 EXPECT_EQ("Payload", response_text);
10831}
10832
bncd16676a2016-07-20 16:23:0110833TEST_F(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:2710834 HttpRequestInfo request;
10835 request.method = "GET";
bncce36dca22015-04-21 22:11:2310836 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010837 request.traffic_annotation =
10838 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710839
Lily Houghton8c2f97d2018-01-22 05:06:5910840 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910841 ProxyResolutionService::CreateFixedFromPacResult(
10842 "SOCKS5 myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110843 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710844 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:3510845
danakj1fd259a02016-04-16 03:17:0910846 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610847 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:3510848
[email protected]e0c27be2009-07-15 13:09:3510849 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
10850 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:3710851 const char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:2310852 0x05, // Version
10853 0x01, // Command (CONNECT)
10854 0x00, // Reserved.
10855 0x03, // Address type (DOMAINNAME).
10856 0x0F, // Length of domain (15)
10857 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
10858 '.', 'o', 'r', 'g', 0x00, 0x50, // 16-bit port (80)
[email protected]f209dba2009-12-18 00:24:3710859 };
[email protected]e0c27be2009-07-15 13:09:3510860 const char kSOCKS5OkResponse[] =
10861 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
10862
10863 MockWrite data_writes[] = {
Avi Drissman4365a4782018-12-28 19:26:2410864 MockWrite(ASYNC, kSOCKS5GreetRequest, base::size(kSOCKS5GreetRequest)),
10865 MockWrite(ASYNC, kSOCKS5OkRequest, base::size(kSOCKS5OkRequest)),
10866 MockWrite("GET / HTTP/1.1\r\n"
10867 "Host: www.example.org\r\n"
10868 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:3510869
10870 MockRead data_reads[] = {
Avi Drissman4365a4782018-12-28 19:26:2410871 MockRead(ASYNC, kSOCKS5GreetResponse, base::size(kSOCKS5GreetResponse)),
10872 MockRead(ASYNC, kSOCKS5OkResponse, base::size(kSOCKS5OkResponse)),
10873 MockRead("HTTP/1.0 200 OK\r\n"),
10874 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
10875 MockRead("Payload"),
10876 MockRead(SYNCHRONOUS, OK)};
[email protected]e0c27be2009-07-15 13:09:3510877
Ryan Sleevib8d7ea02018-05-07 20:01:0110878 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710879 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:3510880
[email protected]49639fa2011-12-20 23:22:4110881 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:3510882
tfarina42834112016-09-22 13:38:2010883 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110884 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:3510885
10886 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110887 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3510888
bnc691fda62016-08-12 00:43:1610889 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210890 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:4710891 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:3510892
[email protected]029c83b62013-01-24 05:28:2010893 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1610894 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2010895 TestLoadTimingNotReusedWithPac(load_timing_info,
10896 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
10897
[email protected]e0c27be2009-07-15 13:09:3510898 std::string response_text;
bnc691fda62016-08-12 00:43:1610899 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0110900 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3510901 EXPECT_EQ("Payload", response_text);
10902}
10903
bncd16676a2016-07-20 16:23:0110904TEST_F(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:2710905 HttpRequestInfo request;
10906 request.method = "GET";
bncce36dca22015-04-21 22:11:2310907 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010908 request.traffic_annotation =
10909 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710910
Lily Houghton8c2f97d2018-01-22 05:06:5910911 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910912 ProxyResolutionService::CreateFixedFromPacResult(
10913 "SOCKS5 myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110914 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710915 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:3510916
danakj1fd259a02016-04-16 03:17:0910917 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610918 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:3510919
[email protected]e0c27be2009-07-15 13:09:3510920 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
10921 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:3710922 const unsigned char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:2310923 0x05, // Version
10924 0x01, // Command (CONNECT)
10925 0x00, // Reserved.
10926 0x03, // Address type (DOMAINNAME).
10927 0x0F, // Length of domain (15)
10928 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
10929 '.', 'o', 'r', 'g', 0x01, 0xBB, // 16-bit port (443)
[email protected]f209dba2009-12-18 00:24:3710930 };
10931
[email protected]e0c27be2009-07-15 13:09:3510932 const char kSOCKS5OkResponse[] =
10933 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
10934
10935 MockWrite data_writes[] = {
Avi Drissman4365a4782018-12-28 19:26:2410936 MockWrite(ASYNC, kSOCKS5GreetRequest, base::size(kSOCKS5GreetRequest)),
bncce36dca22015-04-21 22:11:2310937 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
Avi Drissman4365a4782018-12-28 19:26:2410938 base::size(kSOCKS5OkRequest)),
10939 MockWrite("GET / HTTP/1.1\r\n"
10940 "Host: www.example.org\r\n"
10941 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:3510942
10943 MockRead data_reads[] = {
Avi Drissman4365a4782018-12-28 19:26:2410944 MockRead(ASYNC, kSOCKS5GreetResponse, base::size(kSOCKS5GreetResponse)),
10945 MockRead(ASYNC, kSOCKS5OkResponse, base::size(kSOCKS5OkResponse)),
10946 MockRead("HTTP/1.0 200 OK\r\n"),
10947 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
10948 MockRead("Payload"),
10949 MockRead(SYNCHRONOUS, OK)};
[email protected]3cd17242009-06-23 02:59:0210950
Ryan Sleevib8d7ea02018-05-07 20:01:0110951 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710952 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:0210953
[email protected]8ddf8322012-02-23 18:08:0610954 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710955 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:0210956
[email protected]49639fa2011-12-20 23:22:4110957 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:0210958
tfarina42834112016-09-22 13:38:2010959 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110960 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:0210961
10962 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110963 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0210964
bnc691fda62016-08-12 00:43:1610965 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210966 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:4710967 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]3cd17242009-06-23 02:59:0210968
[email protected]029c83b62013-01-24 05:28:2010969 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1610970 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2010971 TestLoadTimingNotReusedWithPac(load_timing_info,
10972 CONNECT_TIMING_HAS_SSL_TIMES);
10973
[email protected]3cd17242009-06-23 02:59:0210974 std::string response_text;
bnc691fda62016-08-12 00:43:1610975 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0110976 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0210977 EXPECT_EQ("Payload", response_text);
10978}
10979
[email protected]448d4ca52012-03-04 04:12:2310980namespace {
10981
[email protected]04e5be32009-06-26 20:00:3110982// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:0610983
10984struct GroupNameTest {
10985 std::string proxy_server;
10986 std::string url;
10987 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:1810988 bool ssl;
[email protected]2d731a32010-04-29 01:04:0610989};
10990
danakj1fd259a02016-04-16 03:17:0910991std::unique_ptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]bb88e1d32013-05-03 23:11:0710992 SpdySessionDependencies* session_deps_) {
danakj1fd259a02016-04-16 03:17:0910993 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:0610994
bnc525e175a2016-06-20 12:36:4010995 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310996 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110997 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnc7dc7e1b42015-07-28 14:43:1210998 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110999 http_server_properties->SetHttp2AlternativeService(
bncaa60ff402016-06-22 19:12:4211000 url::SchemeHostPort("https", "host.with.alternate", 443),
zhongyi3d4a55e72016-04-22 20:36:4611001 alternative_service, expiration);
[email protected]2d731a32010-04-29 01:04:0611002
11003 return session;
11004}
11005
mmenkee65e7af2015-10-13 17:16:4211006int GroupNameTransactionHelper(const std::string& url,
11007 HttpNetworkSession* session) {
[email protected]2d731a32010-04-29 01:04:0611008 HttpRequestInfo request;
11009 request.method = "GET";
11010 request.url = GURL(url);
Ramin Halavatib5e433e2018-02-07 07:41:1011011 request.traffic_annotation =
11012 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d731a32010-04-29 01:04:0611013
bnc691fda62016-08-12 00:43:1611014 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
[email protected]cb9bf6ca2011-01-28 13:15:2711015
[email protected]49639fa2011-12-20 23:22:4111016 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:0611017
11018 // We do not complete this request, the dtor will clean the transaction up.
tfarina42834112016-09-22 13:38:2011019 return trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]2d731a32010-04-29 01:04:0611020}
11021
[email protected]448d4ca52012-03-04 04:12:2311022} // namespace
11023
bncd16676a2016-07-20 16:23:0111024TEST_F(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:0611025 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:2311026 {
11027 "", // unused
11028 "http://www.example.org/direct",
11029 "www.example.org:80",
11030 false,
11031 },
11032 {
11033 "", // unused
11034 "http://[2001:1418:13:1::25]/direct",
11035 "[2001:1418:13:1::25]:80",
11036 false,
11037 },
[email protected]04e5be32009-06-26 20:00:3111038
bncce36dca22015-04-21 22:11:2311039 // SSL Tests
11040 {
11041 "", // unused
11042 "https://www.example.org/direct_ssl",
11043 "ssl/www.example.org:443",
11044 true,
11045 },
11046 {
11047 "", // unused
11048 "https://[2001:1418:13:1::25]/direct",
11049 "ssl/[2001:1418:13:1::25]:443",
11050 true,
11051 },
11052 {
11053 "", // unused
bncaa60ff402016-06-22 19:12:4211054 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:2311055 "ssl/host.with.alternate:443",
11056 true,
11057 },
[email protected]2d731a32010-04-29 01:04:0611058 };
[email protected]2ff8b312010-04-26 22:20:5411059
Avi Drissman4365a4782018-12-28 19:26:2411060 for (size_t i = 0; i < base::size(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5911061 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4911062 ProxyResolutionService::CreateFixed(tests[i].proxy_server,
11063 TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:0911064 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:4011065 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:0611066
mmenkee65e7af2015-10-13 17:16:4211067 HttpNetworkSessionPeer peer(session.get());
[email protected]ab739042011-04-07 15:22:2811068 CaptureGroupNameTransportSocketPool* transport_conn_pool =
bnc87dcefc2017-05-25 12:47:5811069 new CaptureGroupNameTransportSocketPool(nullptr, nullptr);
[email protected]2431756e2010-09-29 20:26:1311070 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
bnc87dcefc2017-05-25 12:47:5811071 new CaptureGroupNameSSLSocketPool(nullptr, nullptr);
Jeremy Roman0579ed62017-08-29 15:56:1911072 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
[email protected]a42dbd142011-11-17 16:42:0211073 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
11074 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
dchengc7eeda422015-12-26 03:56:4811075 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:0611076
11077 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:4211078 GroupNameTransactionHelper(tests[i].url, session.get()));
Tarun Bansal162eabe52018-01-20 01:16:3911079 if (tests[i].ssl) {
[email protected]e60e47a2010-07-14 03:37:1811080 EXPECT_EQ(tests[i].expected_group_name,
11081 ssl_conn_pool->last_group_name_received());
Tarun Bansal162eabe52018-01-20 01:16:3911082 } else {
[email protected]e60e47a2010-07-14 03:37:1811083 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:2811084 transport_conn_pool->last_group_name_received());
Tarun Bansal162eabe52018-01-20 01:16:3911085 }
11086 // When SSL proxy is in use, socket must be requested from |ssl_conn_pool|.
11087 EXPECT_EQ(tests[i].ssl, ssl_conn_pool->socket_requested());
11088 // When SSL proxy is not in use, socket must be requested from
11089 // |transport_conn_pool|.
11090 EXPECT_EQ(!tests[i].ssl, transport_conn_pool->socket_requested());
[email protected]2d731a32010-04-29 01:04:0611091 }
[email protected]2d731a32010-04-29 01:04:0611092}
11093
bncd16676a2016-07-20 16:23:0111094TEST_F(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:0611095 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:2311096 {
Matt Menked1eb6d42018-01-17 04:54:0611097 "http_proxy", "http://www.example.org/http_proxy_normal",
11098 "http_proxy/www.example.org:80", false,
bncce36dca22015-04-21 22:11:2311099 },
[email protected]2d731a32010-04-29 01:04:0611100
bncce36dca22015-04-21 22:11:2311101 // SSL Tests
11102 {
Matt Menked1eb6d42018-01-17 04:54:0611103 "http_proxy", "https://www.example.org/http_connect_ssl",
11104 "http_proxy/ssl/www.example.org:443", true,
bncce36dca22015-04-21 22:11:2311105 },
[email protected]af3490e2010-10-16 21:02:2911106
bncce36dca22015-04-21 22:11:2311107 {
Matt Menked1eb6d42018-01-17 04:54:0611108 "http_proxy", "https://host.with.alternate/direct",
11109 "http_proxy/ssl/host.with.alternate:443", true,
bncce36dca22015-04-21 22:11:2311110 },
[email protected]45499252013-01-23 17:12:5611111
bncce36dca22015-04-21 22:11:2311112 {
Matt Menked1eb6d42018-01-17 04:54:0611113 "http_proxy", "ftp://ftp.google.com/http_proxy_normal",
11114 "http_proxy/ftp/ftp.google.com:21", false,
bncce36dca22015-04-21 22:11:2311115 },
[email protected]2d731a32010-04-29 01:04:0611116 };
11117
Avi Drissman4365a4782018-12-28 19:26:2411118 for (size_t i = 0; i < base::size(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5911119 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4911120 ProxyResolutionService::CreateFixed(tests[i].proxy_server,
11121 TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:0911122 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:4011123 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:0611124
mmenkee65e7af2015-10-13 17:16:4211125 HttpNetworkSessionPeer peer(session.get());
[email protected]2d731a32010-04-29 01:04:0611126
Matt Menkee8648fa2019-01-17 16:47:0711127 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
11128 HostPortPair("http_proxy", 80));
[email protected]2431756e2010-09-29 20:26:1311129 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:3411130 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:1311131 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:3411132 new CaptureGroupNameSSLSocketPool(NULL, NULL);
Jeremy Roman0579ed62017-08-29 15:56:1911133 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
aviadef3442016-10-03 18:50:3911134 mock_pool_manager->SetSocketPoolForHTTPProxy(
Matt Menkee8648fa2019-01-17 16:47:0711135 proxy_server, base::WrapUnique(http_proxy_pool));
aviadef3442016-10-03 18:50:3911136 mock_pool_manager->SetSocketPoolForSSLWithProxy(
Matt Menkee8648fa2019-01-17 16:47:0711137 proxy_server, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:4811138 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:0611139
11140 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:4211141 GroupNameTransactionHelper(tests[i].url, session.get()));
Matt Menkee8648fa2019-01-17 16:47:0711142 if (tests[i].ssl) {
[email protected]e60e47a2010-07-14 03:37:1811143 EXPECT_EQ(tests[i].expected_group_name,
11144 ssl_conn_pool->last_group_name_received());
Matt Menkee8648fa2019-01-17 16:47:0711145 } else {
[email protected]e60e47a2010-07-14 03:37:1811146 EXPECT_EQ(tests[i].expected_group_name,
11147 http_proxy_pool->last_group_name_received());
Matt Menkee8648fa2019-01-17 16:47:0711148 }
[email protected]2d731a32010-04-29 01:04:0611149 }
[email protected]2d731a32010-04-29 01:04:0611150}
11151
bncd16676a2016-07-20 16:23:0111152TEST_F(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:0611153 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:2311154 {
11155 "socks4://socks_proxy:1080",
11156 "http://www.example.org/socks4_direct",
11157 "socks4/www.example.org:80",
11158 false,
11159 },
11160 {
11161 "socks5://socks_proxy:1080",
11162 "http://www.example.org/socks5_direct",
11163 "socks5/www.example.org:80",
11164 false,
11165 },
[email protected]2d731a32010-04-29 01:04:0611166
bncce36dca22015-04-21 22:11:2311167 // SSL Tests
11168 {
11169 "socks4://socks_proxy:1080",
11170 "https://www.example.org/socks4_ssl",
11171 "socks4/ssl/www.example.org:443",
11172 true,
11173 },
11174 {
11175 "socks5://socks_proxy:1080",
11176 "https://www.example.org/socks5_ssl",
11177 "socks5/ssl/www.example.org:443",
11178 true,
11179 },
[email protected]af3490e2010-10-16 21:02:2911180
bncce36dca22015-04-21 22:11:2311181 {
11182 "socks4://socks_proxy:1080",
bncaa60ff402016-06-22 19:12:4211183 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:2311184 "socks4/ssl/host.with.alternate:443",
11185 true,
11186 },
[email protected]04e5be32009-06-26 20:00:3111187 };
11188
Avi Drissman4365a4782018-12-28 19:26:2411189 for (size_t i = 0; i < base::size(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5911190 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4911191 ProxyResolutionService::CreateFixed(tests[i].proxy_server,
11192 TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:0911193 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:4011194 SetupSessionForGroupNameTests(&session_deps_));
[email protected]8b114dd72011-03-25 05:33:0211195
mmenkee65e7af2015-10-13 17:16:4211196 HttpNetworkSessionPeer peer(session.get());
[email protected]04e5be32009-06-26 20:00:3111197
Matt Menkee8648fa2019-01-17 16:47:0711198 ProxyServer proxy_server(
11199 ProxyServer::FromURI(tests[i].proxy_server, ProxyServer::SCHEME_HTTP));
11200 ASSERT_TRUE(proxy_server.is_valid());
[email protected]2431756e2010-09-29 20:26:1311201 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:3411202 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:1311203 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:3411204 new CaptureGroupNameSSLSocketPool(NULL, NULL);
Jeremy Roman0579ed62017-08-29 15:56:1911205 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
aviadef3442016-10-03 18:50:3911206 mock_pool_manager->SetSocketPoolForSOCKSProxy(
Matt Menkee8648fa2019-01-17 16:47:0711207 proxy_server, base::WrapUnique(socks_conn_pool));
aviadef3442016-10-03 18:50:3911208 mock_pool_manager->SetSocketPoolForSSLWithProxy(
Matt Menkee8648fa2019-01-17 16:47:0711209 proxy_server, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:4811210 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]04e5be32009-06-26 20:00:3111211
bnc691fda62016-08-12 00:43:1611212 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]04e5be32009-06-26 20:00:3111213
[email protected]2d731a32010-04-29 01:04:0611214 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:4211215 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:1811216 if (tests[i].ssl)
11217 EXPECT_EQ(tests[i].expected_group_name,
11218 ssl_conn_pool->last_group_name_received());
11219 else
11220 EXPECT_EQ(tests[i].expected_group_name,
11221 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:3111222 }
11223}
11224
bncd16676a2016-07-20 16:23:0111225TEST_F(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:2711226 HttpRequestInfo request;
11227 request.method = "GET";
bncce36dca22015-04-21 22:11:2311228 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011229 request.traffic_annotation =
11230 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2711231
Ramin Halavatica8d5252018-03-12 05:33:4911232 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
11233 "myproxy:70;foobar:80", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]b59ff372009-07-15 22:04:3211234
[email protected]69719062010-01-05 20:09:2111235 // This simulates failure resolving all hostnames; that means we will fail
11236 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:0711237 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:3211238
danakj1fd259a02016-04-16 03:17:0911239 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611240 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]9172a982009-06-06 00:30:2511241
[email protected]49639fa2011-12-20 23:22:4111242 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:2511243
tfarina42834112016-09-22 13:38:2011244 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111245 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9172a982009-06-06 00:30:2511246
[email protected]9172a982009-06-06 00:30:2511247 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111248 EXPECT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]9172a982009-06-06 00:30:2511249}
11250
Miriam Gershenson2a01b162018-03-22 22:54:4711251// LOAD_BYPASS_CACHE should trigger the host cache bypass.
11252TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh) {
[email protected]cb9bf6ca2011-01-28 13:15:2711253 // Issue a request, asking to bypass the cache(s).
maksim.sisov31452af2016-07-27 06:38:1011254 HttpRequestInfo request_info;
11255 request_info.method = "GET";
Miriam Gershenson2a01b162018-03-22 22:54:4711256 request_info.load_flags = LOAD_BYPASS_CACHE;
maksim.sisov31452af2016-07-27 06:38:1011257 request_info.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011258 request_info.traffic_annotation =
11259 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2711260
[email protected]a2c2fb92009-07-18 07:31:0411261 // Select a host resolver that does caching.
Jeremy Roman0579ed62017-08-29 15:56:1911262 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
[email protected]b59ff372009-07-15 22:04:3211263
danakj1fd259a02016-04-16 03:17:0911264 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611265 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3b9cca42009-06-16 01:08:2811266
bncce36dca22015-04-21 22:11:2311267 // Warm up the host cache so it has an entry for "www.example.org".
[email protected]3b9cca42009-06-16 01:08:2811268 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:2911269 TestCompletionCallback callback;
maksim.sisov31452af2016-07-27 06:38:1011270 std::unique_ptr<HostResolver::Request> request1;
[email protected]bb88e1d32013-05-03 23:11:0711271 int rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:2311272 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:1011273 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request1,
tfarina42834112016-09-22 13:38:2011274 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111275 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4711276 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111277 EXPECT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:2811278
11279 // Verify that it was added to host cache, by doing a subsequent async lookup
11280 // and confirming it completes synchronously.
maksim.sisov31452af2016-07-27 06:38:1011281 std::unique_ptr<HostResolver::Request> request2;
[email protected]bb88e1d32013-05-03 23:11:0711282 rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:2311283 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:1011284 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request2,
tfarina42834112016-09-22 13:38:2011285 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111286 ASSERT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:2811287
bncce36dca22015-04-21 22:11:2311288 // Inject a failure the next time that "www.example.org" is resolved. This way
[email protected]3b9cca42009-06-16 01:08:2811289 // we can tell if the next lookup hit the cache, or the "network".
11290 // (cache --> success, "network" --> failure).
bncce36dca22015-04-21 22:11:2311291 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.example.org");
[email protected]3b9cca42009-06-16 01:08:2811292
11293 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
11294 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:0611295 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
Ryan Sleevib8d7ea02018-05-07 20:01:0111296 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711297 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:2811298
[email protected]3b9cca42009-06-16 01:08:2811299 // Run the request.
tfarina42834112016-09-22 13:38:2011300 rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111301 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]49639fa2011-12-20 23:22:4111302 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:2811303
11304 // If we bypassed the cache, we would have gotten a failure while resolving
bncce36dca22015-04-21 22:11:2311305 // "www.example.org".
robpercival214763f2016-07-01 23:27:0111306 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]3b9cca42009-06-16 01:08:2811307}
11308
[email protected]0877e3d2009-10-17 22:29:5711309// Make sure we can handle an error when writing the request.
bncd16676a2016-07-20 16:23:0111310TEST_F(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:5711311 HttpRequestInfo request;
11312 request.method = "GET";
11313 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:1011314 request.traffic_annotation =
11315 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5711316
11317 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:0611318 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:5711319 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111320 StaticSocketDataProvider data(base::span<MockRead>(), write_failure);
[email protected]bb88e1d32013-05-03 23:11:0711321 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:0911322 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5711323
[email protected]49639fa2011-12-20 23:22:4111324 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5711325
bnc691fda62016-08-12 00:43:1611326 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5711327
tfarina42834112016-09-22 13:38:2011328 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111329 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5711330
11331 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111332 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:5911333
11334 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1611335 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5911336 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:5711337}
11338
zmo9528c9f42015-08-04 22:12:0811339// Check that a connection closed after the start of the headers finishes ok.
bncd16676a2016-07-20 16:23:0111340TEST_F(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:5711341 HttpRequestInfo request;
11342 request.method = "GET";
11343 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:1011344 request.traffic_annotation =
11345 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5711346
11347 MockRead data_reads[] = {
11348 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:0611349 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:5711350 };
11351
Ryan Sleevib8d7ea02018-05-07 20:01:0111352 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711353 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:0911354 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5711355
[email protected]49639fa2011-12-20 23:22:4111356 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5711357
bnc691fda62016-08-12 00:43:1611358 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5711359
tfarina42834112016-09-22 13:38:2011360 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111361 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5711362
11363 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111364 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:0811365
bnc691fda62016-08-12 00:43:1611366 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211367 ASSERT_TRUE(response);
zmo9528c9f42015-08-04 22:12:0811368
wezca1070932016-05-26 20:30:5211369 EXPECT_TRUE(response->headers);
zmo9528c9f42015-08-04 22:12:0811370 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
11371
11372 std::string response_data;
bnc691fda62016-08-12 00:43:1611373 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0111374 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:0811375 EXPECT_EQ("", response_data);
ttuttled9dbc652015-09-29 20:00:5911376
11377 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1611378 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5911379 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:5711380}
11381
11382// Make sure that a dropped connection while draining the body for auth
11383// restart does the right thing.
bncd16676a2016-07-20 16:23:0111384TEST_F(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:5711385 HttpRequestInfo request;
11386 request.method = "GET";
bncce36dca22015-04-21 22:11:2311387 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011388 request.traffic_annotation =
11389 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5711390
11391 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2311392 MockWrite(
11393 "GET / HTTP/1.1\r\n"
11394 "Host: www.example.org\r\n"
11395 "Connection: keep-alive\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:5711396 };
11397
11398 MockRead data_reads1[] = {
11399 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
11400 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
11401 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11402 MockRead("Content-Length: 14\r\n\r\n"),
11403 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:0611404 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:5711405 };
11406
Ryan Sleevib8d7ea02018-05-07 20:01:0111407 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:0711408 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:5711409
bnc691fda62016-08-12 00:43:1611410 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0877e3d2009-10-17 22:29:5711411 // be issuing -- the final header line contains the credentials.
11412 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:2311413 MockWrite(
11414 "GET / HTTP/1.1\r\n"
11415 "Host: www.example.org\r\n"
11416 "Connection: keep-alive\r\n"
11417 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:5711418 };
11419
11420 // Lastly, the server responds with the actual content.
11421 MockRead data_reads2[] = {
11422 MockRead("HTTP/1.1 200 OK\r\n"),
11423 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11424 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0611425 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:5711426 };
11427
Ryan Sleevib8d7ea02018-05-07 20:01:0111428 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:0711429 session_deps_.socket_factory->AddSocketDataProvider(&data2);
danakj1fd259a02016-04-16 03:17:0911430 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5711431
[email protected]49639fa2011-12-20 23:22:4111432 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:5711433
bnc691fda62016-08-12 00:43:1611434 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5011435
tfarina42834112016-09-22 13:38:2011436 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111437 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5711438
11439 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0111440 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:5711441
bnc691fda62016-08-12 00:43:1611442 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211443 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0411444 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:5711445
[email protected]49639fa2011-12-20 23:22:4111446 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:5711447
bnc691fda62016-08-12 00:43:1611448 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:0111449 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5711450
11451 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0111452 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:5711453
bnc691fda62016-08-12 00:43:1611454 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211455 ASSERT_TRUE(response);
11456 EXPECT_FALSE(response->auth_challenge);
[email protected]0877e3d2009-10-17 22:29:5711457 EXPECT_EQ(100, response->headers->GetContentLength());
11458}
11459
11460// Test HTTPS connections going through a proxy that sends extra data.
bncd16676a2016-07-20 16:23:0111461TEST_F(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
Ramin Halavatica8d5252018-03-12 05:33:4911462 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
11463 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5711464
11465 HttpRequestInfo request;
11466 request.method = "GET";
bncce36dca22015-04-21 22:11:2311467 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011468 request.traffic_annotation =
11469 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5711470
11471 MockRead proxy_reads[] = {
11472 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:0611473 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:5711474 };
11475
Ryan Sleevib8d7ea02018-05-07 20:01:0111476 StaticSocketDataProvider data(proxy_reads, base::span<MockWrite>());
[email protected]8ddf8322012-02-23 18:08:0611477 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:5711478
[email protected]bb88e1d32013-05-03 23:11:0711479 session_deps_.socket_factory->AddSocketDataProvider(&data);
11480 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:5711481
[email protected]49639fa2011-12-20 23:22:4111482 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5711483
[email protected]bb88e1d32013-05-03 23:11:0711484 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:5711485
danakj1fd259a02016-04-16 03:17:0911486 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611487 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5711488
tfarina42834112016-09-22 13:38:2011489 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111490 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5711491
11492 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111493 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]0877e3d2009-10-17 22:29:5711494}
11495
bncd16676a2016-07-20 16:23:0111496TEST_F(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:4611497 HttpRequestInfo request;
11498 request.method = "GET";
bncce36dca22015-04-21 22:11:2311499 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011500 request.traffic_annotation =
11501 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]9492e4a2010-02-24 00:58:4611502
danakj1fd259a02016-04-16 03:17:0911503 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611504 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2711505
[email protected]e22e1362009-11-23 21:31:1211506 MockRead data_reads[] = {
11507 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0611508 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:1211509 };
[email protected]9492e4a2010-02-24 00:58:4611510
Ryan Sleevib8d7ea02018-05-07 20:01:0111511 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711512 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:4611513
[email protected]49639fa2011-12-20 23:22:4111514 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:4611515
tfarina42834112016-09-22 13:38:2011516 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111517 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9492e4a2010-02-24 00:58:4611518
robpercival214763f2016-07-01 23:27:0111519 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]9492e4a2010-02-24 00:58:4611520
bnc691fda62016-08-12 00:43:1611521 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211522 ASSERT_TRUE(response);
[email protected]9492e4a2010-02-24 00:58:4611523
wezca1070932016-05-26 20:30:5211524 EXPECT_TRUE(response->headers);
[email protected]9492e4a2010-02-24 00:58:4611525 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
11526
11527 std::string response_data;
bnc691fda62016-08-12 00:43:1611528 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0111529 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]e22e1362009-11-23 21:31:1211530}
11531
bncd16676a2016-07-20 16:23:0111532TEST_F(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:1511533 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:5211534 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
avibf0746c2015-12-09 19:53:1411535 const uint64_t kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:2111536 UploadFileElementReader::ScopedOverridingContentLengthForTests
11537 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:3311538
danakj1fd259a02016-04-16 03:17:0911539 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:1911540 element_readers.push_back(std::make_unique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:1411541 base::ThreadTaskRunnerHandle::Get().get(), temp_file_path, 0,
ricea2deef682016-09-09 08:04:0711542 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:2211543 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:2711544
11545 HttpRequestInfo request;
11546 request.method = "POST";
bncce36dca22015-04-21 22:11:2311547 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:2711548 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1011549 request.traffic_annotation =
11550 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]329b68b2012-11-14 17:54:2711551
danakj1fd259a02016-04-16 03:17:0911552 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611553 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]95d88ffe2010-02-04 21:25:3311554
11555 MockRead data_reads[] = {
11556 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
11557 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611558 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:3311559 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111560 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711561 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:3311562
[email protected]49639fa2011-12-20 23:22:4111563 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:3311564
tfarina42834112016-09-22 13:38:2011565 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111566 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]95d88ffe2010-02-04 21:25:3311567
11568 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111569 EXPECT_THAT(rv, IsError(ERR_UPLOAD_FILE_CHANGED));
[email protected]95d88ffe2010-02-04 21:25:3311570
bnc691fda62016-08-12 00:43:1611571 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211572 ASSERT_TRUE(response);
[email protected]95d88ffe2010-02-04 21:25:3311573
maksim.sisove869bf52016-06-23 17:11:5211574 EXPECT_FALSE(response->headers);
[email protected]95d88ffe2010-02-04 21:25:3311575
[email protected]dd3aa792013-07-16 19:10:2311576 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:3311577}
11578
bncd16676a2016-07-20 16:23:0111579TEST_F(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:1511580 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:5211581 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:3611582 std::string temp_file_content("Unreadable file.");
lazyboy8df84fc2017-04-12 02:12:4811583 ASSERT_EQ(static_cast<int>(temp_file_content.length()),
11584 base::WriteFile(temp_file, temp_file_content.c_str(),
11585 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:1111586 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:3611587
danakj1fd259a02016-04-16 03:17:0911588 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:1911589 element_readers.push_back(std::make_unique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:1411590 base::ThreadTaskRunnerHandle::Get().get(), temp_file, 0,
ricea2deef682016-09-09 08:04:0711591 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:2211592 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:2711593
11594 HttpRequestInfo request;
11595 request.method = "POST";
bncce36dca22015-04-21 22:11:2311596 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:2711597 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1011598 request.traffic_annotation =
11599 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]329b68b2012-11-14 17:54:2711600
[email protected]999dd8c2013-11-12 06:45:5411601 // If we try to upload an unreadable file, the transaction should fail.
danakj1fd259a02016-04-16 03:17:0911602 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611603 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]6624b4622010-03-29 19:58:3611604
Ryan Sleevib8d7ea02018-05-07 20:01:0111605 StaticSocketDataProvider data;
[email protected]bb88e1d32013-05-03 23:11:0711606 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:3611607
[email protected]49639fa2011-12-20 23:22:4111608 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:3611609
tfarina42834112016-09-22 13:38:2011610 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111611 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6624b4622010-03-29 19:58:3611612
11613 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111614 EXPECT_THAT(rv, IsError(ERR_ACCESS_DENIED));
[email protected]6624b4622010-03-29 19:58:3611615
[email protected]dd3aa792013-07-16 19:10:2311616 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:3611617}
11618
bncd16676a2016-07-20 16:23:0111619TEST_F(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
[email protected]02cad5d2013-10-02 08:14:0311620 class FakeUploadElementReader : public UploadElementReader {
11621 public:
Chris Watkins7a41d3552017-12-01 02:13:2711622 FakeUploadElementReader() = default;
11623 ~FakeUploadElementReader() override = default;
[email protected]02cad5d2013-10-02 08:14:0311624
Matt Menkecc1d3a902018-02-05 18:27:3311625 CompletionOnceCallback TakeCallback() { return std::move(callback_); }
[email protected]02cad5d2013-10-02 08:14:0311626
11627 // UploadElementReader overrides:
Matt Menkecc1d3a902018-02-05 18:27:3311628 int Init(CompletionOnceCallback callback) override {
11629 callback_ = std::move(callback);
[email protected]02cad5d2013-10-02 08:14:0311630 return ERR_IO_PENDING;
11631 }
avibf0746c2015-12-09 19:53:1411632 uint64_t GetContentLength() const override { return 0; }
11633 uint64_t BytesRemaining() const override { return 0; }
dchengb03027d2014-10-21 12:00:2011634 int Read(IOBuffer* buf,
11635 int buf_length,
Matt Menkecc1d3a902018-02-05 18:27:3311636 CompletionOnceCallback callback) override {
[email protected]02cad5d2013-10-02 08:14:0311637 return ERR_FAILED;
11638 }
11639
11640 private:
Matt Menkecc1d3a902018-02-05 18:27:3311641 CompletionOnceCallback callback_;
[email protected]02cad5d2013-10-02 08:14:0311642 };
11643
11644 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
danakj1fd259a02016-04-16 03:17:0911645 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
11646 element_readers.push_back(base::WrapUnique(fake_reader));
olli.raula6df48b2a2015-11-26 07:40:2211647 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02cad5d2013-10-02 08:14:0311648
11649 HttpRequestInfo request;
11650 request.method = "POST";
bncce36dca22015-04-21 22:11:2311651 request.url = GURL("http://www.example.org/upload");
[email protected]02cad5d2013-10-02 08:14:0311652 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1011653 request.traffic_annotation =
11654 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02cad5d2013-10-02 08:14:0311655
danakj1fd259a02016-04-16 03:17:0911656 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5811657 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1911658 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]02cad5d2013-10-02 08:14:0311659
11660 StaticSocketDataProvider data;
11661 session_deps_.socket_factory->AddSocketDataProvider(&data);
11662
11663 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2011664 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111665 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
fdoray92e35a72016-06-10 15:54:5511666 base::RunLoop().RunUntilIdle();
[email protected]02cad5d2013-10-02 08:14:0311667
11668 // Transaction is pending on request body initialization.
Matt Menkecc1d3a902018-02-05 18:27:3311669 CompletionOnceCallback init_callback = fake_reader->TakeCallback();
11670 ASSERT_FALSE(init_callback.is_null());
[email protected]02cad5d2013-10-02 08:14:0311671
11672 // Return Init()'s result after the transaction gets destroyed.
11673 trans.reset();
Matt Menkecc1d3a902018-02-05 18:27:3311674 std::move(init_callback).Run(OK); // Should not crash.
[email protected]02cad5d2013-10-02 08:14:0311675}
11676
[email protected]aeefc9e82010-02-19 16:18:2711677// Tests that changes to Auth realms are treated like auth rejections.
bncd16676a2016-07-20 16:23:0111678TEST_F(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:2711679 HttpRequestInfo request;
11680 request.method = "GET";
bncce36dca22015-04-21 22:11:2311681 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011682 request.traffic_annotation =
11683 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]aeefc9e82010-02-19 16:18:2711684
11685 // First transaction will request a resource and receive a Basic challenge
11686 // with realm="first_realm".
11687 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2311688 MockWrite(
11689 "GET / HTTP/1.1\r\n"
11690 "Host: www.example.org\r\n"
11691 "Connection: keep-alive\r\n"
11692 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2711693 };
11694 MockRead data_reads1[] = {
11695 MockRead("HTTP/1.1 401 Unauthorized\r\n"
11696 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
11697 "\r\n"),
11698 };
11699
bnc691fda62016-08-12 00:43:1611700 // After calling trans.RestartWithAuth(), provide an Authentication header
[email protected]aeefc9e82010-02-19 16:18:2711701 // for first_realm. The server will reject and provide a challenge with
11702 // second_realm.
11703 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:2311704 MockWrite(
11705 "GET / HTTP/1.1\r\n"
11706 "Host: www.example.org\r\n"
11707 "Connection: keep-alive\r\n"
11708 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
11709 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2711710 };
11711 MockRead data_reads2[] = {
11712 MockRead("HTTP/1.1 401 Unauthorized\r\n"
11713 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
11714 "\r\n"),
11715 };
11716
11717 // This again fails, and goes back to first_realm. Make sure that the
11718 // entry is removed from cache.
11719 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:2311720 MockWrite(
11721 "GET / HTTP/1.1\r\n"
11722 "Host: www.example.org\r\n"
11723 "Connection: keep-alive\r\n"
11724 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
11725 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2711726 };
11727 MockRead data_reads3[] = {
11728 MockRead("HTTP/1.1 401 Unauthorized\r\n"
11729 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
11730 "\r\n"),
11731 };
11732
11733 // Try one last time (with the correct password) and get the resource.
11734 MockWrite data_writes4[] = {
bncce36dca22015-04-21 22:11:2311735 MockWrite(
11736 "GET / HTTP/1.1\r\n"
11737 "Host: www.example.org\r\n"
11738 "Connection: keep-alive\r\n"
11739 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
11740 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2711741 };
11742 MockRead data_reads4[] = {
11743 MockRead("HTTP/1.1 200 OK\r\n"
11744 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:5011745 "Content-Length: 5\r\n"
11746 "\r\n"
11747 "hello"),
[email protected]aeefc9e82010-02-19 16:18:2711748 };
11749
Ryan Sleevib8d7ea02018-05-07 20:01:0111750 StaticSocketDataProvider data1(data_reads1, data_writes1);
11751 StaticSocketDataProvider data2(data_reads2, data_writes2);
11752 StaticSocketDataProvider data3(data_reads3, data_writes3);
11753 StaticSocketDataProvider data4(data_reads4, data_writes4);
[email protected]bb88e1d32013-05-03 23:11:0711754 session_deps_.socket_factory->AddSocketDataProvider(&data1);
11755 session_deps_.socket_factory->AddSocketDataProvider(&data2);
11756 session_deps_.socket_factory->AddSocketDataProvider(&data3);
11757 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:2711758
[email protected]49639fa2011-12-20 23:22:4111759 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:2711760
danakj1fd259a02016-04-16 03:17:0911761 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611762 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5011763
[email protected]aeefc9e82010-02-19 16:18:2711764 // Issue the first request with Authorize headers. There should be a
11765 // password prompt for first_realm waiting to be filled in after the
11766 // transaction completes.
tfarina42834112016-09-22 13:38:2011767 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111768 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2711769 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0111770 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1611771 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211772 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0411773 const AuthChallengeInfo* challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5211774 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0411775 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4311776 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0411777 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1911778 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2711779
11780 // Issue the second request with an incorrect password. There should be a
11781 // password prompt for second_realm waiting to be filled in after the
11782 // transaction completes.
[email protected]49639fa2011-12-20 23:22:4111783 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:1611784 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBaz),
11785 callback2.callback());
robpercival214763f2016-07-01 23:27:0111786 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2711787 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0111788 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1611789 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211790 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0411791 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5211792 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0411793 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4311794 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0411795 EXPECT_EQ("second_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1911796 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2711797
11798 // Issue the third request with another incorrect password. There should be
11799 // a password prompt for first_realm waiting to be filled in. If the password
11800 // prompt is not present, it indicates that the HttpAuthCacheEntry for
11801 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:4111802 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:1611803 rv = trans.RestartWithAuth(AuthCredentials(kSecond, kFou),
11804 callback3.callback());
robpercival214763f2016-07-01 23:27:0111805 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2711806 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:0111807 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1611808 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211809 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0411810 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5211811 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0411812 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4311813 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0411814 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1911815 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2711816
11817 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:4111818 TestCompletionCallback callback4;
bnc691fda62016-08-12 00:43:1611819 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBar),
11820 callback4.callback());
robpercival214763f2016-07-01 23:27:0111821 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2711822 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:0111823 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1611824 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211825 ASSERT_TRUE(response);
11826 EXPECT_FALSE(response->auth_challenge);
[email protected]aeefc9e82010-02-19 16:18:2711827}
11828
Bence Béky230ac612017-08-30 19:17:0811829// Regression test for https://crbug.com/754395.
11830TEST_F(HttpNetworkTransactionTest, IgnoreAltSvcWithInvalidCert) {
11831 MockRead data_reads[] = {
11832 MockRead("HTTP/1.1 200 OK\r\n"),
11833 MockRead(kAlternativeServiceHttpHeader),
11834 MockRead("\r\n"),
11835 MockRead("hello world"),
11836 MockRead(SYNCHRONOUS, OK),
11837 };
11838
11839 HttpRequestInfo request;
11840 request.method = "GET";
11841 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011842 request.traffic_annotation =
11843 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Béky230ac612017-08-30 19:17:0811844
Ryan Sleevib8d7ea02018-05-07 20:01:0111845 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
Bence Béky230ac612017-08-30 19:17:0811846 session_deps_.socket_factory->AddSocketDataProvider(&data);
11847
11848 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911849 ssl.ssl_info.cert =
11850 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11851 ASSERT_TRUE(ssl.ssl_info.cert);
11852 ssl.ssl_info.cert_status = CERT_STATUS_COMMON_NAME_INVALID;
Bence Béky230ac612017-08-30 19:17:0811853 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11854
11855 TestCompletionCallback callback;
11856
11857 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11858 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11859
11860 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
11861 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11862
11863 url::SchemeHostPort test_server(request.url);
11864 HttpServerProperties* http_server_properties =
11865 session->http_server_properties();
11866 EXPECT_TRUE(
11867 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
11868
11869 EXPECT_THAT(callback.WaitForResult(), IsOk());
11870
11871 const HttpResponseInfo* response = trans.GetResponseInfo();
11872 ASSERT_TRUE(response);
11873 ASSERT_TRUE(response->headers);
11874 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11875 EXPECT_FALSE(response->was_fetched_via_spdy);
11876 EXPECT_FALSE(response->was_alpn_negotiated);
11877
11878 std::string response_data;
11879 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
11880 EXPECT_EQ("hello world", response_data);
11881
11882 EXPECT_TRUE(
11883 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
11884}
11885
bncd16676a2016-07-20 16:23:0111886TEST_F(HttpNetworkTransactionTest, HonorAlternativeServiceHeader) {
bncc958faa2015-07-31 18:14:5211887 MockRead data_reads[] = {
11888 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311889 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211890 MockRead("\r\n"),
11891 MockRead("hello world"),
11892 MockRead(SYNCHRONOUS, OK),
11893 };
11894
11895 HttpRequestInfo request;
11896 request.method = "GET";
bncb26024382016-06-29 02:39:4511897 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011898 request.traffic_annotation =
11899 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bncc958faa2015-07-31 18:14:5211900
Ryan Sleevib8d7ea02018-05-07 20:01:0111901 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:5211902 session_deps_.socket_factory->AddSocketDataProvider(&data);
11903
bncb26024382016-06-29 02:39:4511904 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911905 ssl.ssl_info.cert =
11906 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11907 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4511908 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11909
bncc958faa2015-07-31 18:14:5211910 TestCompletionCallback callback;
11911
danakj1fd259a02016-04-16 03:17:0911912 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611913 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5211914
tfarina42834112016-09-22 13:38:2011915 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111916 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5211917
bncb26024382016-06-29 02:39:4511918 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4011919 HttpServerProperties* http_server_properties =
11920 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3411921 EXPECT_TRUE(
11922 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5211923
robpercival214763f2016-07-01 23:27:0111924 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5211925
bnc691fda62016-08-12 00:43:1611926 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211927 ASSERT_TRUE(response);
11928 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5211929 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11930 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211931 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5211932
11933 std::string response_data;
bnc691fda62016-08-12 00:43:1611934 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5211935 EXPECT_EQ("hello world", response_data);
11936
zhongyic4de03032017-05-19 04:07:3411937 AlternativeServiceInfoVector alternative_service_info_vector =
11938 http_server_properties->GetAlternativeServiceInfos(test_server);
11939 ASSERT_EQ(1u, alternative_service_info_vector.size());
11940 AlternativeService alternative_service(kProtoHTTP2, "mail.example.org", 443);
11941 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5411942 alternative_service_info_vector[0].alternative_service());
bncc958faa2015-07-31 18:14:5211943}
11944
bnce3dd56f2016-06-01 10:37:1111945// Regression test for https://crbug.com/615497.
bncd16676a2016-07-20 16:23:0111946TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1111947 DoNotParseAlternativeServiceHeaderOnInsecureRequest) {
bnce3dd56f2016-06-01 10:37:1111948 MockRead data_reads[] = {
11949 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311950 MockRead(kAlternativeServiceHttpHeader),
bnce3dd56f2016-06-01 10:37:1111951 MockRead("\r\n"),
11952 MockRead("hello world"),
11953 MockRead(SYNCHRONOUS, OK),
11954 };
11955
11956 HttpRequestInfo request;
11957 request.method = "GET";
11958 request.url = GURL("http://www.example.org/");
11959 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1011960 request.traffic_annotation =
11961 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnce3dd56f2016-06-01 10:37:1111962
Ryan Sleevib8d7ea02018-05-07 20:01:0111963 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
bnce3dd56f2016-06-01 10:37:1111964 session_deps_.socket_factory->AddSocketDataProvider(&data);
11965
11966 TestCompletionCallback callback;
11967
11968 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611969 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1111970
11971 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4011972 HttpServerProperties* http_server_properties =
11973 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3411974 EXPECT_TRUE(
11975 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1111976
tfarina42834112016-09-22 13:38:2011977 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111978 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11979 EXPECT_THAT(callback.WaitForResult(), IsOk());
bnce3dd56f2016-06-01 10:37:1111980
bnc691fda62016-08-12 00:43:1611981 const HttpResponseInfo* response = trans.GetResponseInfo();
bnce3dd56f2016-06-01 10:37:1111982 ASSERT_TRUE(response);
11983 ASSERT_TRUE(response->headers);
11984 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11985 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211986 EXPECT_FALSE(response->was_alpn_negotiated);
bnce3dd56f2016-06-01 10:37:1111987
11988 std::string response_data;
bnc691fda62016-08-12 00:43:1611989 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnce3dd56f2016-06-01 10:37:1111990 EXPECT_EQ("hello world", response_data);
11991
zhongyic4de03032017-05-19 04:07:3411992 EXPECT_TRUE(
11993 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1111994}
11995
bnca86731e2017-04-17 12:31:2811996// HTTP/2 Alternative Services should be disabled by default.
bnc8bef8da22016-05-30 01:28:2511997// TODO(bnc): Remove when https://crbug.com/615413 is fixed.
bncd16676a2016-07-20 16:23:0111998TEST_F(HttpNetworkTransactionTest,
bnc8bef8da22016-05-30 01:28:2511999 DisableHTTP2AlternativeServicesWithDifferentHost) {
bnca86731e2017-04-17 12:31:2812000 session_deps_.enable_http2_alternative_service = false;
bncb26024382016-06-29 02:39:4512001
bnc8bef8da22016-05-30 01:28:2512002 HttpRequestInfo request;
12003 request.method = "GET";
bncb26024382016-06-29 02:39:4512004 request.url = GURL("https://www.example.org/");
bnc8bef8da22016-05-30 01:28:2512005 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1012006 request.traffic_annotation =
12007 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8bef8da22016-05-30 01:28:2512008
12009 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
12010 StaticSocketDataProvider first_data;
12011 first_data.set_connect_data(mock_connect);
12012 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4512013 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612014 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512015 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
bnc8bef8da22016-05-30 01:28:2512016
12017 MockRead data_reads[] = {
12018 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
12019 MockRead(ASYNC, OK),
12020 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112021 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
bnc8bef8da22016-05-30 01:28:2512022 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
12023
12024 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12025
bnc525e175a2016-06-20 12:36:4012026 HttpServerProperties* http_server_properties =
bnc8bef8da22016-05-30 01:28:2512027 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2112028 AlternativeService alternative_service(kProtoHTTP2, "different.example.org",
12029 444);
bnc8bef8da22016-05-30 01:28:2512030 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112031 http_server_properties->SetHttp2AlternativeService(
bnc8bef8da22016-05-30 01:28:2512032 url::SchemeHostPort(request.url), alternative_service, expiration);
12033
bnc691fda62016-08-12 00:43:1612034 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc8bef8da22016-05-30 01:28:2512035 TestCompletionCallback callback;
12036
tfarina42834112016-09-22 13:38:2012037 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc8bef8da22016-05-30 01:28:2512038 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0112039 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc8bef8da22016-05-30 01:28:2512040}
12041
bnce3dd56f2016-06-01 10:37:1112042// Regression test for https://crbug.com/615497:
12043// Alternative Services should be disabled for http origin.
bncd16676a2016-07-20 16:23:0112044TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1112045 DisableAlternativeServicesForInsecureOrigin) {
bnce3dd56f2016-06-01 10:37:1112046 HttpRequestInfo request;
12047 request.method = "GET";
12048 request.url = GURL("http://www.example.org/");
12049 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1012050 request.traffic_annotation =
12051 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnce3dd56f2016-06-01 10:37:1112052
12053 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
12054 StaticSocketDataProvider first_data;
12055 first_data.set_connect_data(mock_connect);
12056 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
12057
12058 MockRead data_reads[] = {
12059 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
12060 MockRead(ASYNC, OK),
12061 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112062 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
bnce3dd56f2016-06-01 10:37:1112063 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
12064
12065 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12066
bnc525e175a2016-06-20 12:36:4012067 HttpServerProperties* http_server_properties =
bnce3dd56f2016-06-01 10:37:1112068 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2112069 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnce3dd56f2016-06-01 10:37:1112070 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112071 http_server_properties->SetHttp2AlternativeService(
bnce3dd56f2016-06-01 10:37:1112072 url::SchemeHostPort(request.url), alternative_service, expiration);
12073
bnc691fda62016-08-12 00:43:1612074 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1112075 TestCompletionCallback callback;
12076
tfarina42834112016-09-22 13:38:2012077 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnce3dd56f2016-06-01 10:37:1112078 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0112079 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnce3dd56f2016-06-01 10:37:1112080}
12081
bncd16676a2016-07-20 16:23:0112082TEST_F(HttpNetworkTransactionTest, ClearAlternativeServices) {
bnc4f575852015-10-14 18:35:0812083 // Set an alternative service for origin.
danakj1fd259a02016-04-16 03:17:0912084 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4012085 HttpServerProperties* http_server_properties =
12086 session->http_server_properties();
bncb26024382016-06-29 02:39:4512087 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc3472afd2016-11-17 15:27:2112088 AlternativeService alternative_service(kProtoQUIC, "", 80);
bnc4f575852015-10-14 18:35:0812089 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112090 http_server_properties->SetQuicAlternativeService(
12091 test_server, alternative_service, expiration,
12092 session->params().quic_supported_versions);
zhongyic4de03032017-05-19 04:07:3412093 EXPECT_EQ(
12094 1u,
12095 http_server_properties->GetAlternativeServiceInfos(test_server).size());
bnc4f575852015-10-14 18:35:0812096
12097 // Send a clear header.
12098 MockRead data_reads[] = {
12099 MockRead("HTTP/1.1 200 OK\r\n"),
12100 MockRead("Alt-Svc: clear\r\n"),
12101 MockRead("\r\n"),
12102 MockRead("hello world"),
12103 MockRead(SYNCHRONOUS, OK),
12104 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112105 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
bnc4f575852015-10-14 18:35:0812106 session_deps_.socket_factory->AddSocketDataProvider(&data);
12107
bncb26024382016-06-29 02:39:4512108 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4912109 ssl.ssl_info.cert =
12110 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
12111 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4512112 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12113
bnc4f575852015-10-14 18:35:0812114 HttpRequestInfo request;
12115 request.method = "GET";
bncb26024382016-06-29 02:39:4512116 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1012117 request.traffic_annotation =
12118 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc4f575852015-10-14 18:35:0812119
12120 TestCompletionCallback callback;
12121
bnc691fda62016-08-12 00:43:1612122 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc4f575852015-10-14 18:35:0812123
tfarina42834112016-09-22 13:38:2012124 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112125 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc4f575852015-10-14 18:35:0812126
bnc691fda62016-08-12 00:43:1612127 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212128 ASSERT_TRUE(response);
12129 ASSERT_TRUE(response->headers);
bnc4f575852015-10-14 18:35:0812130 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12131 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212132 EXPECT_FALSE(response->was_alpn_negotiated);
bnc4f575852015-10-14 18:35:0812133
12134 std::string response_data;
bnc691fda62016-08-12 00:43:1612135 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc4f575852015-10-14 18:35:0812136 EXPECT_EQ("hello world", response_data);
12137
zhongyic4de03032017-05-19 04:07:3412138 EXPECT_TRUE(
12139 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnc4f575852015-10-14 18:35:0812140}
12141
bncd16676a2016-07-20 16:23:0112142TEST_F(HttpNetworkTransactionTest, HonorMultipleAlternativeServiceHeaders) {
bncc958faa2015-07-31 18:14:5212143 MockRead data_reads[] = {
12144 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312145 MockRead("Alt-Svc: h2=\"www.example.com:443\","),
12146 MockRead("h2=\":1234\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:5212147 MockRead("hello world"),
12148 MockRead(SYNCHRONOUS, OK),
12149 };
12150
12151 HttpRequestInfo request;
12152 request.method = "GET";
bncb26024382016-06-29 02:39:4512153 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1012154 request.traffic_annotation =
12155 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bncc958faa2015-07-31 18:14:5212156
Ryan Sleevib8d7ea02018-05-07 20:01:0112157 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:5212158 session_deps_.socket_factory->AddSocketDataProvider(&data);
12159
bncb26024382016-06-29 02:39:4512160 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4912161 ssl.ssl_info.cert =
12162 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
12163 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4512164 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12165
bncc958faa2015-07-31 18:14:5212166 TestCompletionCallback callback;
12167
danakj1fd259a02016-04-16 03:17:0912168 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1612169 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5212170
tfarina42834112016-09-22 13:38:2012171 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112172 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5212173
bncb26024382016-06-29 02:39:4512174 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc525e175a2016-06-20 12:36:4012175 HttpServerProperties* http_server_properties =
12176 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3412177 EXPECT_TRUE(
12178 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5212179
robpercival214763f2016-07-01 23:27:0112180 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5212181
bnc691fda62016-08-12 00:43:1612182 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212183 ASSERT_TRUE(response);
12184 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5212185 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12186 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212187 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5212188
12189 std::string response_data;
bnc691fda62016-08-12 00:43:1612190 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5212191 EXPECT_EQ("hello world", response_data);
12192
zhongyic4de03032017-05-19 04:07:3412193 AlternativeServiceInfoVector alternative_service_info_vector =
12194 http_server_properties->GetAlternativeServiceInfos(test_server);
12195 ASSERT_EQ(2u, alternative_service_info_vector.size());
12196
12197 AlternativeService alternative_service(kProtoHTTP2, "www.example.com", 443);
12198 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5412199 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3412200 AlternativeService alternative_service_2(kProtoHTTP2, "www.example.org",
12201 1234);
12202 EXPECT_EQ(alternative_service_2,
zhongyi422ce352017-06-09 23:28:5412203 alternative_service_info_vector[1].alternative_service());
bncc958faa2015-07-31 18:14:5212204}
12205
bncd16676a2016-07-20 16:23:0112206TEST_F(HttpNetworkTransactionTest, IdentifyQuicBroken) {
zhongyi3d4a55e72016-04-22 20:36:4612207 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0212208 HostPortPair alternative("alternative.example.org", 443);
12209 std::string origin_url = "https://origin.example.org:443";
12210 std::string alternative_url = "https://alternative.example.org:443";
12211
12212 // Negotiate HTTP/1.1 with alternative.example.org.
12213 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612214 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0212215 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12216
12217 // HTTP/1.1 data for request.
12218 MockWrite http_writes[] = {
12219 MockWrite("GET / HTTP/1.1\r\n"
12220 "Host: alternative.example.org\r\n"
12221 "Connection: keep-alive\r\n\r\n"),
12222 };
12223
12224 MockRead http_reads[] = {
12225 MockRead("HTTP/1.1 200 OK\r\n"
12226 "Content-Type: text/html; charset=iso-8859-1\r\n"
12227 "Content-Length: 40\r\n\r\n"
12228 "first HTTP/1.1 response from alternative"),
12229 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112230 StaticSocketDataProvider http_data(http_reads, http_writes);
zhongyi48704c182015-12-07 07:52:0212231 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12232
12233 StaticSocketDataProvider data_refused;
12234 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
12235 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
12236
zhongyi3d4a55e72016-04-22 20:36:4612237 // Set up a QUIC alternative service for server.
danakj1fd259a02016-04-16 03:17:0912238 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4012239 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0212240 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2112241 AlternativeService alternative_service(kProtoQUIC, alternative);
zhongyi48704c182015-12-07 07:52:0212242 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112243 http_server_properties->SetQuicAlternativeService(
12244 server, alternative_service, expiration,
12245 HttpNetworkSession::Params().quic_supported_versions);
zhongyi48704c182015-12-07 07:52:0212246 // Mark the QUIC alternative service as broken.
12247 http_server_properties->MarkAlternativeServiceBroken(alternative_service);
12248
zhongyi48704c182015-12-07 07:52:0212249 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4612250 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0212251 request.method = "GET";
12252 request.url = GURL(origin_url);
Ramin Halavatib5e433e2018-02-07 07:41:1012253 request.traffic_annotation =
12254 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
12255
zhongyi48704c182015-12-07 07:52:0212256 TestCompletionCallback callback;
12257 NetErrorDetails details;
12258 EXPECT_FALSE(details.quic_broken);
12259
tfarina42834112016-09-22 13:38:2012260 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1612261 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0212262 EXPECT_TRUE(details.quic_broken);
12263}
12264
bncd16676a2016-07-20 16:23:0112265TEST_F(HttpNetworkTransactionTest, IdentifyQuicNotBroken) {
zhongyi3d4a55e72016-04-22 20:36:4612266 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0212267 HostPortPair alternative1("alternative1.example.org", 443);
12268 HostPortPair alternative2("alternative2.example.org", 443);
12269 std::string origin_url = "https://origin.example.org:443";
12270 std::string alternative_url1 = "https://alternative1.example.org:443";
12271 std::string alternative_url2 = "https://alternative2.example.org:443";
12272
12273 // Negotiate HTTP/1.1 with alternative1.example.org.
12274 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612275 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0212276 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12277
12278 // HTTP/1.1 data for request.
12279 MockWrite http_writes[] = {
12280 MockWrite("GET / HTTP/1.1\r\n"
12281 "Host: alternative1.example.org\r\n"
12282 "Connection: keep-alive\r\n\r\n"),
12283 };
12284
12285 MockRead http_reads[] = {
12286 MockRead("HTTP/1.1 200 OK\r\n"
12287 "Content-Type: text/html; charset=iso-8859-1\r\n"
12288 "Content-Length: 40\r\n\r\n"
12289 "first HTTP/1.1 response from alternative1"),
12290 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112291 StaticSocketDataProvider http_data(http_reads, http_writes);
zhongyi48704c182015-12-07 07:52:0212292 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12293
12294 StaticSocketDataProvider data_refused;
12295 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
12296 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
12297
danakj1fd259a02016-04-16 03:17:0912298 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4012299 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0212300 session->http_server_properties();
12301
zhongyi3d4a55e72016-04-22 20:36:4612302 // Set up two QUIC alternative services for server.
zhongyi48704c182015-12-07 07:52:0212303 AlternativeServiceInfoVector alternative_service_info_vector;
12304 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
12305
bnc3472afd2016-11-17 15:27:2112306 AlternativeService alternative_service1(kProtoQUIC, alternative1);
zhongyie537a002017-06-27 16:48:2112307 alternative_service_info_vector.push_back(
12308 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
12309 alternative_service1, expiration,
12310 session->params().quic_supported_versions));
bnc3472afd2016-11-17 15:27:2112311 AlternativeService alternative_service2(kProtoQUIC, alternative2);
zhongyie537a002017-06-27 16:48:2112312 alternative_service_info_vector.push_back(
12313 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
12314 alternative_service2, expiration,
12315 session->params().quic_supported_versions));
zhongyi48704c182015-12-07 07:52:0212316
12317 http_server_properties->SetAlternativeServices(
zhongyi3d4a55e72016-04-22 20:36:4612318 server, alternative_service_info_vector);
zhongyi48704c182015-12-07 07:52:0212319
12320 // Mark one of the QUIC alternative service as broken.
12321 http_server_properties->MarkAlternativeServiceBroken(alternative_service1);
zhongyic4de03032017-05-19 04:07:3412322 EXPECT_EQ(2u,
12323 http_server_properties->GetAlternativeServiceInfos(server).size());
zhongyi48704c182015-12-07 07:52:0212324
zhongyi48704c182015-12-07 07:52:0212325 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4612326 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0212327 request.method = "GET";
12328 request.url = GURL(origin_url);
Ramin Halavatib5e433e2018-02-07 07:41:1012329 request.traffic_annotation =
12330 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
12331
zhongyi48704c182015-12-07 07:52:0212332 TestCompletionCallback callback;
12333 NetErrorDetails details;
12334 EXPECT_FALSE(details.quic_broken);
12335
tfarina42834112016-09-22 13:38:2012336 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1612337 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0212338 EXPECT_FALSE(details.quic_broken);
12339}
12340
bncd16676a2016-07-20 16:23:0112341TEST_F(HttpNetworkTransactionTest, MarkBrokenAlternateProtocolAndFallback) {
[email protected]564b4912010-03-09 16:30:4212342 HttpRequestInfo request;
12343 request.method = "GET";
bncb26024382016-06-29 02:39:4512344 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1012345 request.traffic_annotation =
12346 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]564b4912010-03-09 16:30:4212347
[email protected]d973e99a2012-02-17 21:02:3612348 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:4212349 StaticSocketDataProvider first_data;
12350 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712351 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4512352 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612353 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512354 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]564b4912010-03-09 16:30:4212355
12356 MockRead data_reads[] = {
12357 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12358 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0612359 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:4212360 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112361 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712362 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:4212363
danakj1fd259a02016-04-16 03:17:0912364 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:4212365
bnc525e175a2016-06-20 12:36:4012366 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5312367 session->http_server_properties();
zhongyi3d4a55e72016-04-22 20:36:4612368 const url::SchemeHostPort server(request.url);
[email protected]3912662a32011-10-04 00:51:1112369 // Port must be < 1024, or the header will be ignored (since initial port was
12370 // port 80 (another restricted port).
zhongyie537a002017-06-27 16:48:2112371 // Port is ignored by MockConnect anyway.
12372 const AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12373 666);
bnc7dc7e1b42015-07-28 14:43:1212374 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112375 http_server_properties->SetHttp2AlternativeService(
12376 server, alternative_service, expiration);
[email protected]564b4912010-03-09 16:30:4212377
bnc691fda62016-08-12 00:43:1612378 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112379 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:4212380
tfarina42834112016-09-22 13:38:2012381 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112382 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12383 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]564b4912010-03-09 16:30:4212384
bnc691fda62016-08-12 00:43:1612385 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212386 ASSERT_TRUE(response);
12387 ASSERT_TRUE(response->headers);
[email protected]564b4912010-03-09 16:30:4212388 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12389
12390 std::string response_data;
bnc691fda62016-08-12 00:43:1612391 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]564b4912010-03-09 16:30:4212392 EXPECT_EQ("hello world", response_data);
12393
zhongyic4de03032017-05-19 04:07:3412394 const AlternativeServiceInfoVector alternative_service_info_vector =
12395 http_server_properties->GetAlternativeServiceInfos(server);
12396 ASSERT_EQ(1u, alternative_service_info_vector.size());
12397 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5412398 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3412399 EXPECT_TRUE(
12400 http_server_properties->IsAlternativeServiceBroken(alternative_service));
[email protected]564b4912010-03-09 16:30:4212401}
12402
bnc55ff9da2015-08-19 18:42:3512403// Ensure that we are not allowed to redirect traffic via an alternate protocol
12404// to an unrestricted (port >= 1024) when the original traffic was on a
12405// restricted port (port < 1024). Ensure that we can redirect in all other
12406// cases.
bncd16676a2016-07-20 16:23:0112407TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:1112408 HttpRequestInfo restricted_port_request;
12409 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4512410 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1112411 restricted_port_request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1012412 restricted_port_request.traffic_annotation =
12413 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1112414
[email protected]d973e99a2012-02-17 21:02:3612415 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1112416 StaticSocketDataProvider first_data;
12417 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712418 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1112419
12420 MockRead data_reads[] = {
12421 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12422 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0612423 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1112424 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112425 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712426 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4512427 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612428 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512429 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1112430
danakj1fd259a02016-04-16 03:17:0912431 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1112432
bnc525e175a2016-06-20 12:36:4012433 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5312434 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1112435 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2112436 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12437 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1212438 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112439 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4612440 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5012441 expiration);
[email protected]3912662a32011-10-04 00:51:1112442
bnc691fda62016-08-12 00:43:1612443 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112444 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1112445
tfarina42834112016-09-22 13:38:2012446 int rv = trans.Start(&restricted_port_request, callback.callback(),
12447 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112448 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1112449 // Invalid change to unrestricted port should fail.
robpercival214763f2016-07-01 23:27:0112450 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_REFUSED));
[email protected]c54c6962013-02-01 04:53:1912451}
[email protected]3912662a32011-10-04 00:51:1112452
bnc55ff9da2015-08-19 18:42:3512453// Ensure that we are allowed to redirect traffic via an alternate protocol to
12454// an unrestricted (port >= 1024) when the original traffic was on a restricted
12455// port (port < 1024) if we set |enable_user_alternate_protocol_ports|.
bncd16676a2016-07-20 16:23:0112456TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedPermitted) {
[email protected]bb88e1d32013-05-03 23:11:0712457 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:1912458
12459 HttpRequestInfo restricted_port_request;
12460 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4512461 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]c54c6962013-02-01 04:53:1912462 restricted_port_request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1012463 restricted_port_request.traffic_annotation =
12464 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]c54c6962013-02-01 04:53:1912465
12466 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
12467 StaticSocketDataProvider first_data;
12468 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712469 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:1912470
12471 MockRead data_reads[] = {
12472 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12473 MockRead("hello world"),
12474 MockRead(ASYNC, OK),
12475 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112476 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712477 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4512478 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612479 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512480 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]c54c6962013-02-01 04:53:1912481
danakj1fd259a02016-04-16 03:17:0912482 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:1912483
bnc525e175a2016-06-20 12:36:4012484 HttpServerProperties* http_server_properties =
[email protected]c54c6962013-02-01 04:53:1912485 session->http_server_properties();
12486 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2112487 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12488 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1212489 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112490 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4612491 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5012492 expiration);
[email protected]c54c6962013-02-01 04:53:1912493
bnc691fda62016-08-12 00:43:1612494 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]c54c6962013-02-01 04:53:1912495 TestCompletionCallback callback;
12496
tfarina42834112016-09-22 13:38:2012497 EXPECT_EQ(ERR_IO_PENDING,
12498 trans.Start(&restricted_port_request, callback.callback(),
12499 NetLogWithSource()));
[email protected]c54c6962013-02-01 04:53:1912500 // Change to unrestricted port should succeed.
robpercival214763f2016-07-01 23:27:0112501 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1112502}
12503
bnc55ff9da2015-08-19 18:42:3512504// Ensure that we are not allowed to redirect traffic via an alternate protocol
12505// to an unrestricted (port >= 1024) when the original traffic was on a
12506// restricted port (port < 1024). Ensure that we can redirect in all other
12507// cases.
bncd16676a2016-07-20 16:23:0112508TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:1112509 HttpRequestInfo restricted_port_request;
12510 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4512511 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1112512 restricted_port_request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1012513 restricted_port_request.traffic_annotation =
12514 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1112515
[email protected]d973e99a2012-02-17 21:02:3612516 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1112517 StaticSocketDataProvider first_data;
12518 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712519 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1112520
12521 MockRead data_reads[] = {
12522 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12523 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0612524 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1112525 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112526 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712527 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1112528
bncb26024382016-06-29 02:39:4512529 SSLSocketDataProvider ssl(ASYNC, OK);
12530 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12531
danakj1fd259a02016-04-16 03:17:0912532 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1112533
bnc525e175a2016-06-20 12:36:4012534 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5312535 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1112536 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2112537 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12538 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1212539 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112540 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4612541 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5012542 expiration);
[email protected]3912662a32011-10-04 00:51:1112543
bnc691fda62016-08-12 00:43:1612544 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112545 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1112546
tfarina42834112016-09-22 13:38:2012547 int rv = trans.Start(&restricted_port_request, callback.callback(),
12548 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112549 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1112550 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0112551 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1112552}
12553
bnc55ff9da2015-08-19 18:42:3512554// Ensure that we are not allowed to redirect traffic via an alternate protocol
12555// to an unrestricted (port >= 1024) when the original traffic was on a
12556// restricted port (port < 1024). Ensure that we can redirect in all other
12557// cases.
bncd16676a2016-07-20 16:23:0112558TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:1112559 HttpRequestInfo unrestricted_port_request;
12560 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4512561 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1112562 unrestricted_port_request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1012563 unrestricted_port_request.traffic_annotation =
12564 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1112565
[email protected]d973e99a2012-02-17 21:02:3612566 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1112567 StaticSocketDataProvider first_data;
12568 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712569 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1112570
12571 MockRead data_reads[] = {
12572 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12573 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0612574 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1112575 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112576 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712577 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4512578 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612579 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512580 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1112581
danakj1fd259a02016-04-16 03:17:0912582 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1112583
bnc525e175a2016-06-20 12:36:4012584 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5312585 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1112586 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2112587 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12588 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1212589 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112590 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4612591 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5012592 expiration);
[email protected]3912662a32011-10-04 00:51:1112593
bnc691fda62016-08-12 00:43:1612594 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112595 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1112596
bnc691fda62016-08-12 00:43:1612597 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2012598 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112599 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1112600 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0112601 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1112602}
12603
bnc55ff9da2015-08-19 18:42:3512604// Ensure that we are not allowed to redirect traffic via an alternate protocol
12605// to an unrestricted (port >= 1024) when the original traffic was on a
12606// restricted port (port < 1024). Ensure that we can redirect in all other
12607// cases.
bncd16676a2016-07-20 16:23:0112608TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:1112609 HttpRequestInfo unrestricted_port_request;
12610 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4512611 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1112612 unrestricted_port_request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1012613 unrestricted_port_request.traffic_annotation =
12614 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1112615
[email protected]d973e99a2012-02-17 21:02:3612616 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1112617 StaticSocketDataProvider first_data;
12618 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712619 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1112620
12621 MockRead data_reads[] = {
12622 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12623 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0612624 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1112625 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112626 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712627 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1112628
bncb26024382016-06-29 02:39:4512629 SSLSocketDataProvider ssl(ASYNC, OK);
12630 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12631
danakj1fd259a02016-04-16 03:17:0912632 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1112633
bnc525e175a2016-06-20 12:36:4012634 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5312635 session->http_server_properties();
bnc0bbb02622015-07-23 10:06:2212636 const int kUnrestrictedAlternatePort = 1025;
bnc3472afd2016-11-17 15:27:2112637 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12638 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1212639 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112640 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4612641 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5012642 expiration);
[email protected]3912662a32011-10-04 00:51:1112643
bnc691fda62016-08-12 00:43:1612644 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112645 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1112646
bnc691fda62016-08-12 00:43:1612647 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2012648 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112649 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1112650 // Valid change to an unrestricted port should pass.
robpercival214763f2016-07-01 23:27:0112651 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1112652}
12653
bnc55ff9da2015-08-19 18:42:3512654// Ensure that we are not allowed to redirect traffic via an alternate protocol
Xida Chen9bfe0b62018-04-24 19:52:2112655// to an unsafe port, and that we resume the second HttpStreamFactory::Job once
12656// the alternate protocol request fails.
bncd16676a2016-07-20 16:23:0112657TEST_F(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:0212658 HttpRequestInfo request;
12659 request.method = "GET";
bncce36dca22015-04-21 22:11:2312660 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1012661 request.traffic_annotation =
12662 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]eb6234e2012-01-19 01:50:0212663
12664 // The alternate protocol request will error out before we attempt to connect,
12665 // so only the standard HTTP request will try to connect.
12666 MockRead data_reads[] = {
12667 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12668 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0612669 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:0212670 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112671 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712672 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:0212673
danakj1fd259a02016-04-16 03:17:0912674 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:0212675
bnc525e175a2016-06-20 12:36:4012676 HttpServerProperties* http_server_properties =
[email protected]eb6234e2012-01-19 01:50:0212677 session->http_server_properties();
12678 const int kUnsafePort = 7;
bnc3472afd2016-11-17 15:27:2112679 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12680 kUnsafePort);
bnc7dc7e1b42015-07-28 14:43:1212681 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112682 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4612683 url::SchemeHostPort(request.url), alternative_service, expiration);
[email protected]eb6234e2012-01-19 01:50:0212684
bnc691fda62016-08-12 00:43:1612685 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]eb6234e2012-01-19 01:50:0212686 TestCompletionCallback callback;
12687
tfarina42834112016-09-22 13:38:2012688 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112689 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]eb6234e2012-01-19 01:50:0212690 // The HTTP request should succeed.
robpercival214763f2016-07-01 23:27:0112691 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb6234e2012-01-19 01:50:0212692
bnc691fda62016-08-12 00:43:1612693 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212694 ASSERT_TRUE(response);
12695 ASSERT_TRUE(response->headers);
[email protected]eb6234e2012-01-19 01:50:0212696 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12697
12698 std::string response_data;
bnc691fda62016-08-12 00:43:1612699 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]eb6234e2012-01-19 01:50:0212700 EXPECT_EQ("hello world", response_data);
12701}
12702
bncd16676a2016-07-20 16:23:0112703TEST_F(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]2ff8b312010-04-26 22:20:5412704 HttpRequestInfo request;
12705 request.method = "GET";
bncb26024382016-06-29 02:39:4512706 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1012707 request.traffic_annotation =
12708 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2ff8b312010-04-26 22:20:5412709
12710 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212711 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312712 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212713 MockRead("\r\n"),
12714 MockRead("hello world"),
12715 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
12716 MockRead(ASYNC, OK)};
[email protected]2ff8b312010-04-26 22:20:5412717
Ryan Sleevib8d7ea02018-05-07 20:01:0112718 StaticSocketDataProvider first_transaction(data_reads,
12719 base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712720 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4512721 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612722 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512723 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5412724
bnc032658ba2016-09-26 18:17:1512725 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5412726
Ryan Hamilton0239aac2018-05-19 00:03:1312727 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4512728 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4112729 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5412730
Ryan Hamilton0239aac2018-05-19 00:03:1312731 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
12732 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5412733 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4112734 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5412735 };
12736
Ryan Sleevib8d7ea02018-05-07 20:01:0112737 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0712738 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5412739
[email protected]d973e99a2012-02-17 21:02:3612740 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0112741 StaticSocketDataProvider hanging_non_alternate_protocol_socket;
[email protected]2d6728692011-03-12 01:39:5512742 hanging_non_alternate_protocol_socket.set_connect_data(
12743 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0712744 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5512745 &hanging_non_alternate_protocol_socket);
12746
[email protected]49639fa2011-12-20 23:22:4112747 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5412748
danakj1fd259a02016-04-16 03:17:0912749 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5812750 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1912751 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5412752
tfarina42834112016-09-22 13:38:2012753 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112754 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12755 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412756
12757 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212758 ASSERT_TRUE(response);
12759 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5412760 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12761
12762 std::string response_data;
robpercival214763f2016-07-01 23:27:0112763 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412764 EXPECT_EQ("hello world", response_data);
12765
bnc87dcefc2017-05-25 12:47:5812766 trans =
Jeremy Roman0579ed62017-08-29 15:56:1912767 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5412768
tfarina42834112016-09-22 13:38:2012769 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112770 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12771 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412772
12773 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212774 ASSERT_TRUE(response);
12775 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212776 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5312777 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212778 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5412779
robpercival214763f2016-07-01 23:27:0112780 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412781 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:5412782}
12783
bncd16676a2016-07-20 16:23:0112784TEST_F(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]2d6728692011-03-12 01:39:5512785 HttpRequestInfo request;
12786 request.method = "GET";
bncb26024382016-06-29 02:39:4512787 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1012788 request.traffic_annotation =
12789 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d6728692011-03-12 01:39:5512790
bncb26024382016-06-29 02:39:4512791 // First transaction receives Alt-Svc header over HTTP/1.1.
[email protected]2d6728692011-03-12 01:39:5512792 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212793 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312794 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212795 MockRead("\r\n"),
12796 MockRead("hello world"),
12797 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
12798 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5512799 };
12800
Ryan Sleevib8d7ea02018-05-07 20:01:0112801 StaticSocketDataProvider http11_data(data_reads, base::span<MockWrite>());
bncb26024382016-06-29 02:39:4512802 session_deps_.socket_factory->AddSocketDataProvider(&http11_data);
[email protected]2d6728692011-03-12 01:39:5512803
bncb26024382016-06-29 02:39:4512804 SSLSocketDataProvider ssl_http11(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4912805 ssl_http11.ssl_info.cert =
12806 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
12807 ASSERT_TRUE(ssl_http11.ssl_info.cert);
bncb26024382016-06-29 02:39:4512808 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
12809
12810 // Second transaction starts an alternative and a non-alternative Job.
12811 // Both sockets hang.
[email protected]d973e99a2012-02-17 21:02:3612812 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0112813 StaticSocketDataProvider hanging_socket1;
mmenkecc2298e2015-12-07 18:20:1812814 hanging_socket1.set_connect_data(never_finishing_connect);
mmenkecc2298e2015-12-07 18:20:1812815 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket1);
12816
Ryan Sleevib8d7ea02018-05-07 20:01:0112817 StaticSocketDataProvider hanging_socket2;
mmenkecc2298e2015-12-07 18:20:1812818 hanging_socket2.set_connect_data(never_finishing_connect);
12819 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket2);
[email protected]2d6728692011-03-12 01:39:5512820
bncb26024382016-06-29 02:39:4512821 // Third transaction starts an alternative and a non-alternative job.
12822 // The non-alternative job hangs, but the alternative one succeeds.
12823 // The second transaction, still pending, binds to this socket.
Ryan Hamilton0239aac2018-05-19 00:03:1312824 spdy::SpdySerializedFrame req1(
bncb26024382016-06-29 02:39:4512825 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1312826 spdy::SpdySerializedFrame req2(
bncb26024382016-06-29 02:39:4512827 spdy_util_.ConstructSpdyGet("https://www.example.org/", 3, LOWEST));
[email protected]2d6728692011-03-12 01:39:5512828 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4112829 CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
[email protected]2d6728692011-03-12 01:39:5512830 };
Ryan Hamilton0239aac2018-05-19 00:03:1312831 spdy::SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
12832 spdy::SpdySerializedFrame data1(spdy_util_.ConstructSpdyDataFrame(1, true));
12833 spdy::SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
12834 spdy::SpdySerializedFrame data2(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]2d6728692011-03-12 01:39:5512835 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4112836 CreateMockRead(resp1, 2), CreateMockRead(data1, 3),
12837 CreateMockRead(resp2, 4), CreateMockRead(data2, 5),
rch8e6c6c42015-05-01 14:05:1312838 MockRead(ASYNC, 0, 6),
[email protected]2d6728692011-03-12 01:39:5512839 };
12840
Ryan Sleevib8d7ea02018-05-07 20:01:0112841 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0712842 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:5512843
bnc032658ba2016-09-26 18:17:1512844 AddSSLSocketData();
bncb26024382016-06-29 02:39:4512845
Ryan Sleevib8d7ea02018-05-07 20:01:0112846 StaticSocketDataProvider hanging_socket3;
mmenkecc2298e2015-12-07 18:20:1812847 hanging_socket3.set_connect_data(never_finishing_connect);
12848 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket3);
[email protected]2d6728692011-03-12 01:39:5512849
danakj1fd259a02016-04-16 03:17:0912850 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:4112851 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:5012852 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5512853
tfarina42834112016-09-22 13:38:2012854 int rv = trans1.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112855 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12856 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512857
12858 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5212859 ASSERT_TRUE(response);
12860 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5512861 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12862
12863 std::string response_data;
robpercival214763f2016-07-01 23:27:0112864 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512865 EXPECT_EQ("hello world", response_data);
12866
[email protected]49639fa2011-12-20 23:22:4112867 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:5012868 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2012869 rv = trans2.Start(&request, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112870 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5512871
[email protected]49639fa2011-12-20 23:22:4112872 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:5012873 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2012874 rv = trans3.Start(&request, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112875 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5512876
robpercival214763f2016-07-01 23:27:0112877 EXPECT_THAT(callback2.WaitForResult(), IsOk());
12878 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512879
12880 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5212881 ASSERT_TRUE(response);
12882 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212883 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5512884 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212885 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0112886 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512887 EXPECT_EQ("hello!", response_data);
12888
12889 response = trans3.GetResponseInfo();
wezca1070932016-05-26 20:30:5212890 ASSERT_TRUE(response);
12891 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212892 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5512893 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212894 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0112895 ASSERT_THAT(ReadTransaction(&trans3, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512896 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:5512897}
12898
bncd16676a2016-07-20 16:23:0112899TEST_F(HttpNetworkTransactionTest, StallAlternativeServiceForNpnSpdy) {
Bence Békybcae37092018-06-12 04:18:5312900 session_deps_.host_resolver->set_synchronous_mode(true);
12901
[email protected]2d6728692011-03-12 01:39:5512902 HttpRequestInfo request;
12903 request.method = "GET";
bncb26024382016-06-29 02:39:4512904 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1012905 request.traffic_annotation =
12906 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d6728692011-03-12 01:39:5512907
12908 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212909 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312910 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212911 MockRead("\r\n"),
12912 MockRead("hello world"),
12913 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
12914 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5512915 };
12916
Ryan Sleevib8d7ea02018-05-07 20:01:0112917 StaticSocketDataProvider first_transaction(data_reads,
12918 base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712919 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:5512920
[email protected]8ddf8322012-02-23 18:08:0612921 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4912922 ssl.ssl_info.cert =
12923 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
12924 ASSERT_TRUE(ssl.ssl_info.cert);
[email protected]bb88e1d32013-05-03 23:11:0712925 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5512926
[email protected]d973e99a2012-02-17 21:02:3612927 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0112928 StaticSocketDataProvider hanging_alternate_protocol_socket;
[email protected]2d6728692011-03-12 01:39:5512929 hanging_alternate_protocol_socket.set_connect_data(
12930 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0712931 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5512932 &hanging_alternate_protocol_socket);
12933
bncb26024382016-06-29 02:39:4512934 // 2nd request is just a copy of the first one, over HTTP/1.1 again.
Ryan Sleevib8d7ea02018-05-07 20:01:0112935 StaticSocketDataProvider second_transaction(data_reads,
12936 base::span<MockWrite>());
mmenkecc2298e2015-12-07 18:20:1812937 session_deps_.socket_factory->AddSocketDataProvider(&second_transaction);
bncb26024382016-06-29 02:39:4512938 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5512939
[email protected]49639fa2011-12-20 23:22:4112940 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:5512941
danakj1fd259a02016-04-16 03:17:0912942 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5812943 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1912944 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5512945
tfarina42834112016-09-22 13:38:2012946 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112947 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12948 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512949
12950 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212951 ASSERT_TRUE(response);
12952 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5512953 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12954
12955 std::string response_data;
robpercival214763f2016-07-01 23:27:0112956 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512957 EXPECT_EQ("hello world", response_data);
12958
bnc87dcefc2017-05-25 12:47:5812959 trans =
Jeremy Roman0579ed62017-08-29 15:56:1912960 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5512961
tfarina42834112016-09-22 13:38:2012962 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112963 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12964 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512965
12966 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212967 ASSERT_TRUE(response);
12968 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5512969 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12970 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212971 EXPECT_FALSE(response->was_alpn_negotiated);
[email protected]2d6728692011-03-12 01:39:5512972
robpercival214763f2016-07-01 23:27:0112973 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512974 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:5512975}
12976
bnc2e884782016-08-11 19:45:1912977// Test that proxy is resolved using the origin url,
12978// regardless of the alternative server.
12979TEST_F(HttpNetworkTransactionTest, UseOriginNotAlternativeForProxy) {
12980 // Configure proxy to bypass www.example.org, which is the origin URL.
12981 ProxyConfig proxy_config;
12982 proxy_config.proxy_rules().ParseFromString("myproxy:70");
12983 proxy_config.proxy_rules().bypass_rules.AddRuleFromString("www.example.org");
Ramin Halavatica8d5252018-03-12 05:33:4912984 auto proxy_config_service = std::make_unique<ProxyConfigServiceFixed>(
12985 ProxyConfigWithAnnotation(proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS));
bnc2e884782016-08-11 19:45:1912986
12987 CapturingProxyResolver capturing_proxy_resolver;
Jeremy Roman0579ed62017-08-29 15:56:1912988 auto proxy_resolver_factory = std::make_unique<CapturingProxyResolverFactory>(
bnc2e884782016-08-11 19:45:1912989 &capturing_proxy_resolver);
12990
12991 TestNetLog net_log;
12992
Bence Béky53a5aef2018-03-29 21:54:1212993 session_deps_.proxy_resolution_service =
12994 std::make_unique<ProxyResolutionService>(
12995 std::move(proxy_config_service), std::move(proxy_resolver_factory),
12996 &net_log);
bnc2e884782016-08-11 19:45:1912997
12998 session_deps_.net_log = &net_log;
12999
13000 // Configure alternative service with a hostname that is not bypassed by the
13001 // proxy.
13002 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13003 HttpServerProperties* http_server_properties =
13004 session->http_server_properties();
13005 url::SchemeHostPort server("https", "www.example.org", 443);
13006 HostPortPair alternative("www.example.com", 443);
bnc3472afd2016-11-17 15:27:2113007 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc2e884782016-08-11 19:45:1913008 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2113009 http_server_properties->SetHttp2AlternativeService(
13010 server, alternative_service, expiration);
bnc2e884782016-08-11 19:45:1913011
13012 // Non-alternative job should hang.
13013 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0113014 StaticSocketDataProvider hanging_alternate_protocol_socket;
bnc2e884782016-08-11 19:45:1913015 hanging_alternate_protocol_socket.set_connect_data(never_finishing_connect);
13016 session_deps_.socket_factory->AddSocketDataProvider(
13017 &hanging_alternate_protocol_socket);
13018
bnc032658ba2016-09-26 18:17:1513019 AddSSLSocketData();
bnc2e884782016-08-11 19:45:1913020
13021 HttpRequestInfo request;
13022 request.method = "GET";
13023 request.url = GURL("https://www.example.org/");
13024 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1013025 request.traffic_annotation =
13026 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc2e884782016-08-11 19:45:1913027
Ryan Hamilton0239aac2018-05-19 00:03:1313028 spdy::SpdySerializedFrame req(
bnc2e884782016-08-11 19:45:1913029 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
13030
13031 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
13032
Ryan Hamilton0239aac2018-05-19 00:03:1313033 spdy::SpdySerializedFrame resp(
13034 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
13035 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
bnc2e884782016-08-11 19:45:1913036 MockRead spdy_reads[] = {
13037 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
13038 };
13039
Ryan Sleevib8d7ea02018-05-07 20:01:0113040 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
bnc2e884782016-08-11 19:45:1913041 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
13042
13043 TestCompletionCallback callback;
13044
13045 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
13046
tfarina42834112016-09-22 13:38:2013047 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc2e884782016-08-11 19:45:1913048 EXPECT_THAT(callback.GetResult(rv), IsOk());
13049
13050 const HttpResponseInfo* response = trans.GetResponseInfo();
13051 ASSERT_TRUE(response);
13052 ASSERT_TRUE(response->headers);
13053 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
13054 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213055 EXPECT_TRUE(response->was_alpn_negotiated);
bnc2e884782016-08-11 19:45:1913056
13057 std::string response_data;
13058 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
13059 EXPECT_EQ("hello!", response_data);
13060
13061 // Origin host bypasses proxy, no resolution should have happened.
13062 ASSERT_TRUE(capturing_proxy_resolver.resolved().empty());
13063}
13064
bncd16676a2016-07-20 16:23:0113065TEST_F(HttpNetworkTransactionTest, UseAlternativeServiceForTunneledNpnSpdy) {
[email protected]631f1322010-04-30 17:59:1113066 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:4213067 proxy_config.set_auto_detect(true);
13068 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:1113069
sammc5dd160c2015-04-02 02:43:1313070 CapturingProxyResolver capturing_proxy_resolver;
Ramin Halavatica8d5252018-03-12 05:33:4913071 session_deps_.proxy_resolution_service =
13072 std::make_unique<ProxyResolutionService>(
13073 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
13074 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
13075 std::make_unique<CapturingProxyResolverFactory>(
13076 &capturing_proxy_resolver),
13077 nullptr);
vishal.b62985ca92015-04-17 08:45:5113078 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0713079 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:1113080
13081 HttpRequestInfo request;
13082 request.method = "GET";
bncb26024382016-06-29 02:39:4513083 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1013084 request.traffic_annotation =
13085 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]631f1322010-04-30 17:59:1113086
13087 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5213088 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4313089 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5213090 MockRead("\r\n"),
13091 MockRead("hello world"),
13092 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
13093 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:1113094 };
13095
Ryan Sleevib8d7ea02018-05-07 20:01:0113096 StaticSocketDataProvider first_transaction(data_reads,
13097 base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0713098 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4513099 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613100 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4513101 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]631f1322010-04-30 17:59:1113102
bnc032658ba2016-09-26 18:17:1513103 AddSSLSocketData();
[email protected]631f1322010-04-30 17:59:1113104
Ryan Hamilton0239aac2018-05-19 00:03:1313105 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4513106 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
[email protected]631f1322010-04-30 17:59:1113107 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1313108 MockWrite(ASYNC, 0,
bnc8bef8da22016-05-30 01:28:2513109 "CONNECT www.example.org:443 HTTP/1.1\r\n"
13110 "Host: www.example.org:443\r\n"
rch8e6c6c42015-05-01 14:05:1313111 "Proxy-Connection: keep-alive\r\n\r\n"),
bncdf80d44fd2016-07-15 20:27:4113112 CreateMockWrite(req, 2),
[email protected]631f1322010-04-30 17:59:1113113 };
13114
[email protected]d911f1b2010-05-05 22:39:4213115 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
13116
Ryan Hamilton0239aac2018-05-19 00:03:1313117 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
13118 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]631f1322010-04-30 17:59:1113119 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113120 MockRead(ASYNC, 1, kCONNECTResponse), CreateMockRead(resp, 3),
13121 CreateMockRead(data, 4), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5),
[email protected]631f1322010-04-30 17:59:1113122 };
13123
Ryan Sleevib8d7ea02018-05-07 20:01:0113124 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0713125 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:1113126
[email protected]d973e99a2012-02-17 21:02:3613127 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0113128 StaticSocketDataProvider hanging_non_alternate_protocol_socket;
[email protected]2d6728692011-03-12 01:39:5513129 hanging_non_alternate_protocol_socket.set_connect_data(
13130 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0713131 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5513132 &hanging_non_alternate_protocol_socket);
13133
[email protected]49639fa2011-12-20 23:22:4113134 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:1113135
danakj1fd259a02016-04-16 03:17:0913136 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5813137 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1913138 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1113139
tfarina42834112016-09-22 13:38:2013140 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea2dcd3bf2016-08-16 21:49:4113141 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13142 EXPECT_THAT(callback.WaitForResult(), IsOk());
13143
13144 const HttpResponseInfo* response = trans->GetResponseInfo();
13145 ASSERT_TRUE(response);
13146 ASSERT_TRUE(response->headers);
13147 EXPECT_EQ("HTTP/0.9 200 OK", response->headers->GetStatusLine());
13148 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213149 EXPECT_TRUE(response->was_alpn_negotiated);
mmenkea2dcd3bf2016-08-16 21:49:4113150
13151 std::string response_data;
13152 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
13153 EXPECT_EQ("hello world", response_data);
[email protected]631f1322010-04-30 17:59:1113154
bnc87dcefc2017-05-25 12:47:5813155 trans =
Jeremy Roman0579ed62017-08-29 15:56:1913156 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1113157
tfarina42834112016-09-22 13:38:2013158 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113159 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13160 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]631f1322010-04-30 17:59:1113161
mmenkea2dcd3bf2016-08-16 21:49:4113162 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5213163 ASSERT_TRUE(response);
13164 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213165 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5313166 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213167 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]631f1322010-04-30 17:59:1113168
robpercival214763f2016-07-01 23:27:0113169 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]631f1322010-04-30 17:59:1113170 EXPECT_EQ("hello!", response_data);
bncb26024382016-06-29 02:39:4513171 ASSERT_EQ(2u, capturing_proxy_resolver.resolved().size());
13172 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1313173 capturing_proxy_resolver.resolved()[0].spec());
bncce36dca22015-04-21 22:11:2313174 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1313175 capturing_proxy_resolver.resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:1113176
[email protected]029c83b62013-01-24 05:28:2013177 LoadTimingInfo load_timing_info;
13178 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
13179 TestLoadTimingNotReusedWithPac(load_timing_info,
13180 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:1113181}
[email protected]631f1322010-04-30 17:59:1113182
bncd16676a2016-07-20 16:23:0113183TEST_F(HttpNetworkTransactionTest,
bnc1c196c6e2016-05-28 13:51:4813184 UseAlternativeServiceForNpnSpdyWithExistingSpdySession) {
[email protected]2ff8b312010-04-26 22:20:5413185 HttpRequestInfo request;
13186 request.method = "GET";
bncb26024382016-06-29 02:39:4513187 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1013188 request.traffic_annotation =
13189 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2ff8b312010-04-26 22:20:5413190
13191 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5213192 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4313193 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5213194 MockRead("\r\n"),
13195 MockRead("hello world"),
13196 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:5413197 };
13198
Ryan Sleevib8d7ea02018-05-07 20:01:0113199 StaticSocketDataProvider first_transaction(data_reads,
13200 base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0713201 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4513202 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613203 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4513204 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5413205
bnc032658ba2016-09-26 18:17:1513206 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5413207
Ryan Hamilton0239aac2018-05-19 00:03:1313208 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4513209 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4113210 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5413211
Ryan Hamilton0239aac2018-05-19 00:03:1313212 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
13213 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5413214 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113215 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5413216 };
13217
Ryan Sleevib8d7ea02018-05-07 20:01:0113218 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0713219 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5413220
[email protected]83039bb2011-12-09 18:43:5513221 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5413222
danakj1fd259a02016-04-16 03:17:0913223 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:5413224
bnc87dcefc2017-05-25 12:47:5813225 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1913226 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5413227
tfarina42834112016-09-22 13:38:2013228 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113229 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13230 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5413231
13232 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5213233 ASSERT_TRUE(response);
13234 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5413235 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13236
13237 std::string response_data;
robpercival214763f2016-07-01 23:27:0113238 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5413239 EXPECT_EQ("hello world", response_data);
13240
13241 // Set up an initial SpdySession in the pool to reuse.
bnc8bef8da22016-05-30 01:28:2513242 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4013243 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
Matt Menke2436b2f2018-12-11 18:07:1113244 PRIVACY_MODE_DISABLED,
13245 SpdySessionKey::IsProxySession::kFalse, SocketTag());
[email protected]795cbf82013-07-22 09:37:2713246 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:5213247 CreateSpdySession(session.get(), key, NetLogWithSource());
[email protected]02b0c342010-09-25 21:09:3813248
bnc87dcefc2017-05-25 12:47:5813249 trans =
Jeremy Roman0579ed62017-08-29 15:56:1913250 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5413251
tfarina42834112016-09-22 13:38:2013252 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113253 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13254 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5413255
13256 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5213257 ASSERT_TRUE(response);
13258 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213259 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5313260 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213261 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5413262
robpercival214763f2016-07-01 23:27:0113263 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5413264 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:4213265}
13266
[email protected]044de0642010-06-17 10:42:1513267// GenerateAuthToken is a mighty big test.
13268// It tests all permutation of GenerateAuthToken behavior:
13269// - Synchronous and Asynchronous completion.
13270// - OK or error on completion.
13271// - Direct connection, non-authenticating proxy, and authenticating proxy.
13272// - HTTP or HTTPS backend (to include proxy tunneling).
13273// - Non-authenticating and authenticating backend.
13274//
[email protected]fe3b7dc2012-02-03 19:52:0913275// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:1513276// problems generating an auth token for an authenticating proxy, we don't
13277// need to test all permutations of the backend server).
13278//
13279// The test proceeds by going over each of the configuration cases, and
13280// potentially running up to three rounds in each of the tests. The TestConfig
13281// specifies both the configuration for the test as well as the expectations
13282// for the results.
bncd16676a2016-07-20 16:23:0113283TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:5013284 static const char kServer[] = "http://www.example.com";
13285 static const char kSecureServer[] = "https://www.example.com";
13286 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:1513287
13288 enum AuthTiming {
13289 AUTH_NONE,
13290 AUTH_SYNC,
13291 AUTH_ASYNC,
13292 };
13293
13294 const MockWrite kGet(
13295 "GET / HTTP/1.1\r\n"
13296 "Host: www.example.com\r\n"
13297 "Connection: keep-alive\r\n\r\n");
13298 const MockWrite kGetProxy(
13299 "GET http://www.example.com/ HTTP/1.1\r\n"
13300 "Host: www.example.com\r\n"
13301 "Proxy-Connection: keep-alive\r\n\r\n");
13302 const MockWrite kGetAuth(
13303 "GET / HTTP/1.1\r\n"
13304 "Host: www.example.com\r\n"
13305 "Connection: keep-alive\r\n"
13306 "Authorization: auth_token\r\n\r\n");
13307 const MockWrite kGetProxyAuth(
13308 "GET http://www.example.com/ HTTP/1.1\r\n"
13309 "Host: www.example.com\r\n"
13310 "Proxy-Connection: keep-alive\r\n"
13311 "Proxy-Authorization: auth_token\r\n\r\n");
13312 const MockWrite kGetAuthThroughProxy(
13313 "GET http://www.example.com/ HTTP/1.1\r\n"
13314 "Host: www.example.com\r\n"
13315 "Proxy-Connection: keep-alive\r\n"
13316 "Authorization: auth_token\r\n\r\n");
13317 const MockWrite kGetAuthWithProxyAuth(
13318 "GET http://www.example.com/ HTTP/1.1\r\n"
13319 "Host: www.example.com\r\n"
13320 "Proxy-Connection: keep-alive\r\n"
13321 "Proxy-Authorization: auth_token\r\n"
13322 "Authorization: auth_token\r\n\r\n");
13323 const MockWrite kConnect(
13324 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1713325 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1513326 "Proxy-Connection: keep-alive\r\n\r\n");
13327 const MockWrite kConnectProxyAuth(
13328 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1713329 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1513330 "Proxy-Connection: keep-alive\r\n"
13331 "Proxy-Authorization: auth_token\r\n\r\n");
13332
13333 const MockRead kSuccess(
13334 "HTTP/1.1 200 OK\r\n"
13335 "Content-Type: text/html; charset=iso-8859-1\r\n"
13336 "Content-Length: 3\r\n\r\n"
13337 "Yes");
13338 const MockRead kFailure(
13339 "Should not be called.");
13340 const MockRead kServerChallenge(
13341 "HTTP/1.1 401 Unauthorized\r\n"
13342 "WWW-Authenticate: Mock realm=server\r\n"
13343 "Content-Type: text/html; charset=iso-8859-1\r\n"
13344 "Content-Length: 14\r\n\r\n"
13345 "Unauthorized\r\n");
13346 const MockRead kProxyChallenge(
13347 "HTTP/1.1 407 Unauthorized\r\n"
13348 "Proxy-Authenticate: Mock realm=proxy\r\n"
13349 "Proxy-Connection: close\r\n"
13350 "Content-Type: text/html; charset=iso-8859-1\r\n"
13351 "Content-Length: 14\r\n\r\n"
13352 "Unauthorized\r\n");
13353 const MockRead kProxyConnected(
13354 "HTTP/1.1 200 Connection Established\r\n\r\n");
13355
13356 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
13357 // no constructors, but the C++ compiler on Windows warns about
13358 // unspecified data in compound literals. So, moved to using constructors,
13359 // and TestRound's created with the default constructor should not be used.
13360 struct TestRound {
13361 TestRound()
13362 : expected_rv(ERR_UNEXPECTED),
13363 extra_write(NULL),
13364 extra_read(NULL) {
13365 }
13366 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
13367 int expected_rv_arg)
13368 : write(write_arg),
13369 read(read_arg),
13370 expected_rv(expected_rv_arg),
13371 extra_write(NULL),
13372 extra_read(NULL) {
13373 }
13374 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
13375 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:0113376 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:1513377 : write(write_arg),
13378 read(read_arg),
13379 expected_rv(expected_rv_arg),
13380 extra_write(extra_write_arg),
13381 extra_read(extra_read_arg) {
13382 }
13383 MockWrite write;
13384 MockRead read;
13385 int expected_rv;
13386 const MockWrite* extra_write;
13387 const MockRead* extra_read;
13388 };
13389
13390 static const int kNoSSL = 500;
13391
13392 struct TestConfig {
asanka463ca4262016-11-16 02:34:3113393 int line_number;
thestig9d3bb0c2015-01-24 00:49:5113394 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:1513395 AuthTiming proxy_auth_timing;
asanka463ca4262016-11-16 02:34:3113396 int first_generate_proxy_token_rv;
thestig9d3bb0c2015-01-24 00:49:5113397 const char* const server_url;
[email protected]044de0642010-06-17 10:42:1513398 AuthTiming server_auth_timing;
asanka463ca4262016-11-16 02:34:3113399 int first_generate_server_token_rv;
[email protected]044de0642010-06-17 10:42:1513400 int num_auth_rounds;
13401 int first_ssl_round;
asankae2257db2016-10-11 22:03:1613402 TestRound rounds[4];
[email protected]044de0642010-06-17 10:42:1513403 } test_configs[] = {
asankac93076192016-10-03 15:46:0213404 // Non-authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3113405 {__LINE__,
13406 nullptr,
asankac93076192016-10-03 15:46:0213407 AUTH_NONE,
13408 OK,
13409 kServer,
13410 AUTH_NONE,
13411 OK,
13412 1,
13413 kNoSSL,
13414 {TestRound(kGet, kSuccess, OK)}},
13415 // Authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3113416 {__LINE__,
13417 nullptr,
asankac93076192016-10-03 15:46:0213418 AUTH_NONE,
13419 OK,
13420 kServer,
13421 AUTH_SYNC,
13422 OK,
13423 2,
13424 kNoSSL,
13425 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513426 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113427 {__LINE__,
13428 nullptr,
asankac93076192016-10-03 15:46:0213429 AUTH_NONE,
13430 OK,
13431 kServer,
13432 AUTH_SYNC,
13433 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1613434 3,
13435 kNoSSL,
13436 {TestRound(kGet, kServerChallenge, OK),
13437 TestRound(kGet, kServerChallenge, OK),
13438 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113439 {__LINE__,
13440 nullptr,
asankae2257db2016-10-11 22:03:1613441 AUTH_NONE,
13442 OK,
13443 kServer,
13444 AUTH_SYNC,
13445 ERR_UNSUPPORTED_AUTH_SCHEME,
13446 2,
13447 kNoSSL,
13448 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113449 {__LINE__,
13450 nullptr,
asankae2257db2016-10-11 22:03:1613451 AUTH_NONE,
13452 OK,
13453 kServer,
13454 AUTH_SYNC,
13455 ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS,
13456 2,
13457 kNoSSL,
13458 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113459 {__LINE__,
13460 kProxy,
asankae2257db2016-10-11 22:03:1613461 AUTH_SYNC,
13462 ERR_FAILED,
13463 kServer,
13464 AUTH_NONE,
13465 OK,
13466 2,
13467 kNoSSL,
13468 {TestRound(kGetProxy, kProxyChallenge, OK),
13469 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3113470 {__LINE__,
13471 kProxy,
asankae2257db2016-10-11 22:03:1613472 AUTH_ASYNC,
13473 ERR_FAILED,
13474 kServer,
13475 AUTH_NONE,
13476 OK,
13477 2,
13478 kNoSSL,
13479 {TestRound(kGetProxy, kProxyChallenge, OK),
13480 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3113481 {__LINE__,
13482 nullptr,
asankae2257db2016-10-11 22:03:1613483 AUTH_NONE,
13484 OK,
13485 kServer,
13486 AUTH_SYNC,
13487 ERR_FAILED,
asankac93076192016-10-03 15:46:0213488 2,
13489 kNoSSL,
13490 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613491 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3113492 {__LINE__,
13493 nullptr,
asankae2257db2016-10-11 22:03:1613494 AUTH_NONE,
13495 OK,
13496 kServer,
13497 AUTH_ASYNC,
13498 ERR_FAILED,
13499 2,
13500 kNoSSL,
13501 {TestRound(kGet, kServerChallenge, OK),
13502 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3113503 {__LINE__,
13504 nullptr,
asankac93076192016-10-03 15:46:0213505 AUTH_NONE,
13506 OK,
13507 kServer,
13508 AUTH_ASYNC,
13509 OK,
13510 2,
13511 kNoSSL,
13512 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513513 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113514 {__LINE__,
13515 nullptr,
asankac93076192016-10-03 15:46:0213516 AUTH_NONE,
13517 OK,
13518 kServer,
13519 AUTH_ASYNC,
13520 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1613521 3,
asankac93076192016-10-03 15:46:0213522 kNoSSL,
13523 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613524 // The second round uses a HttpAuthHandlerMock that always succeeds.
13525 TestRound(kGet, kServerChallenge, OK),
13526 TestRound(kGetAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213527 // Non-authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3113528 {__LINE__,
13529 kProxy,
asankac93076192016-10-03 15:46:0213530 AUTH_NONE,
13531 OK,
13532 kServer,
13533 AUTH_NONE,
13534 OK,
13535 1,
13536 kNoSSL,
13537 {TestRound(kGetProxy, kSuccess, OK)}},
13538 // Authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3113539 {__LINE__,
13540 kProxy,
asankac93076192016-10-03 15:46:0213541 AUTH_NONE,
13542 OK,
13543 kServer,
13544 AUTH_SYNC,
13545 OK,
13546 2,
13547 kNoSSL,
13548 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513549 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113550 {__LINE__,
13551 kProxy,
asankac93076192016-10-03 15:46:0213552 AUTH_NONE,
13553 OK,
13554 kServer,
13555 AUTH_SYNC,
13556 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1613557 3,
asankac93076192016-10-03 15:46:0213558 kNoSSL,
13559 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613560 TestRound(kGetProxy, kServerChallenge, OK),
13561 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113562 {__LINE__,
13563 kProxy,
asankac93076192016-10-03 15:46:0213564 AUTH_NONE,
13565 OK,
13566 kServer,
13567 AUTH_ASYNC,
13568 OK,
13569 2,
13570 kNoSSL,
13571 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513572 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113573 {__LINE__,
13574 kProxy,
asankac93076192016-10-03 15:46:0213575 AUTH_NONE,
13576 OK,
13577 kServer,
13578 AUTH_ASYNC,
13579 ERR_INVALID_AUTH_CREDENTIALS,
13580 2,
13581 kNoSSL,
13582 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613583 TestRound(kGetProxy, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213584 // Non-authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3113585 {__LINE__,
13586 kProxy,
asankac93076192016-10-03 15:46:0213587 AUTH_SYNC,
13588 OK,
13589 kServer,
13590 AUTH_NONE,
13591 OK,
13592 2,
13593 kNoSSL,
13594 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513595 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113596 {__LINE__,
13597 kProxy,
asankac93076192016-10-03 15:46:0213598 AUTH_SYNC,
13599 ERR_INVALID_AUTH_CREDENTIALS,
13600 kServer,
13601 AUTH_NONE,
13602 OK,
13603 2,
13604 kNoSSL,
13605 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1613606 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113607 {__LINE__,
13608 kProxy,
asankac93076192016-10-03 15:46:0213609 AUTH_ASYNC,
13610 OK,
13611 kServer,
13612 AUTH_NONE,
13613 OK,
13614 2,
13615 kNoSSL,
13616 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513617 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113618 {__LINE__,
13619 kProxy,
asankac93076192016-10-03 15:46:0213620 AUTH_ASYNC,
13621 ERR_INVALID_AUTH_CREDENTIALS,
13622 kServer,
13623 AUTH_NONE,
13624 OK,
13625 2,
13626 kNoSSL,
13627 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1613628 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113629 {__LINE__,
13630 kProxy,
13631 AUTH_ASYNC,
13632 ERR_INVALID_AUTH_CREDENTIALS,
13633 kServer,
13634 AUTH_NONE,
13635 OK,
13636 3,
13637 kNoSSL,
13638 {TestRound(kGetProxy, kProxyChallenge, OK),
13639 TestRound(kGetProxy, kProxyChallenge, OK),
13640 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213641 // Authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3113642 {__LINE__,
13643 kProxy,
asankac93076192016-10-03 15:46:0213644 AUTH_SYNC,
13645 OK,
13646 kServer,
13647 AUTH_SYNC,
13648 OK,
13649 3,
13650 kNoSSL,
13651 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513652 TestRound(kGetProxyAuth, kServerChallenge, OK),
13653 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113654 {__LINE__,
13655 kProxy,
asankac93076192016-10-03 15:46:0213656 AUTH_SYNC,
13657 OK,
13658 kServer,
13659 AUTH_SYNC,
13660 ERR_INVALID_AUTH_CREDENTIALS,
13661 3,
13662 kNoSSL,
13663 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513664 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613665 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113666 {__LINE__,
13667 kProxy,
asankac93076192016-10-03 15:46:0213668 AUTH_ASYNC,
13669 OK,
13670 kServer,
13671 AUTH_SYNC,
13672 OK,
13673 3,
13674 kNoSSL,
13675 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513676 TestRound(kGetProxyAuth, kServerChallenge, OK),
13677 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113678 {__LINE__,
13679 kProxy,
asankac93076192016-10-03 15:46:0213680 AUTH_ASYNC,
13681 OK,
13682 kServer,
13683 AUTH_SYNC,
13684 ERR_INVALID_AUTH_CREDENTIALS,
13685 3,
13686 kNoSSL,
13687 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513688 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613689 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113690 {__LINE__,
13691 kProxy,
asankac93076192016-10-03 15:46:0213692 AUTH_SYNC,
13693 OK,
13694 kServer,
13695 AUTH_ASYNC,
13696 OK,
13697 3,
13698 kNoSSL,
13699 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513700 TestRound(kGetProxyAuth, kServerChallenge, OK),
13701 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113702 {__LINE__,
13703 kProxy,
13704 AUTH_SYNC,
13705 ERR_INVALID_AUTH_CREDENTIALS,
13706 kServer,
13707 AUTH_ASYNC,
13708 OK,
13709 4,
13710 kNoSSL,
13711 {TestRound(kGetProxy, kProxyChallenge, OK),
13712 TestRound(kGetProxy, kProxyChallenge, OK),
13713 TestRound(kGetProxyAuth, kServerChallenge, OK),
13714 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
13715 {__LINE__,
13716 kProxy,
asankac93076192016-10-03 15:46:0213717 AUTH_SYNC,
13718 OK,
13719 kServer,
13720 AUTH_ASYNC,
13721 ERR_INVALID_AUTH_CREDENTIALS,
13722 3,
13723 kNoSSL,
13724 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513725 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613726 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113727 {__LINE__,
13728 kProxy,
asankac93076192016-10-03 15:46:0213729 AUTH_ASYNC,
13730 OK,
13731 kServer,
13732 AUTH_ASYNC,
13733 OK,
13734 3,
13735 kNoSSL,
13736 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513737 TestRound(kGetProxyAuth, kServerChallenge, OK),
13738 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113739 {__LINE__,
13740 kProxy,
asankac93076192016-10-03 15:46:0213741 AUTH_ASYNC,
13742 OK,
13743 kServer,
13744 AUTH_ASYNC,
13745 ERR_INVALID_AUTH_CREDENTIALS,
13746 3,
13747 kNoSSL,
13748 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513749 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613750 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113751 {__LINE__,
13752 kProxy,
13753 AUTH_ASYNC,
13754 ERR_INVALID_AUTH_CREDENTIALS,
13755 kServer,
13756 AUTH_ASYNC,
13757 ERR_INVALID_AUTH_CREDENTIALS,
13758 4,
13759 kNoSSL,
13760 {TestRound(kGetProxy, kProxyChallenge, OK),
13761 TestRound(kGetProxy, kProxyChallenge, OK),
13762 TestRound(kGetProxyAuth, kServerChallenge, OK),
13763 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213764 // Non-authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3113765 {__LINE__,
13766 nullptr,
asankac93076192016-10-03 15:46:0213767 AUTH_NONE,
13768 OK,
13769 kSecureServer,
13770 AUTH_NONE,
13771 OK,
13772 1,
13773 0,
13774 {TestRound(kGet, kSuccess, OK)}},
13775 // Authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3113776 {__LINE__,
13777 nullptr,
asankac93076192016-10-03 15:46:0213778 AUTH_NONE,
13779 OK,
13780 kSecureServer,
13781 AUTH_SYNC,
13782 OK,
13783 2,
13784 0,
13785 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513786 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113787 {__LINE__,
13788 nullptr,
asankac93076192016-10-03 15:46:0213789 AUTH_NONE,
13790 OK,
13791 kSecureServer,
13792 AUTH_SYNC,
13793 ERR_INVALID_AUTH_CREDENTIALS,
13794 2,
13795 0,
asankae2257db2016-10-11 22:03:1613796 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113797 {__LINE__,
13798 nullptr,
asankac93076192016-10-03 15:46:0213799 AUTH_NONE,
13800 OK,
13801 kSecureServer,
13802 AUTH_ASYNC,
13803 OK,
13804 2,
13805 0,
13806 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513807 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113808 {__LINE__,
13809 nullptr,
asankac93076192016-10-03 15:46:0213810 AUTH_NONE,
13811 OK,
13812 kSecureServer,
13813 AUTH_ASYNC,
13814 ERR_INVALID_AUTH_CREDENTIALS,
13815 2,
13816 0,
asankae2257db2016-10-11 22:03:1613817 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213818 // Non-authenticating HTTPS server with a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3113819 {__LINE__,
13820 kProxy,
asankac93076192016-10-03 15:46:0213821 AUTH_NONE,
13822 OK,
13823 kSecureServer,
13824 AUTH_NONE,
13825 OK,
13826 1,
13827 0,
13828 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
13829 // Authenticating HTTPS server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3113830 {__LINE__,
13831 kProxy,
asankac93076192016-10-03 15:46:0213832 AUTH_NONE,
13833 OK,
13834 kSecureServer,
13835 AUTH_SYNC,
13836 OK,
13837 2,
13838 0,
13839 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513840 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113841 {__LINE__,
13842 kProxy,
asankac93076192016-10-03 15:46:0213843 AUTH_NONE,
13844 OK,
13845 kSecureServer,
13846 AUTH_SYNC,
13847 ERR_INVALID_AUTH_CREDENTIALS,
13848 2,
13849 0,
13850 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1613851 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113852 {__LINE__,
13853 kProxy,
asankac93076192016-10-03 15:46:0213854 AUTH_NONE,
13855 OK,
13856 kSecureServer,
13857 AUTH_ASYNC,
13858 OK,
13859 2,
13860 0,
13861 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513862 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113863 {__LINE__,
13864 kProxy,
asankac93076192016-10-03 15:46:0213865 AUTH_NONE,
13866 OK,
13867 kSecureServer,
13868 AUTH_ASYNC,
13869 ERR_INVALID_AUTH_CREDENTIALS,
13870 2,
13871 0,
13872 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1613873 TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213874 // Non-Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3113875 {__LINE__,
13876 kProxy,
asankac93076192016-10-03 15:46:0213877 AUTH_SYNC,
13878 OK,
13879 kSecureServer,
13880 AUTH_NONE,
13881 OK,
13882 2,
13883 1,
13884 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513885 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113886 {__LINE__,
13887 kProxy,
asankac93076192016-10-03 15:46:0213888 AUTH_SYNC,
13889 ERR_INVALID_AUTH_CREDENTIALS,
13890 kSecureServer,
13891 AUTH_NONE,
13892 OK,
13893 2,
13894 kNoSSL,
13895 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1613896 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113897 {__LINE__,
13898 kProxy,
asankae2257db2016-10-11 22:03:1613899 AUTH_SYNC,
13900 ERR_UNSUPPORTED_AUTH_SCHEME,
13901 kSecureServer,
13902 AUTH_NONE,
13903 OK,
13904 2,
13905 kNoSSL,
13906 {TestRound(kConnect, kProxyChallenge, OK),
13907 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113908 {__LINE__,
13909 kProxy,
asankae2257db2016-10-11 22:03:1613910 AUTH_SYNC,
13911 ERR_UNEXPECTED,
13912 kSecureServer,
13913 AUTH_NONE,
13914 OK,
13915 2,
13916 kNoSSL,
13917 {TestRound(kConnect, kProxyChallenge, OK),
13918 TestRound(kConnect, kProxyConnected, ERR_UNEXPECTED)}},
asanka463ca4262016-11-16 02:34:3113919 {__LINE__,
13920 kProxy,
asankac93076192016-10-03 15:46:0213921 AUTH_ASYNC,
13922 OK,
13923 kSecureServer,
13924 AUTH_NONE,
13925 OK,
13926 2,
13927 1,
13928 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513929 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113930 {__LINE__,
13931 kProxy,
asankac93076192016-10-03 15:46:0213932 AUTH_ASYNC,
13933 ERR_INVALID_AUTH_CREDENTIALS,
13934 kSecureServer,
13935 AUTH_NONE,
13936 OK,
13937 2,
13938 kNoSSL,
13939 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1613940 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asankac93076192016-10-03 15:46:0213941 // Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3113942 {__LINE__,
13943 kProxy,
asankac93076192016-10-03 15:46:0213944 AUTH_SYNC,
13945 OK,
13946 kSecureServer,
13947 AUTH_SYNC,
13948 OK,
13949 3,
13950 1,
13951 {TestRound(kConnect, kProxyChallenge, OK),
13952 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13953 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513954 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113955 {__LINE__,
13956 kProxy,
asankac93076192016-10-03 15:46:0213957 AUTH_SYNC,
13958 OK,
13959 kSecureServer,
13960 AUTH_SYNC,
13961 ERR_INVALID_AUTH_CREDENTIALS,
13962 3,
13963 1,
13964 {TestRound(kConnect, kProxyChallenge, OK),
13965 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13966 &kServerChallenge),
asankae2257db2016-10-11 22:03:1613967 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113968 {__LINE__,
13969 kProxy,
asankac93076192016-10-03 15:46:0213970 AUTH_ASYNC,
13971 OK,
13972 kSecureServer,
13973 AUTH_SYNC,
13974 OK,
13975 3,
13976 1,
13977 {TestRound(kConnect, kProxyChallenge, OK),
13978 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13979 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513980 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113981 {__LINE__,
13982 kProxy,
asankac93076192016-10-03 15:46:0213983 AUTH_ASYNC,
13984 OK,
13985 kSecureServer,
13986 AUTH_SYNC,
13987 ERR_INVALID_AUTH_CREDENTIALS,
13988 3,
13989 1,
13990 {TestRound(kConnect, kProxyChallenge, OK),
13991 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13992 &kServerChallenge),
asankae2257db2016-10-11 22:03:1613993 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113994 {__LINE__,
13995 kProxy,
asankac93076192016-10-03 15:46:0213996 AUTH_SYNC,
13997 OK,
13998 kSecureServer,
13999 AUTH_ASYNC,
14000 OK,
14001 3,
14002 1,
14003 {TestRound(kConnect, kProxyChallenge, OK),
14004 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14005 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1514006 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114007 {__LINE__,
14008 kProxy,
asankac93076192016-10-03 15:46:0214009 AUTH_SYNC,
14010 OK,
14011 kSecureServer,
14012 AUTH_ASYNC,
14013 ERR_INVALID_AUTH_CREDENTIALS,
14014 3,
14015 1,
14016 {TestRound(kConnect, kProxyChallenge, OK),
14017 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14018 &kServerChallenge),
asankae2257db2016-10-11 22:03:1614019 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114020 {__LINE__,
14021 kProxy,
asankac93076192016-10-03 15:46:0214022 AUTH_ASYNC,
14023 OK,
14024 kSecureServer,
14025 AUTH_ASYNC,
14026 OK,
14027 3,
14028 1,
14029 {TestRound(kConnect, kProxyChallenge, OK),
14030 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14031 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1514032 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114033 {__LINE__,
14034 kProxy,
asankac93076192016-10-03 15:46:0214035 AUTH_ASYNC,
14036 OK,
14037 kSecureServer,
14038 AUTH_ASYNC,
14039 ERR_INVALID_AUTH_CREDENTIALS,
14040 3,
14041 1,
14042 {TestRound(kConnect, kProxyChallenge, OK),
14043 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14044 &kServerChallenge),
asankae2257db2016-10-11 22:03:1614045 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114046 {__LINE__,
14047 kProxy,
14048 AUTH_ASYNC,
14049 ERR_INVALID_AUTH_CREDENTIALS,
14050 kSecureServer,
14051 AUTH_ASYNC,
14052 ERR_INVALID_AUTH_CREDENTIALS,
14053 4,
14054 2,
14055 {TestRound(kConnect, kProxyChallenge, OK),
14056 TestRound(kConnect, kProxyChallenge, OK),
14057 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14058 &kServerChallenge),
14059 TestRound(kGet, kSuccess, OK)}},
[email protected]044de0642010-06-17 10:42:1514060 };
14061
asanka463ca4262016-11-16 02:34:3114062 for (const auto& test_config : test_configs) {
14063 SCOPED_TRACE(::testing::Message() << "Test config at "
14064 << test_config.line_number);
[email protected]2d01c262011-08-11 23:07:0814065 HttpAuthHandlerMock::Factory* auth_factory(
14066 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0714067 session_deps_.http_auth_handler_factory.reset(auth_factory);
asanka5ffd5d72016-03-23 16:20:4914068 SSLInfo empty_ssl_info;
[email protected]65d34382010-07-01 18:12:2614069
14070 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:1514071 if (test_config.proxy_auth_timing != AUTH_NONE) {
asanka463ca4262016-11-16 02:34:3114072 for (int n = 0; n < 3; n++) {
[email protected]2d01c262011-08-11 23:07:0814073 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
14074 std::string auth_challenge = "Mock realm=proxy";
14075 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:2414076 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
14077 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:0814078 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
tfarina42834112016-09-22 13:38:2014079 empty_ssl_info, origin,
14080 NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0814081 auth_handler->SetGenerateExpectation(
14082 test_config.proxy_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3114083 n == 0 ? test_config.first_generate_proxy_token_rv : OK);
[email protected]2d01c262011-08-11 23:07:0814084 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
14085 }
[email protected]044de0642010-06-17 10:42:1514086 }
14087 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:0014088 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:1514089 std::string auth_challenge = "Mock realm=server";
14090 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:2414091 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
14092 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:1514093 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2014094 empty_ssl_info, origin,
14095 NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1514096 auth_handler->SetGenerateExpectation(
14097 test_config.server_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3114098 test_config.first_generate_server_token_rv);
[email protected]2d01c262011-08-11 23:07:0814099 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
asankae2257db2016-10-11 22:03:1614100
14101 // The second handler always succeeds. It should only be used where there
14102 // are multiple auth sessions for server auth in the same network
14103 // transaction using the same auth scheme.
14104 std::unique_ptr<HttpAuthHandlerMock> second_handler =
Jeremy Roman0579ed62017-08-29 15:56:1914105 std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:1614106 second_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
14107 empty_ssl_info, origin,
14108 NetLogWithSource());
14109 second_handler->SetGenerateExpectation(true, OK);
14110 auth_factory->AddMockHandler(second_handler.release(),
14111 HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:1514112 }
14113 if (test_config.proxy_url) {
Lily Houghton8c2f97d2018-01-22 05:06:5914114 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4914115 ProxyResolutionService::CreateFixed(test_config.proxy_url,
14116 TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]044de0642010-06-17 10:42:1514117 } else {
Bence Béky53a5aef2018-03-29 21:54:1214118 session_deps_.proxy_resolution_service =
14119 ProxyResolutionService::CreateDirect();
[email protected]044de0642010-06-17 10:42:1514120 }
14121
14122 HttpRequestInfo request;
14123 request.method = "GET";
14124 request.url = GURL(test_config.server_url);
Ramin Halavatib5e433e2018-02-07 07:41:1014125 request.traffic_annotation =
14126 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]044de0642010-06-17 10:42:1514127
danakj1fd259a02016-04-16 03:17:0914128 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]044de0642010-06-17 10:42:1514129
rchcb68dc62015-05-21 04:45:3614130 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
14131
14132 std::vector<std::vector<MockRead>> mock_reads(1);
14133 std::vector<std::vector<MockWrite>> mock_writes(1);
[email protected]044de0642010-06-17 10:42:1514134 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2214135 SCOPED_TRACE(round);
[email protected]044de0642010-06-17 10:42:1514136 const TestRound& read_write_round = test_config.rounds[round];
14137
14138 // Set up expected reads and writes.
rchcb68dc62015-05-21 04:45:3614139 mock_reads.back().push_back(read_write_round.read);
14140 mock_writes.back().push_back(read_write_round.write);
14141
14142 // kProxyChallenge uses Proxy-Connection: close which means that the
14143 // socket is closed and a new one will be created for the next request.
mmenkee71e15332015-10-07 16:39:5414144 if (read_write_round.read.data == kProxyChallenge.data) {
rchcb68dc62015-05-21 04:45:3614145 mock_reads.push_back(std::vector<MockRead>());
14146 mock_writes.push_back(std::vector<MockWrite>());
[email protected]044de0642010-06-17 10:42:1514147 }
14148
rchcb68dc62015-05-21 04:45:3614149 if (read_write_round.extra_read) {
14150 mock_reads.back().push_back(*read_write_round.extra_read);
[email protected]044de0642010-06-17 10:42:1514151 }
rchcb68dc62015-05-21 04:45:3614152 if (read_write_round.extra_write) {
14153 mock_writes.back().push_back(*read_write_round.extra_write);
14154 }
[email protected]044de0642010-06-17 10:42:1514155
14156 // Add an SSL sequence if necessary.
[email protected]044de0642010-06-17 10:42:1514157 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0714158 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1514159 &ssl_socket_data_provider);
rchcb68dc62015-05-21 04:45:3614160 }
[email protected]044de0642010-06-17 10:42:1514161
danakj1fd259a02016-04-16 03:17:0914162 std::vector<std::unique_ptr<StaticSocketDataProvider>> data_providers;
rchcb68dc62015-05-21 04:45:3614163 for (size_t i = 0; i < mock_reads.size(); ++i) {
Jeremy Roman0579ed62017-08-29 15:56:1914164 data_providers.push_back(std::make_unique<StaticSocketDataProvider>(
Ryan Sleevib8d7ea02018-05-07 20:01:0114165 mock_reads[i], mock_writes[i]));
rchcb68dc62015-05-21 04:45:3614166 session_deps_.socket_factory->AddSocketDataProvider(
olli.raula525048c2015-12-10 07:38:3214167 data_providers.back().get());
rchcb68dc62015-05-21 04:45:3614168 }
14169
mmenkecc2298e2015-12-07 18:20:1814170 // Transaction must be created after DataProviders, so it's destroyed before
14171 // they are as well.
14172 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
14173
rchcb68dc62015-05-21 04:45:3614174 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2214175 SCOPED_TRACE(round);
rchcb68dc62015-05-21 04:45:3614176 const TestRound& read_write_round = test_config.rounds[round];
[email protected]044de0642010-06-17 10:42:1514177 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4114178 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1514179 int rv;
14180 if (round == 0) {
tfarina42834112016-09-22 13:38:2014181 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1514182 } else {
[email protected]49639fa2011-12-20 23:22:4114183 rv = trans.RestartWithAuth(
14184 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1514185 }
14186 if (rv == ERR_IO_PENDING)
14187 rv = callback.WaitForResult();
14188
14189 // Compare results with expected data.
asankae2257db2016-10-11 22:03:1614190 EXPECT_THAT(rv, IsError(read_write_round.expected_rv));
[email protected]0b0bf032010-09-21 18:08:5014191 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttlec0c828492015-05-15 01:25:5514192 if (read_write_round.expected_rv != OK) {
[email protected]044de0642010-06-17 10:42:1514193 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
14194 continue;
14195 }
14196 if (round + 1 < test_config.num_auth_rounds) {
wezca1070932016-05-26 20:30:5214197 EXPECT_TRUE(response->auth_challenge);
[email protected]044de0642010-06-17 10:42:1514198 } else {
wezca1070932016-05-26 20:30:5214199 EXPECT_FALSE(response->auth_challenge);
asankae2257db2016-10-11 22:03:1614200 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]044de0642010-06-17 10:42:1514201 }
14202 }
[email protected]e5ae96a2010-04-14 20:12:4514203 }
14204}
14205
bncd16676a2016-07-20 16:23:0114206TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1414207 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1414208 HttpAuthHandlerMock::Factory* auth_factory(
14209 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0714210 session_deps_.http_auth_handler_factory.reset(auth_factory);
Bence Béky53a5aef2018-03-29 21:54:1214211 session_deps_.proxy_resolution_service =
14212 ProxyResolutionService::CreateDirect();
[email protected]bb88e1d32013-05-03 23:11:0714213 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
[email protected]c871bce92010-07-15 21:51:1414214
14215 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
14216 auth_handler->set_connection_based(true);
14217 std::string auth_challenge = "Mock realm=server";
14218 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2414219 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
14220 auth_challenge.end());
asanka5ffd5d72016-03-23 16:20:4914221 SSLInfo empty_ssl_info;
[email protected]c871bce92010-07-15 21:51:1414222 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2014223 empty_ssl_info, origin, NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0814224 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1414225
[email protected]c871bce92010-07-15 21:51:1414226 int rv = OK;
14227 const HttpResponseInfo* response = NULL;
14228 HttpRequestInfo request;
14229 request.method = "GET";
14230 request.url = origin;
Ramin Halavatib5e433e2018-02-07 07:41:1014231 request.traffic_annotation =
14232 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2714233
danakj1fd259a02016-04-16 03:17:0914234 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1014235
14236 // Use a TCP Socket Pool with only one connection per group. This is used
14237 // to validate that the TCP socket is not released to the pool between
14238 // each round of multi-round authentication.
mmenkee65e7af2015-10-13 17:16:4214239 HttpNetworkSessionPeer session_peer(session.get());
[email protected]ab739042011-04-07 15:22:2814240 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:1014241 50, // Max sockets for pool
14242 1, // Max sockets per group
tbansal7b403bcc2016-04-13 22:33:2114243 session_deps_.host_resolver.get(), session_deps_.socket_factory.get(),
14244 NULL, session_deps_.net_log);
Jeremy Roman0579ed62017-08-29 15:56:1914245 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
[email protected]a42dbd142011-11-17 16:42:0214246 mock_pool_manager->SetTransportSocketPool(transport_pool);
dchengc7eeda422015-12-26 03:56:4814247 session_peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]7ef4cbbb2011-02-06 11:19:1014248
bnc691fda62016-08-12 00:43:1614249 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4114250 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1414251
14252 const MockWrite kGet(
14253 "GET / HTTP/1.1\r\n"
14254 "Host: www.example.com\r\n"
14255 "Connection: keep-alive\r\n\r\n");
14256 const MockWrite kGetAuth(
14257 "GET / HTTP/1.1\r\n"
14258 "Host: www.example.com\r\n"
14259 "Connection: keep-alive\r\n"
14260 "Authorization: auth_token\r\n\r\n");
14261
14262 const MockRead kServerChallenge(
14263 "HTTP/1.1 401 Unauthorized\r\n"
14264 "WWW-Authenticate: Mock realm=server\r\n"
14265 "Content-Type: text/html; charset=iso-8859-1\r\n"
14266 "Content-Length: 14\r\n\r\n"
14267 "Unauthorized\r\n");
14268 const MockRead kSuccess(
14269 "HTTP/1.1 200 OK\r\n"
14270 "Content-Type: text/html; charset=iso-8859-1\r\n"
14271 "Content-Length: 3\r\n\r\n"
14272 "Yes");
14273
14274 MockWrite writes[] = {
14275 // First round
14276 kGet,
14277 // Second round
14278 kGetAuth,
14279 // Third round
14280 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3014281 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1014282 kGetAuth,
14283 // Competing request
14284 kGet,
[email protected]c871bce92010-07-15 21:51:1414285 };
14286 MockRead reads[] = {
14287 // First round
14288 kServerChallenge,
14289 // Second round
14290 kServerChallenge,
14291 // Third round
[email protected]eca50e122010-09-11 14:03:3014292 kServerChallenge,
14293 // Fourth round
[email protected]c871bce92010-07-15 21:51:1414294 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1014295 // Competing response
14296 kSuccess,
[email protected]c871bce92010-07-15 21:51:1414297 };
Ryan Sleevib8d7ea02018-05-07 20:01:0114298 StaticSocketDataProvider data_provider(reads, writes);
[email protected]bb88e1d32013-05-03 23:11:0714299 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1414300
thestig9d3bb0c2015-01-24 00:49:5114301 const char kSocketGroup[] = "www.example.com:80";
[email protected]7ef4cbbb2011-02-06 11:19:1014302
14303 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1414304 auth_handler->SetGenerateExpectation(false, OK);
tfarina42834112016-09-22 13:38:2014305 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]c871bce92010-07-15 21:51:1414306 if (rv == ERR_IO_PENDING)
14307 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114308 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1614309 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214310 ASSERT_TRUE(response);
14311 EXPECT_TRUE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2814312 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3114313 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
14314 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1414315
[email protected]7ef4cbbb2011-02-06 11:19:1014316 // In between rounds, another request comes in for the same domain.
14317 // It should not be able to grab the TCP socket that trans has already
14318 // claimed.
bnc691fda62016-08-12 00:43:1614319 HttpNetworkTransaction trans_compete(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4114320 TestCompletionCallback callback_compete;
tfarina42834112016-09-22 13:38:2014321 rv = trans_compete.Start(&request, callback_compete.callback(),
14322 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114323 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7ef4cbbb2011-02-06 11:19:1014324 // callback_compete.WaitForResult at this point would stall forever,
14325 // since the HttpNetworkTransaction does not release the request back to
14326 // the pool until after authentication completes.
14327
14328 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1414329 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1614330 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1414331 if (rv == ERR_IO_PENDING)
14332 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114333 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1614334 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214335 ASSERT_TRUE(response);
14336 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2814337 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3114338 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
14339 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1414340
[email protected]7ef4cbbb2011-02-06 11:19:1014341 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1414342 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1614343 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1414344 if (rv == ERR_IO_PENDING)
14345 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114346 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1614347 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214348 ASSERT_TRUE(response);
14349 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2814350 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3114351 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
14352 auth_handler->state());
[email protected]eca50e122010-09-11 14:03:3014353
[email protected]7ef4cbbb2011-02-06 11:19:1014354 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3014355 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1614356 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3014357 if (rv == ERR_IO_PENDING)
14358 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114359 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1614360 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214361 ASSERT_TRUE(response);
14362 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2814363 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1014364
asanka463ca4262016-11-16 02:34:3114365 // In WAIT_FOR_CHALLENGE, although in reality the auth handler is done. A real
14366 // auth handler should transition to a DONE state in concert with the remote
14367 // server. But that's not something we can test here with a mock handler.
14368 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_CHALLENGE,
14369 auth_handler->state());
14370
[email protected]7ef4cbbb2011-02-06 11:19:1014371 // Read the body since the fourth round was successful. This will also
14372 // release the socket back to the pool.
Victor Costan9c7302b2018-08-27 16:39:4414373 scoped_refptr<IOBufferWithSize> io_buf =
14374 base::MakeRefCounted<IOBufferWithSize>(50);
bnc691fda62016-08-12 00:43:1614375 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1014376 if (rv == ERR_IO_PENDING)
14377 rv = callback.WaitForResult();
14378 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1614379 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1014380 EXPECT_EQ(0, rv);
14381 // There are still 0 idle sockets, since the trans_compete transaction
14382 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:2814383 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1014384
14385 // The competing request can now finish. Wait for the headers and then
14386 // read the body.
14387 rv = callback_compete.WaitForResult();
robpercival214763f2016-07-01 23:27:0114388 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1614389 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1014390 if (rv == ERR_IO_PENDING)
14391 rv = callback.WaitForResult();
14392 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1614393 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1014394 EXPECT_EQ(0, rv);
14395
14396 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:2814397 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1414398}
14399
[email protected]65041fa2010-05-21 06:56:5314400// This tests the case that a request is issued via http instead of spdy after
14401// npn is negotiated.
bncd16676a2016-07-20 16:23:0114402TEST_F(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]65041fa2010-05-21 06:56:5314403 HttpRequestInfo request;
14404 request.method = "GET";
bncce36dca22015-04-21 22:11:2314405 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1014406 request.traffic_annotation =
14407 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]65041fa2010-05-21 06:56:5314408
14409 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2314410 MockWrite(
14411 "GET / HTTP/1.1\r\n"
14412 "Host: www.example.org\r\n"
14413 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5314414 };
14415
14416 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5214417 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4314418 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5214419 MockRead("\r\n"),
14420 MockRead("hello world"),
14421 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5314422 };
14423
[email protected]8ddf8322012-02-23 18:08:0614424 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614425 ssl.next_proto = kProtoHTTP11;
[email protected]65041fa2010-05-21 06:56:5314426
[email protected]bb88e1d32013-05-03 23:11:0714427 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5314428
Ryan Sleevib8d7ea02018-05-07 20:01:0114429 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0714430 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5314431
[email protected]49639fa2011-12-20 23:22:4114432 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5314433
danakj1fd259a02016-04-16 03:17:0914434 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614435 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]65041fa2010-05-21 06:56:5314436
tfarina42834112016-09-22 13:38:2014437 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]65041fa2010-05-21 06:56:5314438
robpercival214763f2016-07-01 23:27:0114439 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14440 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]65041fa2010-05-21 06:56:5314441
bnc691fda62016-08-12 00:43:1614442 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214443 ASSERT_TRUE(response);
14444 ASSERT_TRUE(response->headers);
[email protected]65041fa2010-05-21 06:56:5314445 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
14446
14447 std::string response_data;
bnc691fda62016-08-12 00:43:1614448 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]65041fa2010-05-21 06:56:5314449 EXPECT_EQ("hello world", response_data);
14450
14451 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214452 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]65041fa2010-05-21 06:56:5314453}
[email protected]26ef6582010-06-24 02:30:4714454
bnc55ff9da2015-08-19 18:42:3514455// Simulate the SSL handshake completing with an NPN negotiation followed by an
14456// immediate server closing of the socket.
14457// Regression test for https://crbug.com/46369.
bncd16676a2016-07-20 16:23:0114458TEST_F(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:4714459 HttpRequestInfo request;
14460 request.method = "GET";
bncce36dca22015-04-21 22:11:2314461 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1014462 request.traffic_annotation =
14463 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]26ef6582010-06-24 02:30:4714464
[email protected]8ddf8322012-02-23 18:08:0614465 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614466 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0714467 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4714468
Ryan Hamilton0239aac2018-05-19 00:03:1314469 spdy::SpdySerializedFrame req(
14470 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4114471 MockWrite spdy_writes[] = {CreateMockWrite(req, 1)};
[email protected]26ef6582010-06-24 02:30:4714472
14473 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0614474 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4714475 };
14476
Ryan Sleevib8d7ea02018-05-07 20:01:0114477 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0714478 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4714479
[email protected]49639fa2011-12-20 23:22:4114480 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4714481
danakj1fd259a02016-04-16 03:17:0914482 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614483 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]26ef6582010-06-24 02:30:4714484
tfarina42834112016-09-22 13:38:2014485 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114486 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14487 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]26ef6582010-06-24 02:30:4714488}
[email protected]65d34382010-07-01 18:12:2614489
[email protected]795cbf82013-07-22 09:37:2714490// A subclass of HttpAuthHandlerMock that records the request URL when
14491// it gets it. This is needed since the auth handler may get destroyed
14492// before we get a chance to query it.
14493class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
14494 public:
14495 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
14496
Chris Watkins7a41d3552017-12-01 02:13:2714497 ~UrlRecordingHttpAuthHandlerMock() override = default;
[email protected]795cbf82013-07-22 09:37:2714498
14499 protected:
dchengb03027d2014-10-21 12:00:2014500 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
14501 const HttpRequestInfo* request,
Bence Béky7236fb72018-08-01 14:35:0914502 CompletionOnceCallback callback,
dchengb03027d2014-10-21 12:00:2014503 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2714504 *url_ = request->url;
14505 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
Bence Béky7236fb72018-08-01 14:35:0914506 credentials, request, std::move(callback), auth_token);
[email protected]795cbf82013-07-22 09:37:2714507 }
14508
14509 private:
14510 GURL* url_;
14511};
14512
[email protected]8e6441ca2010-08-19 05:56:3814513// Test that if we cancel the transaction as the connection is completing, that
14514// everything tears down correctly.
bncd16676a2016-07-20 16:23:0114515TEST_F(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3814516 // Setup everything about the connection to complete synchronously, so that
14517 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
14518 // for is the callback from the HttpStreamRequest.
14519 // Then cancel the transaction.
14520 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3614521 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3814522 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0614523 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
14524 MockRead(SYNCHRONOUS, "hello world"),
14525 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3814526 };
14527
[email protected]8e6441ca2010-08-19 05:56:3814528 HttpRequestInfo request;
14529 request.method = "GET";
bncce36dca22015-04-21 22:11:2314530 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1014531 request.traffic_annotation =
14532 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8e6441ca2010-08-19 05:56:3814533
danakj1fd259a02016-04-16 03:17:0914534 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5814535 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1914536 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2714537
Ryan Sleevib8d7ea02018-05-07 20:01:0114538 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]8e6441ca2010-08-19 05:56:3814539 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0714540 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3814541
[email protected]49639fa2011-12-20 23:22:4114542 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3814543
vishal.b62985ca92015-04-17 08:45:5114544 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4114545 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114546 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8e6441ca2010-08-19 05:56:3814547 trans.reset(); // Cancel the transaction here.
14548
fdoray92e35a72016-06-10 15:54:5514549 base::RunLoop().RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3014550}
14551
[email protected]ecab6e052014-05-16 14:58:1214552// Test that if a transaction is cancelled after receiving the headers, the
14553// stream is drained properly and added back to the socket pool. The main
14554// purpose of this test is to make sure that an HttpStreamParser can be read
14555// from after the HttpNetworkTransaction and the objects it owns have been
14556// deleted.
14557// See http://crbug.com/368418
bncd16676a2016-07-20 16:23:0114558TEST_F(HttpNetworkTransactionTest, CancelAfterHeaders) {
[email protected]ecab6e052014-05-16 14:58:1214559 MockRead data_reads[] = {
14560 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
14561 MockRead(ASYNC, "Content-Length: 2\r\n"),
14562 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
14563 MockRead(ASYNC, "1"),
14564 // 2 async reads are necessary to trigger a ReadResponseBody call after the
14565 // HttpNetworkTransaction has been deleted.
14566 MockRead(ASYNC, "2"),
14567 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
14568 };
Ryan Sleevib8d7ea02018-05-07 20:01:0114569 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]ecab6e052014-05-16 14:58:1214570 session_deps_.socket_factory->AddSocketDataProvider(&data);
14571
danakj1fd259a02016-04-16 03:17:0914572 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]ecab6e052014-05-16 14:58:1214573
14574 {
14575 HttpRequestInfo request;
14576 request.method = "GET";
bncce36dca22015-04-21 22:11:2314577 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1014578 request.traffic_annotation =
14579 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ecab6e052014-05-16 14:58:1214580
dcheng48459ac22014-08-26 00:46:4114581 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1214582 TestCompletionCallback callback;
14583
tfarina42834112016-09-22 13:38:2014584 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114585 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ecab6e052014-05-16 14:58:1214586 callback.WaitForResult();
14587
14588 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214589 ASSERT_TRUE(response);
14590 EXPECT_TRUE(response->headers);
[email protected]ecab6e052014-05-16 14:58:1214591 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
14592
14593 // The transaction and HttpRequestInfo are deleted.
14594 }
14595
14596 // Let the HttpResponseBodyDrainer drain the socket.
fdoray92e35a72016-06-10 15:54:5514597 base::RunLoop().RunUntilIdle();
[email protected]ecab6e052014-05-16 14:58:1214598
14599 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4114600 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1214601}
14602
[email protected]76a505b2010-08-25 06:23:0014603// Test a basic GET request through a proxy.
bncd16676a2016-07-20 16:23:0114604TEST_F(HttpNetworkTransactionTest, ProxyGet) {
Lily Houghton8c2f97d2018-01-22 05:06:5914605 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4914606 ProxyResolutionService::CreateFixedFromPacResult(
14607 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5114608 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714609 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0914610 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0014611
[email protected]76a505b2010-08-25 06:23:0014612 HttpRequestInfo request;
14613 request.method = "GET";
bncce36dca22015-04-21 22:11:2314614 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1014615 request.traffic_annotation =
14616 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0014617
14618 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2314619 MockWrite(
14620 "GET http://www.example.org/ HTTP/1.1\r\n"
14621 "Host: www.example.org\r\n"
14622 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014623 };
14624
14625 MockRead data_reads1[] = {
14626 MockRead("HTTP/1.1 200 OK\r\n"),
14627 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14628 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0614629 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0014630 };
14631
Ryan Sleevib8d7ea02018-05-07 20:01:0114632 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:0714633 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0014634
[email protected]49639fa2011-12-20 23:22:4114635 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0014636
bnc691fda62016-08-12 00:43:1614637 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0914638 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1614639 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0914640 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
14641 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5014642
bnc691fda62016-08-12 00:43:1614643 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114644 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0014645
14646 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0114647 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:0014648
bnc691fda62016-08-12 00:43:1614649 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214650 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0014651
14652 EXPECT_TRUE(response->headers->IsKeepAlive());
14653 EXPECT_EQ(200, response->headers->response_code());
14654 EXPECT_EQ(100, response->headers->GetContentLength());
14655 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4714656 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
14657 HostPortPair::FromString("myproxy:70")),
14658 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0914659 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
14660 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
14661 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0014662 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2014663
14664 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1614665 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2014666 TestLoadTimingNotReusedWithPac(load_timing_info,
14667 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0014668}
14669
14670// Test a basic HTTPS GET request through a proxy.
bncd16676a2016-07-20 16:23:0114671TEST_F(HttpNetworkTransactionTest, ProxyTunnelGet) {
Lily Houghton8c2f97d2018-01-22 05:06:5914672 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4914673 ProxyResolutionService::CreateFixedFromPacResult(
14674 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5114675 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714676 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0914677 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0014678
[email protected]76a505b2010-08-25 06:23:0014679 HttpRequestInfo request;
14680 request.method = "GET";
bncce36dca22015-04-21 22:11:2314681 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1014682 request.traffic_annotation =
14683 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0014684
14685 // Since we have proxy, should try to establish tunnel.
14686 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1714687 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
14688 "Host: www.example.org:443\r\n"
14689 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014690
rsleevidb16bb02015-11-12 23:47:1714691 MockWrite("GET / HTTP/1.1\r\n"
14692 "Host: www.example.org\r\n"
14693 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014694 };
14695
14696 MockRead data_reads1[] = {
14697 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
14698
14699 MockRead("HTTP/1.1 200 OK\r\n"),
14700 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14701 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0614702 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0014703 };
14704
Ryan Sleevib8d7ea02018-05-07 20:01:0114705 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:0714706 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0614707 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0714708 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0014709
[email protected]49639fa2011-12-20 23:22:4114710 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0014711
bnc691fda62016-08-12 00:43:1614712 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0914713 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1614714 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0914715 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
14716 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5014717
bnc691fda62016-08-12 00:43:1614718 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114719 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0014720
14721 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0114722 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:4614723 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4014724 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0014725 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014726 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
14727 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0014728 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4014729 entries, pos,
mikecirone8b85c432016-09-08 19:11:0014730 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
14731 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0014732
bnc691fda62016-08-12 00:43:1614733 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214734 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0014735
14736 EXPECT_TRUE(response->headers->IsKeepAlive());
14737 EXPECT_EQ(200, response->headers->response_code());
14738 EXPECT_EQ(100, response->headers->GetContentLength());
14739 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
14740 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4714741 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
14742 HostPortPair::FromString("myproxy:70")),
14743 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0914744 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
14745 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
14746 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]029c83b62013-01-24 05:28:2014747
14748 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1614749 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2014750 TestLoadTimingNotReusedWithPac(load_timing_info,
14751 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0014752}
14753
rsleevidb16bb02015-11-12 23:47:1714754// Test a basic HTTPS GET request through a proxy, connecting to an IPv6
14755// literal host.
bncd16676a2016-07-20 16:23:0114756TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetIPv6) {
Lily Houghton8c2f97d2018-01-22 05:06:5914757 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4914758 ProxyResolutionService::CreateFixedFromPacResult(
14759 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
rsleevidb16bb02015-11-12 23:47:1714760 BoundTestNetLog log;
14761 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0914762 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
rsleevidb16bb02015-11-12 23:47:1714763
14764 HttpRequestInfo request;
14765 request.method = "GET";
Eric Romanda790f92018-11-07 19:17:1514766 request.url = GURL("https://[::2]:443/");
Ramin Halavatib5e433e2018-02-07 07:41:1014767 request.traffic_annotation =
14768 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rsleevidb16bb02015-11-12 23:47:1714769
14770 // Since we have proxy, should try to establish tunnel.
14771 MockWrite data_writes1[] = {
Eric Romanda790f92018-11-07 19:17:1514772 MockWrite("CONNECT [::2]:443 HTTP/1.1\r\n"
14773 "Host: [::2]:443\r\n"
rsleevidb16bb02015-11-12 23:47:1714774 "Proxy-Connection: keep-alive\r\n\r\n"),
14775
14776 MockWrite("GET / HTTP/1.1\r\n"
Eric Romanda790f92018-11-07 19:17:1514777 "Host: [::2]\r\n"
rsleevidb16bb02015-11-12 23:47:1714778 "Connection: keep-alive\r\n\r\n"),
14779 };
14780
14781 MockRead data_reads1[] = {
14782 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
14783
14784 MockRead("HTTP/1.1 200 OK\r\n"),
14785 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14786 MockRead("Content-Length: 100\r\n\r\n"),
14787 MockRead(SYNCHRONOUS, OK),
14788 };
14789
Ryan Sleevib8d7ea02018-05-07 20:01:0114790 StaticSocketDataProvider data1(data_reads1, data_writes1);
rsleevidb16bb02015-11-12 23:47:1714791 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14792 SSLSocketDataProvider ssl(ASYNC, OK);
14793 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14794
14795 TestCompletionCallback callback1;
14796
bnc691fda62016-08-12 00:43:1614797 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
rsleevidb16bb02015-11-12 23:47:1714798
bnc691fda62016-08-12 00:43:1614799 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114800 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rsleevidb16bb02015-11-12 23:47:1714801
14802 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0114803 EXPECT_THAT(rv, IsOk());
rsleevidb16bb02015-11-12 23:47:1714804 TestNetLogEntry::List entries;
14805 log.GetEntries(&entries);
14806 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014807 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
14808 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1714809 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014810 entries, pos,
14811 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
14812 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1714813
bnc691fda62016-08-12 00:43:1614814 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214815 ASSERT_TRUE(response);
rsleevidb16bb02015-11-12 23:47:1714816
14817 EXPECT_TRUE(response->headers->IsKeepAlive());
14818 EXPECT_EQ(200, response->headers->response_code());
14819 EXPECT_EQ(100, response->headers->GetContentLength());
14820 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
14821 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4714822 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
14823 HostPortPair::FromString("myproxy:70")),
14824 response->proxy_server);
rsleevidb16bb02015-11-12 23:47:1714825
14826 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1614827 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
rsleevidb16bb02015-11-12 23:47:1714828 TestLoadTimingNotReusedWithPac(load_timing_info,
14829 CONNECT_TIMING_HAS_SSL_TIMES);
14830}
14831
[email protected]76a505b2010-08-25 06:23:0014832// Test a basic HTTPS GET request through a proxy, but the server hangs up
14833// while establishing the tunnel.
bncd16676a2016-07-20 16:23:0114834TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
Ramin Halavatica8d5252018-03-12 05:33:4914835 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
14836 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5114837 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714838 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0914839 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0014840
[email protected]76a505b2010-08-25 06:23:0014841 HttpRequestInfo request;
14842 request.method = "GET";
bncce36dca22015-04-21 22:11:2314843 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1014844 request.traffic_annotation =
14845 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0014846
14847 // Since we have proxy, should try to establish tunnel.
14848 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1714849 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
14850 "Host: www.example.org:443\r\n"
14851 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014852
rsleevidb16bb02015-11-12 23:47:1714853 MockWrite("GET / HTTP/1.1\r\n"
14854 "Host: www.example.org\r\n"
14855 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014856 };
14857
14858 MockRead data_reads1[] = {
[email protected]76a505b2010-08-25 06:23:0014859 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0614860 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0014861 };
14862
Ryan Sleevib8d7ea02018-05-07 20:01:0114863 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:0714864 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0614865 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0714866 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0014867
[email protected]49639fa2011-12-20 23:22:4114868 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0014869
bnc691fda62016-08-12 00:43:1614870 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5014871
bnc691fda62016-08-12 00:43:1614872 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114873 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0014874
14875 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0114876 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
mmenke43758e62015-05-04 21:09:4614877 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4014878 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0014879 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014880 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
14881 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0014882 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4014883 entries, pos,
mikecirone8b85c432016-09-08 19:11:0014884 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
14885 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0014886}
14887
[email protected]749eefa82010-09-13 22:14:0314888// Test for crbug.com/55424.
bncd16676a2016-07-20 16:23:0114889TEST_F(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
Ryan Hamilton0239aac2018-05-19 00:03:1314890 spdy::SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4914891 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4114892 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]749eefa82010-09-13 22:14:0314893
Ryan Hamilton0239aac2018-05-19 00:03:1314894 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
14895 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0314896 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114897 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0314898 };
14899
Ryan Sleevib8d7ea02018-05-07 20:01:0114900 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0714901 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0314902
[email protected]8ddf8322012-02-23 18:08:0614903 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614904 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0714905 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0314906
danakj1fd259a02016-04-16 03:17:0914907 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0314908
14909 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2314910 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4014911 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
Matt Menke2436b2f2018-12-11 18:07:1114912 PRIVACY_MODE_DISABLED,
14913 SpdySessionKey::IsProxySession::kFalse, SocketTag());
[email protected]795cbf82013-07-22 09:37:2714914 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:5214915 CreateSpdySession(session.get(), key, NetLogWithSource());
[email protected]749eefa82010-09-13 22:14:0314916
14917 HttpRequestInfo request;
14918 request.method = "GET";
bncce36dca22015-04-21 22:11:2314919 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1014920 request.traffic_annotation =
14921 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]749eefa82010-09-13 22:14:0314922
bnc691fda62016-08-12 00:43:1614923 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]749eefa82010-09-13 22:14:0314924
[email protected]41d64e82013-07-03 22:44:2614925 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014926 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114927 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14928 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]749eefa82010-09-13 22:14:0314929}
14930
[email protected]73b8dd222010-11-11 19:55:2414931// Given a net error, cause that error to be returned from the first Write()
bnc691fda62016-08-12 00:43:1614932// call and verify that the HttpNetworkTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0214933void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0714934 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2914935 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2714936 request_info.url = GURL("https://www.example.com/");
14937 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914938 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:1014939 request_info.traffic_annotation =
14940 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2714941
[email protected]8ddf8322012-02-23 18:08:0614942 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2914943 MockWrite data_writes[] = {
14944 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2414945 };
Ryan Sleevib8d7ea02018-05-07 20:01:0114946 StaticSocketDataProvider data(base::span<MockRead>(), data_writes);
[email protected]bb88e1d32013-05-03 23:11:0714947 session_deps_.socket_factory->AddSocketDataProvider(&data);
14948 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2414949
danakj1fd259a02016-04-16 03:17:0914950 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614951 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]73b8dd222010-11-11 19:55:2414952
[email protected]49639fa2011-12-20 23:22:4114953 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014954 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
ttuttle859dc7a2015-04-23 19:42:2914955 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2414956 rv = callback.WaitForResult();
14957 ASSERT_EQ(error, rv);
14958}
14959
bncd16676a2016-07-20 16:23:0114960TEST_F(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2414961 // Just check a grab bag of cert errors.
14962 static const int kErrors[] = {
14963 ERR_CERT_COMMON_NAME_INVALID,
14964 ERR_CERT_AUTHORITY_INVALID,
14965 ERR_CERT_DATE_INVALID,
14966 };
Avi Drissman4365a4782018-12-28 19:26:2414967 for (size_t i = 0; i < base::size(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0614968 CheckErrorIsPassedBack(kErrors[i], ASYNC);
14969 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2414970 }
14971}
14972
[email protected]bd0b6772011-01-11 19:59:3014973// Ensure that a client certificate is removed from the SSL client auth
14974// cache when:
14975// 1) No proxy is involved.
14976// 2) TLS False Start is disabled.
14977// 3) The initial TLS handshake requests a client certificate.
14978// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0114979TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_NoFalseStart) {
ttuttle859dc7a2015-04-23 19:42:2914980 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2714981 request_info.url = GURL("https://www.example.com/");
14982 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914983 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:1014984 request_info.traffic_annotation =
14985 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2714986
[email protected]bd0b6772011-01-11 19:59:3014987 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4114988 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3014989
14990 // [ssl_]data1 contains the data for the first SSL handshake. When a
14991 // CertificateRequest is received for the first time, the handshake will
14992 // be aborted to allow the caller to provide a certificate.
ttuttle859dc7a2015-04-23 19:42:2914993 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3014994 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714995 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
Ryan Sleevib8d7ea02018-05-07 20:01:0114996 StaticSocketDataProvider data1;
[email protected]bb88e1d32013-05-03 23:11:0714997 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3014998
14999 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
15000 // False Start is not being used, the result of the SSL handshake will be
15001 // returned as part of the SSLClientSocket::Connect() call. This test
15002 // matches the result of a server sending a handshake_failure alert,
15003 // rather than a Finished message, because it requires a client
15004 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2915005 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3015006 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715007 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
Ryan Sleevib8d7ea02018-05-07 20:01:0115008 StaticSocketDataProvider data2;
[email protected]bb88e1d32013-05-03 23:11:0715009 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3015010
15011 // [ssl_]data3 contains the data for the third SSL handshake. When a
15012 // connection to a server fails during an SSL handshake,
Steven Valdez0ef94d02018-11-19 23:28:1315013 // HttpNetworkTransaction will attempt to fallback to TLSv1.2 if the previous
15014 // connection was attempted with TLSv1.3. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3015015 // of the HttpNetworkTransaction. Because this test failure is due to
15016 // requiring a client certificate, this fallback handshake should also
15017 // fail.
ttuttle859dc7a2015-04-23 19:42:2915018 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
Steven Valdez0ef94d02018-11-19 23:28:1315019 ssl_data3.expected_ssl_version_max = SSL_PROTOCOL_VERSION_TLS1_2;
[email protected]bd0b6772011-01-11 19:59:3015020 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715021 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
Ryan Sleevib8d7ea02018-05-07 20:01:0115022 StaticSocketDataProvider data3;
[email protected]bb88e1d32013-05-03 23:11:0715023 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3015024
[email protected]80c75f682012-05-26 16:22:1715025 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
15026 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4215027 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
15028 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]80c75f682012-05-26 16:22:1715029 // of the HttpNetworkTransaction. Because this test failure is due to
15030 // requiring a client certificate, this fallback handshake should also
15031 // fail.
ttuttle859dc7a2015-04-23 19:42:2915032 SSLSocketDataProvider ssl_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1715033 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715034 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
Ryan Sleevib8d7ea02018-05-07 20:01:0115035 StaticSocketDataProvider data4;
[email protected]bb88e1d32013-05-03 23:11:0715036 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1715037
danakj1fd259a02016-04-16 03:17:0915038 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615039 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3015040
[email protected]bd0b6772011-01-11 19:59:3015041 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4115042 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2015043 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115044 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3015045
15046 // Complete the SSL handshake, which should abort due to requiring a
15047 // client certificate.
15048 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115049 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3015050
15051 // Indicate that no certificate should be supplied. From the perspective
15052 // of SSLClientCertCache, NULL is just as meaningful as a real
15053 // certificate, so this is the same as supply a
15054 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1615055 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0115056 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3015057
15058 // Ensure the certificate was added to the client auth cache before
15059 // allowing the connection to continue restarting.
15060 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5415061 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4115062 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415063 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5215064 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3015065
15066 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1715067 // then consume ssl_data3 and ssl_data4, both of which should also fail.
15068 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3015069 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115070 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3015071
15072 // Ensure that the client certificate is removed from the cache on a
15073 // handshake failure.
[email protected]791879c2013-12-17 07:22:4115074 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415075 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3015076}
15077
15078// Ensure that a client certificate is removed from the SSL client auth
15079// cache when:
15080// 1) No proxy is involved.
15081// 2) TLS False Start is enabled.
15082// 3) The initial TLS handshake requests a client certificate.
15083// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0115084TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2915085 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2715086 request_info.url = GURL("https://www.example.com/");
15087 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2915088 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:1015089 request_info.traffic_annotation =
15090 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2715091
[email protected]bd0b6772011-01-11 19:59:3015092 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4115093 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3015094
15095 // When TLS False Start is used, SSLClientSocket::Connect() calls will
15096 // return successfully after reading up to the peer's Certificate message.
15097 // This is to allow the caller to call SSLClientSocket::Write(), which can
15098 // enqueue application data to be sent in the same packet as the
15099 // ChangeCipherSpec and Finished messages.
15100 // The actual handshake will be finished when SSLClientSocket::Read() is
15101 // called, which expects to process the peer's ChangeCipherSpec and
15102 // Finished messages. If there was an error negotiating with the peer,
15103 // such as due to the peer requiring a client certificate when none was
15104 // supplied, the alert sent by the peer won't be processed until Read() is
15105 // called.
15106
15107 // Like the non-False Start case, when a client certificate is requested by
15108 // the peer, the handshake is aborted during the Connect() call.
15109 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2915110 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3015111 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715112 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
Ryan Sleevib8d7ea02018-05-07 20:01:0115113 StaticSocketDataProvider data1;
[email protected]bb88e1d32013-05-03 23:11:0715114 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3015115
15116 // When a client certificate is supplied, Connect() will not be aborted
15117 // when the peer requests the certificate. Instead, the handshake will
15118 // artificially succeed, allowing the caller to write the HTTP request to
15119 // the socket. The handshake messages are not processed until Read() is
15120 // called, which then detects that the handshake was aborted, due to the
15121 // peer sending a handshake_failure because it requires a client
15122 // certificate.
ttuttle859dc7a2015-04-23 19:42:2915123 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3015124 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715125 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2915126 MockRead data2_reads[] = {
15127 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3015128 };
Ryan Sleevib8d7ea02018-05-07 20:01:0115129 StaticSocketDataProvider data2(data2_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0715130 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3015131
15132 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1715133 // the data for the SSL handshake once the TLSv1.1 connection falls back to
15134 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2915135 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3015136 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715137 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
Ryan Sleevib8d7ea02018-05-07 20:01:0115138 StaticSocketDataProvider data3(data2_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0715139 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3015140
[email protected]80c75f682012-05-26 16:22:1715141 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
15142 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2915143 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1715144 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715145 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
Ryan Sleevib8d7ea02018-05-07 20:01:0115146 StaticSocketDataProvider data4(data2_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0715147 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1715148
[email protected]7799de12013-05-30 05:52:5115149 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2915150 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5115151 ssl_data5.cert_request_info = cert_request.get();
15152 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
Ryan Sleevib8d7ea02018-05-07 20:01:0115153 StaticSocketDataProvider data5(data2_reads, base::span<MockWrite>());
[email protected]7799de12013-05-30 05:52:5115154 session_deps_.socket_factory->AddSocketDataProvider(&data5);
15155
danakj1fd259a02016-04-16 03:17:0915156 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615157 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3015158
[email protected]bd0b6772011-01-11 19:59:3015159 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4115160 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2015161 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115162 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3015163
15164 // Complete the SSL handshake, which should abort due to requiring a
15165 // client certificate.
15166 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115167 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3015168
15169 // Indicate that no certificate should be supplied. From the perspective
15170 // of SSLClientCertCache, NULL is just as meaningful as a real
15171 // certificate, so this is the same as supply a
15172 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1615173 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0115174 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3015175
15176 // Ensure the certificate was added to the client auth cache before
15177 // allowing the connection to continue restarting.
15178 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5415179 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4115180 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415181 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5215182 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3015183
[email protected]bd0b6772011-01-11 19:59:3015184 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1715185 // then consume ssl_data3 and ssl_data4, both of which should also fail.
15186 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3015187 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115188 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3015189
15190 // Ensure that the client certificate is removed from the cache on a
15191 // handshake failure.
[email protected]791879c2013-12-17 07:22:4115192 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415193 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3015194}
15195
[email protected]8c405132011-01-11 22:03:1815196// Ensure that a client certificate is removed from the SSL client auth
15197// cache when:
15198// 1) An HTTPS proxy is involved.
15199// 3) The HTTPS proxy requests a client certificate.
15200// 4) The client supplies an invalid/unacceptable certificate for the
15201// proxy.
15202// The test is repeated twice, first for connecting to an HTTPS endpoint,
15203// then for connecting to an HTTP endpoint.
bncd16676a2016-07-20 16:23:0115204TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
Ramin Halavatica8d5252018-03-12 05:33:4915205 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
15206 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5115207 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0715208 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1815209
15210 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4115211 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1815212
15213 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
15214 // [ssl_]data[1-3]. Rather than represending the endpoint
15215 // (www.example.com:443), they represent failures with the HTTPS proxy
15216 // (proxy:70).
ttuttle859dc7a2015-04-23 19:42:2915217 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1815218 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715219 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
Ryan Sleevib8d7ea02018-05-07 20:01:0115220 StaticSocketDataProvider data1;
[email protected]bb88e1d32013-05-03 23:11:0715221 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1815222
ttuttle859dc7a2015-04-23 19:42:2915223 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1815224 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715225 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
Ryan Sleevib8d7ea02018-05-07 20:01:0115226 StaticSocketDataProvider data2;
[email protected]bb88e1d32013-05-03 23:11:0715227 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1815228
[email protected]80c75f682012-05-26 16:22:1715229 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
15230#if 0
ttuttle859dc7a2015-04-23 19:42:2915231 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1815232 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715233 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
Ryan Sleevib8d7ea02018-05-07 20:01:0115234 StaticSocketDataProvider data3;
[email protected]bb88e1d32013-05-03 23:11:0715235 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1715236#endif
[email protected]8c405132011-01-11 22:03:1815237
ttuttle859dc7a2015-04-23 19:42:2915238 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1815239 requests[0].url = GURL("https://www.example.com/");
15240 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2915241 requests[0].load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:1015242 requests[0].traffic_annotation =
15243 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c405132011-01-11 22:03:1815244
15245 requests[1].url = GURL("http://www.example.com/");
15246 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2915247 requests[1].load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:1015248 requests[1].traffic_annotation =
15249 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c405132011-01-11 22:03:1815250
Avi Drissman4365a4782018-12-28 19:26:2415251 for (size_t i = 0; i < base::size(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0715252 session_deps_.socket_factory->ResetNextMockIndexes();
danakj1fd259a02016-04-16 03:17:0915253 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615254 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]8c405132011-01-11 22:03:1815255
15256 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4115257 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2015258 int rv = trans.Start(&requests[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115259 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1815260
15261 // Complete the SSL handshake, which should abort due to requiring a
15262 // client certificate.
15263 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115264 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]8c405132011-01-11 22:03:1815265
15266 // Indicate that no certificate should be supplied. From the perspective
15267 // of SSLClientCertCache, NULL is just as meaningful as a real
15268 // certificate, so this is the same as supply a
15269 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1615270 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0115271 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1815272
15273 // Ensure the certificate was added to the client auth cache before
15274 // allowing the connection to continue restarting.
15275 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5415276 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4115277 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415278 HostPortPair("proxy", 70), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5215279 ASSERT_FALSE(client_cert);
[email protected]8c405132011-01-11 22:03:1815280 // Ensure the certificate was NOT cached for the endpoint. This only
15281 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4115282 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415283 HostPortPair("www.example.com", 443), &client_cert,
15284 &client_private_key));
[email protected]8c405132011-01-11 22:03:1815285
15286 // Restart the handshake. This will consume ssl_data2, which fails, and
15287 // then consume ssl_data3, which should also fail. The result code is
15288 // checked against what ssl_data3 should return.
15289 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115290 ASSERT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]8c405132011-01-11 22:03:1815291
15292 // Now that the new handshake has failed, ensure that the client
15293 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4115294 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415295 HostPortPair("proxy", 70), &client_cert, &client_private_key));
[email protected]791879c2013-12-17 07:22:4115296 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415297 HostPortPair("www.example.com", 443), &client_cert,
15298 &client_private_key));
[email protected]8c405132011-01-11 22:03:1815299 }
15300}
15301
bncd16676a2016-07-20 16:23:0115302TEST_F(HttpNetworkTransactionTest, UseIPConnectionPooling) {
[email protected]e3ceb682011-06-28 23:55:4615303 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1915304 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0915305 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4615306
bnc032658ba2016-09-26 18:17:1515307 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4615308
Ryan Hamilton0239aac2018-05-19 00:03:1315309 spdy::SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4915310 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3815311 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1315312 spdy::SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3715313 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4615314 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115315 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4615316 };
Ryan Hamilton0239aac2018-05-19 00:03:1315317 spdy::SpdySerializedFrame host1_resp(
15318 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
15319 spdy::SpdySerializedFrame host1_resp_body(
bncdf80d44fd2016-07-15 20:27:4115320 spdy_util_.ConstructSpdyDataFrame(1, true));
Ryan Hamilton0239aac2018-05-19 00:03:1315321 spdy::SpdySerializedFrame host2_resp(
15322 spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
15323 spdy::SpdySerializedFrame host2_resp_body(
bncdf80d44fd2016-07-15 20:27:4115324 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4615325 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115326 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
15327 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1315328 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4615329 };
15330
eroman36d84e54432016-03-17 03:23:0215331 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0215332 MockConnect connect(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115333 SequencedSocketData spdy_data(connect, spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0715334 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4615335
[email protected]aa22b242011-11-16 18:58:2915336 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4615337 HttpRequestInfo request1;
15338 request1.method = "GET";
bncce36dca22015-04-21 22:11:2315339 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4615340 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015341 request1.traffic_annotation =
15342 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015343 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4615344
tfarina42834112016-09-22 13:38:2015345 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115346 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15347 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615348
15349 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5215350 ASSERT_TRUE(response);
15351 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215352 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4615353
15354 std::string response_data;
robpercival214763f2016-07-01 23:27:0115355 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615356 EXPECT_EQ("hello!", response_data);
15357
bnca4d611d2016-09-22 19:55:3715358 // Preload mail.example.com into HostCache.
15359 HostPortPair host_port("mail.example.com", 443);
[email protected]5109c1952013-08-20 18:44:1015360 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4615361 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1015362 std::unique_ptr<HostResolver::Request> request;
15363 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
15364 &ignored, callback.callback(),
tfarina42834112016-09-22 13:38:2015365 &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115366 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4715367 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115368 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4615369
15370 HttpRequestInfo request2;
15371 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3715372 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4615373 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015374 request2.traffic_annotation =
15375 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015376 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4615377
tfarina42834112016-09-22 13:38:2015378 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115379 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15380 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615381
15382 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215383 ASSERT_TRUE(response);
15384 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215385 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4615386 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215387 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115388 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615389 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4615390}
15391
bncd16676a2016-07-20 16:23:0115392TEST_F(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d2b5f092012-06-08 23:55:0215393 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1915394 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0915395 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0215396
bnc032658ba2016-09-26 18:17:1515397 AddSSLSocketData();
[email protected]d2b5f092012-06-08 23:55:0215398
Ryan Hamilton0239aac2018-05-19 00:03:1315399 spdy::SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4915400 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3815401 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1315402 spdy::SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3715403 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0215404 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115405 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0215406 };
Ryan Hamilton0239aac2018-05-19 00:03:1315407 spdy::SpdySerializedFrame host1_resp(
15408 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
15409 spdy::SpdySerializedFrame host1_resp_body(
bncdf80d44fd2016-07-15 20:27:4115410 spdy_util_.ConstructSpdyDataFrame(1, true));
Ryan Hamilton0239aac2018-05-19 00:03:1315411 spdy::SpdySerializedFrame host2_resp(
15412 spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
15413 spdy::SpdySerializedFrame host2_resp_body(
bncdf80d44fd2016-07-15 20:27:4115414 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0215415 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115416 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
15417 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1315418 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0215419 };
15420
eroman36d84e54432016-03-17 03:23:0215421 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0215422 MockConnect connect(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115423 SequencedSocketData spdy_data(connect, spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0715424 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0215425
15426 TestCompletionCallback callback;
15427 HttpRequestInfo request1;
15428 request1.method = "GET";
bncce36dca22015-04-21 22:11:2315429 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0215430 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015431 request1.traffic_annotation =
15432 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015433 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0215434
tfarina42834112016-09-22 13:38:2015435 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115436 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15437 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0215438
15439 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5215440 ASSERT_TRUE(response);
15441 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215442 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0215443
15444 std::string response_data;
robpercival214763f2016-07-01 23:27:0115445 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0215446 EXPECT_EQ("hello!", response_data);
15447
15448 HttpRequestInfo request2;
15449 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3715450 request2.url = GURL("https://mail.example.com/");
[email protected]d2b5f092012-06-08 23:55:0215451 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015452 request2.traffic_annotation =
15453 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015454 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0215455
tfarina42834112016-09-22 13:38:2015456 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115457 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15458 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0215459
15460 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215461 ASSERT_TRUE(response);
15462 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215463 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0215464 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215465 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115466 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0215467 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0215468}
15469
bnc8016c1f2017-03-31 02:11:2915470// Regression test for https://crbug.com/546991.
15471// The server might not be able to serve an IP pooled request, and might send a
15472// 421 Misdirected Request response status to indicate this.
15473// HttpNetworkTransaction should reset the request and retry without IP pooling.
15474TEST_F(HttpNetworkTransactionTest, RetryWithoutConnectionPooling) {
15475 // Two hosts resolve to the same IP address.
15476 const std::string ip_addr = "1.2.3.4";
15477 IPAddress ip;
15478 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
15479 IPEndPoint peer_addr = IPEndPoint(ip, 443);
15480
Jeremy Roman0579ed62017-08-29 15:56:1915481 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
bnc8016c1f2017-03-31 02:11:2915482 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
15483 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
15484
15485 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15486
15487 // Two requests on the first connection.
Ryan Hamilton0239aac2018-05-19 00:03:1315488 spdy::SpdySerializedFrame req1(
bnc8016c1f2017-03-31 02:11:2915489 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
15490 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1315491 spdy::SpdySerializedFrame req2(
bnc8016c1f2017-03-31 02:11:2915492 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1315493 spdy::SpdySerializedFrame rst(
15494 spdy_util_.ConstructSpdyRstStream(3, spdy::ERROR_CODE_CANCEL));
bnc8016c1f2017-03-31 02:11:2915495 MockWrite writes1[] = {
15496 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
15497 CreateMockWrite(rst, 6),
15498 };
15499
15500 // The first one succeeds, the second gets error 421 Misdirected Request.
Ryan Hamilton0239aac2018-05-19 00:03:1315501 spdy::SpdySerializedFrame resp1(
15502 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
15503 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
15504 spdy::SpdyHeaderBlock response_headers;
15505 response_headers[spdy::kHttp2StatusHeader] = "421";
15506 spdy::SpdySerializedFrame resp2(
bnc8016c1f2017-03-31 02:11:2915507 spdy_util_.ConstructSpdyReply(3, std::move(response_headers)));
15508 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
15509 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
15510
15511 MockConnect connect1(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115512 SequencedSocketData data1(connect1, reads1, writes1);
bnc8016c1f2017-03-31 02:11:2915513 session_deps_.socket_factory->AddSocketDataProvider(&data1);
15514
15515 AddSSLSocketData();
15516
15517 // Retry the second request on a second connection.
15518 SpdyTestUtil spdy_util2;
Ryan Hamilton0239aac2018-05-19 00:03:1315519 spdy::SpdySerializedFrame req3(
bnc8016c1f2017-03-31 02:11:2915520 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
15521 MockWrite writes2[] = {
15522 CreateMockWrite(req3, 0),
15523 };
15524
Ryan Hamilton0239aac2018-05-19 00:03:1315525 spdy::SpdySerializedFrame resp3(
15526 spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
15527 spdy::SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
bnc8016c1f2017-03-31 02:11:2915528 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
15529 MockRead(ASYNC, 0, 3)};
15530
15531 MockConnect connect2(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115532 SequencedSocketData data2(connect2, reads2, writes2);
bnc8016c1f2017-03-31 02:11:2915533 session_deps_.socket_factory->AddSocketDataProvider(&data2);
15534
15535 AddSSLSocketData();
15536
15537 // Preload mail.example.org into HostCache.
15538 HostPortPair host_port("mail.example.org", 443);
15539 HostResolver::RequestInfo resolve_info(host_port);
15540 AddressList ignored;
15541 std::unique_ptr<HostResolver::Request> request;
15542 TestCompletionCallback callback;
15543 int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
15544 &ignored, callback.callback(),
15545 &request, NetLogWithSource());
15546 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15547 rv = callback.WaitForResult();
15548 EXPECT_THAT(rv, IsOk());
15549
15550 HttpRequestInfo request1;
15551 request1.method = "GET";
15552 request1.url = GURL("https://www.example.org/");
15553 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015554 request1.traffic_annotation =
15555 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8016c1f2017-03-31 02:11:2915556 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
15557
15558 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
15559 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15560 rv = callback.WaitForResult();
15561 EXPECT_THAT(rv, IsOk());
15562
15563 const HttpResponseInfo* response = trans1.GetResponseInfo();
15564 ASSERT_TRUE(response);
15565 ASSERT_TRUE(response->headers);
15566 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
15567 EXPECT_TRUE(response->was_fetched_via_spdy);
15568 EXPECT_TRUE(response->was_alpn_negotiated);
15569 std::string response_data;
15570 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
15571 EXPECT_EQ("hello!", response_data);
15572
15573 HttpRequestInfo request2;
15574 request2.method = "GET";
15575 request2.url = GURL("https://mail.example.org/");
15576 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015577 request2.traffic_annotation =
15578 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8016c1f2017-03-31 02:11:2915579 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
15580
15581 BoundTestNetLog log;
15582 rv = trans2.Start(&request2, callback.callback(), log.bound());
15583 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15584 rv = callback.WaitForResult();
15585 EXPECT_THAT(rv, IsOk());
15586
15587 response = trans2.GetResponseInfo();
15588 ASSERT_TRUE(response);
15589 ASSERT_TRUE(response->headers);
15590 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
15591 EXPECT_TRUE(response->was_fetched_via_spdy);
15592 EXPECT_TRUE(response->was_alpn_negotiated);
15593 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
15594 EXPECT_EQ("hello!", response_data);
15595
15596 TestNetLogEntry::List entries;
15597 log.GetEntries(&entries);
davidbence688ae2017-05-04 15:12:5915598 ExpectLogContainsSomewhere(
15599 entries, 0, NetLogEventType::HTTP_TRANSACTION_RESTART_MISDIRECTED_REQUEST,
bnc8016c1f2017-03-31 02:11:2915600 NetLogEventPhase::NONE);
davidbence688ae2017-05-04 15:12:5915601}
15602
15603// Test that HTTP 421 responses are properly returned to the caller if received
15604// on the retry as well. HttpNetworkTransaction should not infinite loop or lose
15605// portions of the response.
15606TEST_F(HttpNetworkTransactionTest, ReturnHTTP421OnRetry) {
15607 // Two hosts resolve to the same IP address.
15608 const std::string ip_addr = "1.2.3.4";
15609 IPAddress ip;
15610 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
15611 IPEndPoint peer_addr = IPEndPoint(ip, 443);
15612
Jeremy Roman0579ed62017-08-29 15:56:1915613 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
davidbence688ae2017-05-04 15:12:5915614 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
15615 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
15616
15617 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15618
15619 // Two requests on the first connection.
Ryan Hamilton0239aac2018-05-19 00:03:1315620 spdy::SpdySerializedFrame req1(
davidbence688ae2017-05-04 15:12:5915621 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
15622 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1315623 spdy::SpdySerializedFrame req2(
davidbence688ae2017-05-04 15:12:5915624 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1315625 spdy::SpdySerializedFrame rst(
15626 spdy_util_.ConstructSpdyRstStream(3, spdy::ERROR_CODE_CANCEL));
davidbence688ae2017-05-04 15:12:5915627 MockWrite writes1[] = {
15628 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
15629 CreateMockWrite(rst, 6),
15630 };
15631
15632 // The first one succeeds, the second gets error 421 Misdirected Request.
Ryan Hamilton0239aac2018-05-19 00:03:1315633 spdy::SpdySerializedFrame resp1(
15634 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
15635 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
15636 spdy::SpdyHeaderBlock response_headers;
15637 response_headers[spdy::kHttp2StatusHeader] = "421";
15638 spdy::SpdySerializedFrame resp2(
davidbence688ae2017-05-04 15:12:5915639 spdy_util_.ConstructSpdyReply(3, response_headers.Clone()));
15640 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
15641 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
15642
15643 MockConnect connect1(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115644 SequencedSocketData data1(connect1, reads1, writes1);
davidbence688ae2017-05-04 15:12:5915645 session_deps_.socket_factory->AddSocketDataProvider(&data1);
15646
15647 AddSSLSocketData();
15648
15649 // Retry the second request on a second connection. It returns 421 Misdirected
15650 // Retry again.
15651 SpdyTestUtil spdy_util2;
Ryan Hamilton0239aac2018-05-19 00:03:1315652 spdy::SpdySerializedFrame req3(
davidbence688ae2017-05-04 15:12:5915653 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
15654 MockWrite writes2[] = {
15655 CreateMockWrite(req3, 0),
15656 };
15657
Ryan Hamilton0239aac2018-05-19 00:03:1315658 spdy::SpdySerializedFrame resp3(
davidbence688ae2017-05-04 15:12:5915659 spdy_util2.ConstructSpdyReply(1, std::move(response_headers)));
Ryan Hamilton0239aac2018-05-19 00:03:1315660 spdy::SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
davidbence688ae2017-05-04 15:12:5915661 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
15662 MockRead(ASYNC, 0, 3)};
15663
15664 MockConnect connect2(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115665 SequencedSocketData data2(connect2, reads2, writes2);
davidbence688ae2017-05-04 15:12:5915666 session_deps_.socket_factory->AddSocketDataProvider(&data2);
15667
15668 AddSSLSocketData();
15669
15670 // Preload mail.example.org into HostCache.
15671 HostPortPair host_port("mail.example.org", 443);
15672 HostResolver::RequestInfo resolve_info(host_port);
15673 AddressList ignored;
15674 std::unique_ptr<HostResolver::Request> request;
15675 TestCompletionCallback callback;
15676 int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
15677 &ignored, callback.callback(),
15678 &request, NetLogWithSource());
15679 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15680 rv = callback.WaitForResult();
15681 EXPECT_THAT(rv, IsOk());
15682
15683 HttpRequestInfo request1;
15684 request1.method = "GET";
15685 request1.url = GURL("https://www.example.org/");
15686 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015687 request1.traffic_annotation =
15688 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
davidbence688ae2017-05-04 15:12:5915689 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
15690
15691 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
15692 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15693 rv = callback.WaitForResult();
15694 EXPECT_THAT(rv, IsOk());
15695
15696 const HttpResponseInfo* response = trans1.GetResponseInfo();
15697 ASSERT_TRUE(response);
15698 ASSERT_TRUE(response->headers);
15699 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
15700 EXPECT_TRUE(response->was_fetched_via_spdy);
15701 EXPECT_TRUE(response->was_alpn_negotiated);
15702 std::string response_data;
15703 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
15704 EXPECT_EQ("hello!", response_data);
15705
15706 HttpRequestInfo request2;
15707 request2.method = "GET";
15708 request2.url = GURL("https://mail.example.org/");
15709 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015710 request2.traffic_annotation =
15711 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
davidbence688ae2017-05-04 15:12:5915712 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
15713
15714 BoundTestNetLog log;
15715 rv = trans2.Start(&request2, callback.callback(), log.bound());
15716 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15717 rv = callback.WaitForResult();
15718 EXPECT_THAT(rv, IsOk());
15719
15720 // After a retry, the 421 Misdirected Request is reported back up to the
15721 // caller.
15722 response = trans2.GetResponseInfo();
15723 ASSERT_TRUE(response);
15724 ASSERT_TRUE(response->headers);
15725 EXPECT_EQ("HTTP/1.1 421", response->headers->GetStatusLine());
15726 EXPECT_TRUE(response->was_fetched_via_spdy);
15727 EXPECT_TRUE(response->was_alpn_negotiated);
15728 EXPECT_TRUE(response->ssl_info.cert);
15729 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
15730 EXPECT_EQ("hello!", response_data);
bnc8016c1f2017-03-31 02:11:2915731}
15732
bnc6dcd8192017-05-25 20:11:5015733class OneTimeCachingHostResolver : public MockHostResolverBase {
[email protected]e3ceb682011-06-28 23:55:4615734 public:
15735 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
bnc6dcd8192017-05-25 20:11:5015736 : MockHostResolverBase(/* use_caching = */ true), host_port_(host_port) {}
Chris Watkins7a41d3552017-12-01 02:13:2715737 ~OneTimeCachingHostResolver() override = default;
[email protected]e3ceb682011-06-28 23:55:4615738
dchengb03027d2014-10-21 12:00:2015739 int ResolveFromCache(const RequestInfo& info,
15740 AddressList* addresses,
tfarina42834112016-09-22 13:38:2015741 const NetLogWithSource& net_log) override {
bnc6dcd8192017-05-25 20:11:5015742 int rv = MockHostResolverBase::ResolveFromCache(info, addresses, net_log);
[email protected]95a214c2011-08-04 21:50:4015743 if (rv == OK && info.host_port_pair().Equals(host_port_))
bnc6dcd8192017-05-25 20:11:5015744 GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4615745 return rv;
15746 }
15747
[email protected]e3ceb682011-06-28 23:55:4615748 private:
[email protected]e3ceb682011-06-28 23:55:4615749 const HostPortPair host_port_;
15750};
15751
bncd16676a2016-07-20 16:23:0115752TEST_F(HttpNetworkTransactionTest,
mmenke5c642132015-06-02 16:05:1315753 UseIPConnectionPoolingWithHostCacheExpiration) {
[email protected]e3ceb682011-06-28 23:55:4615754 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1915755 session_deps_.host_resolver = std::make_unique<OneTimeCachingHostResolver>(
bnca4d611d2016-09-22 19:55:3715756 HostPortPair("mail.example.com", 443));
danakj1fd259a02016-04-16 03:17:0915757 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4615758
bnc032658ba2016-09-26 18:17:1515759 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4615760
Ryan Hamilton0239aac2018-05-19 00:03:1315761 spdy::SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4915762 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3815763 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1315764 spdy::SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3715765 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4615766 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115767 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4615768 };
Ryan Hamilton0239aac2018-05-19 00:03:1315769 spdy::SpdySerializedFrame host1_resp(
15770 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
15771 spdy::SpdySerializedFrame host1_resp_body(
bncdf80d44fd2016-07-15 20:27:4115772 spdy_util_.ConstructSpdyDataFrame(1, true));
Ryan Hamilton0239aac2018-05-19 00:03:1315773 spdy::SpdySerializedFrame host2_resp(
15774 spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
15775 spdy::SpdySerializedFrame host2_resp_body(
bncdf80d44fd2016-07-15 20:27:4115776 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4615777 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115778 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
15779 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1315780 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4615781 };
15782
eroman36d84e54432016-03-17 03:23:0215783 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0215784 MockConnect connect(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115785 SequencedSocketData spdy_data(connect, spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0715786 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4615787
[email protected]aa22b242011-11-16 18:58:2915788 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4615789 HttpRequestInfo request1;
15790 request1.method = "GET";
bncce36dca22015-04-21 22:11:2315791 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4615792 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015793 request1.traffic_annotation =
15794 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015795 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4615796
tfarina42834112016-09-22 13:38:2015797 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115798 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15799 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615800
15801 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5215802 ASSERT_TRUE(response);
15803 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215804 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4615805
15806 std::string response_data;
robpercival214763f2016-07-01 23:27:0115807 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615808 EXPECT_EQ("hello!", response_data);
15809
15810 // Preload cache entries into HostCache.
bnca4d611d2016-09-22 19:55:3715811 HostResolver::RequestInfo resolve_info(HostPortPair("mail.example.com", 443));
[email protected]e3ceb682011-06-28 23:55:4615812 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1015813 std::unique_ptr<HostResolver::Request> request;
bnc6dcd8192017-05-25 20:11:5015814 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
15815 &ignored, callback.callback(),
15816 &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115817 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4715818 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115819 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4615820
15821 HttpRequestInfo request2;
15822 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3715823 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4615824 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015825 request2.traffic_annotation =
15826 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015827 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4615828
tfarina42834112016-09-22 13:38:2015829 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115830 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15831 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615832
15833 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215834 ASSERT_TRUE(response);
15835 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215836 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4615837 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215838 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115839 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615840 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4615841}
15842
bncd16676a2016-07-20 16:23:0115843TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2315844 const std::string https_url = "https://www.example.org:8080/";
15845 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0415846
15847 // SPDY GET for HTTPS URL
Ryan Hamilton0239aac2018-05-19 00:03:1315848 spdy::SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4915849 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0415850
15851 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4115852 CreateMockWrite(req1, 0),
[email protected]8450d722012-07-02 19:14:0415853 };
15854
Ryan Hamilton0239aac2018-05-19 00:03:1315855 spdy::SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
15856 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
bncdf80d44fd2016-07-15 20:27:4115857 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
mmenkee24011922015-12-17 22:12:5915858 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)};
[email protected]8450d722012-07-02 19:14:0415859
Ryan Sleevib8d7ea02018-05-07 20:01:0115860 SequencedSocketData data1(reads1, writes1);
[email protected]8450d722012-07-02 19:14:0415861 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5715862 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0415863
15864 // HTTP GET for the HTTP URL
15865 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1315866 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3415867 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2315868 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3415869 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0415870 };
15871
15872 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1315873 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
15874 MockRead(ASYNC, 2, "hello"),
15875 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0415876 };
15877
Ryan Sleevib8d7ea02018-05-07 20:01:0115878 SequencedSocketData data2(reads2, writes2);
[email protected]8450d722012-07-02 19:14:0415879
[email protected]8450d722012-07-02 19:14:0415880 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615881 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0715882 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15883 session_deps_.socket_factory->AddSocketDataProvider(&data1);
15884 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0415885
danakj1fd259a02016-04-16 03:17:0915886 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0415887
15888 // Start the first transaction to set up the SpdySession
15889 HttpRequestInfo request1;
15890 request1.method = "GET";
15891 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0415892 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015893 request1.traffic_annotation =
15894 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015895 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0415896 TestCompletionCallback callback1;
15897 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015898 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5515899 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0415900
robpercival214763f2016-07-01 23:27:0115901 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0415902 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
15903
15904 // Now, start the HTTP request
15905 HttpRequestInfo request2;
15906 request2.method = "GET";
15907 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0415908 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015909 request2.traffic_annotation =
15910 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015911 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0415912 TestCompletionCallback callback2;
15913 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015914 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5515915 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0415916
robpercival214763f2016-07-01 23:27:0115917 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0415918 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
15919}
15920
bnc5452e2a2015-05-08 16:27:4215921// Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
15922// with the alternative server. That connection should not be used.
bncd16676a2016-07-20 16:23:0115923TEST_F(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
bnc8bef8da22016-05-30 01:28:2515924 url::SchemeHostPort server("https", "www.example.org", 443);
15925 HostPortPair alternative("www.example.org", 444);
bnc5452e2a2015-05-08 16:27:4215926
bnc8bef8da22016-05-30 01:28:2515927 // Negotiate HTTP/1.1 with alternative.
bnc5452e2a2015-05-08 16:27:4215928 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615929 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4215930 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15931
15932 // No data should be read from the alternative, because HTTP/1.1 is
15933 // negotiated.
15934 StaticSocketDataProvider data;
15935 session_deps_.socket_factory->AddSocketDataProvider(&data);
15936
15937 // This test documents that an alternate Job should not be used if HTTP/1.1 is
zhongyi3d4a55e72016-04-22 20:36:4615938 // negotiated. In order to test this, a failed connection to the server is
bnc5452e2a2015-05-08 16:27:4215939 // mocked. This way the request relies on the alternate Job.
15940 StaticSocketDataProvider data_refused;
15941 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
15942 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
15943
zhongyi3d4a55e72016-04-22 20:36:4615944 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0915945 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4015946 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4215947 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2115948 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1215949 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2115950 http_server_properties->SetHttp2AlternativeService(
15951 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4215952
bnc5452e2a2015-05-08 16:27:4215953 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4615954 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4215955 request.method = "GET";
bnc8bef8da22016-05-30 01:28:2515956 request.url = GURL("https://www.example.org:443");
Ramin Halavatib5e433e2018-02-07 07:41:1015957 request.traffic_annotation =
15958 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4215959 TestCompletionCallback callback;
15960
15961 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
bnc94c92842016-09-21 15:22:5215962 // negotiated, the alternate Job should fail with ERR_ALPN_NEGOTIATION_FAILED.
tfarina42834112016-09-22 13:38:2015963 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc94c92842016-09-21 15:22:5215964 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_ALPN_NEGOTIATION_FAILED));
bnc5452e2a2015-05-08 16:27:4215965}
15966
bnc40448a532015-05-11 19:13:1415967// A request to a server with an alternative service fires two Jobs: one to the
zhongyi3d4a55e72016-04-22 20:36:4615968// server, and an alternate one to the alternative server. If the former
bnc40448a532015-05-11 19:13:1415969// succeeds, the request should succeed, even if the latter fails because
15970// HTTP/1.1 is negotiated which is insufficient for alternative service.
bncd16676a2016-07-20 16:23:0115971TEST_F(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
bnc8bef8da22016-05-30 01:28:2515972 url::SchemeHostPort server("https", "www.example.org", 443);
15973 HostPortPair alternative("www.example.org", 444);
bnc40448a532015-05-11 19:13:1415974
15975 // Negotiate HTTP/1.1 with alternative.
15976 SSLSocketDataProvider alternative_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615977 alternative_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1415978 session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
15979
15980 // No data should be read from the alternative, because HTTP/1.1 is
15981 // negotiated.
15982 StaticSocketDataProvider data;
15983 session_deps_.socket_factory->AddSocketDataProvider(&data);
15984
zhongyi3d4a55e72016-04-22 20:36:4615985 // Negotiate HTTP/1.1 with server.
bnc40448a532015-05-11 19:13:1415986 SSLSocketDataProvider origin_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615987 origin_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1415988 session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
15989
15990 MockWrite http_writes[] = {
bnc8bef8da22016-05-30 01:28:2515991 MockWrite("GET / HTTP/1.1\r\n"
15992 "Host: www.example.org\r\n"
15993 "Connection: keep-alive\r\n\r\n"),
15994 MockWrite("GET /second HTTP/1.1\r\n"
15995 "Host: www.example.org\r\n"
15996 "Connection: keep-alive\r\n\r\n"),
bnc40448a532015-05-11 19:13:1415997 };
15998
15999 MockRead http_reads[] = {
16000 MockRead("HTTP/1.1 200 OK\r\n"),
16001 MockRead("Content-Type: text/html\r\n"),
16002 MockRead("Content-Length: 6\r\n\r\n"),
16003 MockRead("foobar"),
16004 MockRead("HTTP/1.1 200 OK\r\n"),
16005 MockRead("Content-Type: text/html\r\n"),
16006 MockRead("Content-Length: 7\r\n\r\n"),
16007 MockRead("another"),
16008 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116009 StaticSocketDataProvider http_data(http_reads, http_writes);
bnc40448a532015-05-11 19:13:1416010 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16011
zhongyi3d4a55e72016-04-22 20:36:4616012 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0916013 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4016014 HttpServerProperties* http_server_properties =
bnc40448a532015-05-11 19:13:1416015 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2116016 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1216017 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2116018 http_server_properties->SetHttp2AlternativeService(
16019 server, alternative_service, expiration);
bnc40448a532015-05-11 19:13:1416020
16021 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
16022 HttpRequestInfo request1;
16023 request1.method = "GET";
bnc8bef8da22016-05-30 01:28:2516024 request1.url = GURL("https://www.example.org:443");
bnc40448a532015-05-11 19:13:1416025 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016026 request1.traffic_annotation =
16027 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc40448a532015-05-11 19:13:1416028 TestCompletionCallback callback1;
16029
tfarina42834112016-09-22 13:38:2016030 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1416031 rv = callback1.GetResult(rv);
robpercival214763f2016-07-01 23:27:0116032 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1416033
16034 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5216035 ASSERT_TRUE(response1);
16036 ASSERT_TRUE(response1->headers);
bnc40448a532015-05-11 19:13:1416037 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
16038
16039 std::string response_data1;
robpercival214763f2016-07-01 23:27:0116040 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc40448a532015-05-11 19:13:1416041 EXPECT_EQ("foobar", response_data1);
16042
16043 // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
16044 // for alternative service.
16045 EXPECT_TRUE(
16046 http_server_properties->IsAlternativeServiceBroken(alternative_service));
16047
zhongyi3d4a55e72016-04-22 20:36:4616048 // Since |alternative_service| is broken, a second transaction to server
bnc40448a532015-05-11 19:13:1416049 // should not start an alternate Job. It should pool to existing connection
zhongyi3d4a55e72016-04-22 20:36:4616050 // to server.
bnc40448a532015-05-11 19:13:1416051 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
16052 HttpRequestInfo request2;
16053 request2.method = "GET";
bnc8bef8da22016-05-30 01:28:2516054 request2.url = GURL("https://www.example.org:443/second");
bnc40448a532015-05-11 19:13:1416055 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016056 request2.traffic_annotation =
16057 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc40448a532015-05-11 19:13:1416058 TestCompletionCallback callback2;
16059
tfarina42834112016-09-22 13:38:2016060 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1416061 rv = callback2.GetResult(rv);
robpercival214763f2016-07-01 23:27:0116062 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1416063
16064 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5216065 ASSERT_TRUE(response2);
16066 ASSERT_TRUE(response2->headers);
bnc40448a532015-05-11 19:13:1416067 EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
16068
16069 std::string response_data2;
robpercival214763f2016-07-01 23:27:0116070 ASSERT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
bnc40448a532015-05-11 19:13:1416071 EXPECT_EQ("another", response_data2);
16072}
16073
bnc5452e2a2015-05-08 16:27:4216074// Alternative service requires HTTP/2 (or SPDY), but there is already a
16075// HTTP/1.1 socket open to the alternative server. That socket should not be
16076// used.
bncd16676a2016-07-20 16:23:0116077TEST_F(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
zhongyi3d4a55e72016-04-22 20:36:4616078 url::SchemeHostPort server("https", "origin.example.org", 443);
bnc5452e2a2015-05-08 16:27:4216079 HostPortPair alternative("alternative.example.org", 443);
16080 std::string origin_url = "https://origin.example.org:443";
16081 std::string alternative_url = "https://alternative.example.org:443";
16082
16083 // Negotiate HTTP/1.1 with alternative.example.org.
16084 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616085 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4216086 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16087
16088 // HTTP/1.1 data for |request1| and |request2|.
16089 MockWrite http_writes[] = {
16090 MockWrite(
16091 "GET / HTTP/1.1\r\n"
16092 "Host: alternative.example.org\r\n"
16093 "Connection: keep-alive\r\n\r\n"),
16094 MockWrite(
16095 "GET / HTTP/1.1\r\n"
16096 "Host: alternative.example.org\r\n"
16097 "Connection: keep-alive\r\n\r\n"),
16098 };
16099
16100 MockRead http_reads[] = {
16101 MockRead(
16102 "HTTP/1.1 200 OK\r\n"
16103 "Content-Type: text/html; charset=iso-8859-1\r\n"
16104 "Content-Length: 40\r\n\r\n"
16105 "first HTTP/1.1 response from alternative"),
16106 MockRead(
16107 "HTTP/1.1 200 OK\r\n"
16108 "Content-Type: text/html; charset=iso-8859-1\r\n"
16109 "Content-Length: 41\r\n\r\n"
16110 "second HTTP/1.1 response from alternative"),
16111 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116112 StaticSocketDataProvider http_data(http_reads, http_writes);
bnc5452e2a2015-05-08 16:27:4216113 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16114
16115 // This test documents that an alternate Job should not pool to an already
16116 // existing HTTP/1.1 connection. In order to test this, a failed connection
zhongyi3d4a55e72016-04-22 20:36:4616117 // to the server is mocked. This way |request2| relies on the alternate Job.
bnc5452e2a2015-05-08 16:27:4216118 StaticSocketDataProvider data_refused;
16119 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
16120 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
16121
zhongyi3d4a55e72016-04-22 20:36:4616122 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0916123 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4016124 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4216125 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2116126 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1216127 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2116128 http_server_properties->SetHttp2AlternativeService(
16129 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4216130
16131 // First transaction to alternative to open an HTTP/1.1 socket.
bnc5452e2a2015-05-08 16:27:4216132 HttpRequestInfo request1;
krasinc06a72a2016-12-21 03:42:4616133 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4216134 request1.method = "GET";
16135 request1.url = GURL(alternative_url);
16136 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016137 request1.traffic_annotation =
16138 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4216139 TestCompletionCallback callback1;
16140
tfarina42834112016-09-22 13:38:2016141 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116142 EXPECT_THAT(callback1.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1616143 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4216144 ASSERT_TRUE(response1);
wezca1070932016-05-26 20:30:5216145 ASSERT_TRUE(response1->headers);
bnc5452e2a2015-05-08 16:27:4216146 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5216147 EXPECT_TRUE(response1->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4216148 EXPECT_FALSE(response1->was_fetched_via_spdy);
16149 std::string response_data1;
bnc691fda62016-08-12 00:43:1616150 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc5452e2a2015-05-08 16:27:4216151 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
16152
16153 // Request for origin.example.org, which has an alternative service. This
16154 // will start two Jobs: the alternative looks for connections to pool to,
16155 // finds one which is HTTP/1.1, and should ignore it, and should not try to
zhongyi3d4a55e72016-04-22 20:36:4616156 // open other connections to alternative server. The Job to server fails, so
bnc5452e2a2015-05-08 16:27:4216157 // this request fails.
bnc5452e2a2015-05-08 16:27:4216158 HttpRequestInfo request2;
krasinc06a72a2016-12-21 03:42:4616159 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4216160 request2.method = "GET";
16161 request2.url = GURL(origin_url);
16162 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016163 request2.traffic_annotation =
16164 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4216165 TestCompletionCallback callback2;
16166
tfarina42834112016-09-22 13:38:2016167 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116168 EXPECT_THAT(callback2.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc5452e2a2015-05-08 16:27:4216169
16170 // Another transaction to alternative. This is to test that the HTTP/1.1
16171 // socket is still open and in the pool.
bnc5452e2a2015-05-08 16:27:4216172 HttpRequestInfo request3;
krasinc06a72a2016-12-21 03:42:4616173 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4216174 request3.method = "GET";
16175 request3.url = GURL(alternative_url);
16176 request3.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016177 request3.traffic_annotation =
16178 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4216179 TestCompletionCallback callback3;
16180
tfarina42834112016-09-22 13:38:2016181 rv = trans3.Start(&request3, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116182 EXPECT_THAT(callback3.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1616183 const HttpResponseInfo* response3 = trans3.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4216184 ASSERT_TRUE(response3);
wezca1070932016-05-26 20:30:5216185 ASSERT_TRUE(response3->headers);
bnc5452e2a2015-05-08 16:27:4216186 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5216187 EXPECT_TRUE(response3->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4216188 EXPECT_FALSE(response3->was_fetched_via_spdy);
16189 std::string response_data3;
bnc691fda62016-08-12 00:43:1616190 ASSERT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
bnc5452e2a2015-05-08 16:27:4216191 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
16192}
16193
bncd16676a2016-07-20 16:23:0116194TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2316195 const std::string https_url = "https://www.example.org:8080/";
16196 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0416197
rdsmithebb50aa2015-11-12 03:44:3816198 // Separate SPDY util instance for naked and wrapped requests.
bncd16676a2016-07-20 16:23:0116199 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:3816200
[email protected]8450d722012-07-02 19:14:0416201 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2316202 const HostPortPair host_port_pair("www.example.org", 8080);
Ryan Hamilton0239aac2018-05-19 00:03:1316203 spdy::SpdySerializedFrame connect(
lgarrona91df87f2014-12-05 00:51:3416204 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
Ryan Hamilton0239aac2018-05-19 00:03:1316205 spdy::SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4916206 spdy_util_wrapped.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1316207 spdy::SpdySerializedFrame wrapped_req1(
[email protected]23e482282013-06-14 16:08:0216208 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3916209
16210 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
Ryan Hamilton0239aac2018-05-19 00:03:1316211 spdy::SpdyHeaderBlock req2_block;
16212 req2_block[spdy::kHttp2MethodHeader] = "GET";
16213 req2_block[spdy::kHttp2AuthorityHeader] = "www.example.org:8080";
16214 req2_block[spdy::kHttp2SchemeHeader] = "http";
16215 req2_block[spdy::kHttp2PathHeader] = "/";
16216 spdy::SpdySerializedFrame req2(
bnc42331402016-07-25 13:36:1516217 spdy_util_.ConstructSpdyHeaders(3, std::move(req2_block), MEDIUM, true));
[email protected]8450d722012-07-02 19:14:0416218
16219 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4116220 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_req1, 2),
16221 CreateMockWrite(req2, 6),
[email protected]8450d722012-07-02 19:14:0416222 };
16223
Ryan Hamilton0239aac2018-05-19 00:03:1316224 spdy::SpdySerializedFrame conn_resp(
bnc42331402016-07-25 13:36:1516225 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316226 spdy::SpdySerializedFrame resp1(
bnc42331402016-07-25 13:36:1516227 spdy_util_wrapped.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316228 spdy::SpdySerializedFrame body1(
16229 spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
16230 spdy::SpdySerializedFrame wrapped_resp1(
rdsmithebb50aa2015-11-12 03:44:3816231 spdy_util_wrapped.ConstructWrappedSpdyFrame(resp1, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316232 spdy::SpdySerializedFrame wrapped_body1(
rdsmithebb50aa2015-11-12 03:44:3816233 spdy_util_wrapped.ConstructWrappedSpdyFrame(body1, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316234 spdy::SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
16235 spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
mmenke666a6fea2015-12-19 04:16:3316236 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4116237 CreateMockRead(conn_resp, 1),
mmenke666a6fea2015-12-19 04:16:3316238 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:4116239 CreateMockRead(wrapped_resp1, 4),
16240 CreateMockRead(wrapped_body1, 5),
mmenke666a6fea2015-12-19 04:16:3316241 MockRead(ASYNC, ERR_IO_PENDING, 7),
bncdf80d44fd2016-07-15 20:27:4116242 CreateMockRead(resp2, 8),
16243 CreateMockRead(body2, 9),
mmenke666a6fea2015-12-19 04:16:3316244 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 10),
16245 };
[email protected]8450d722012-07-02 19:14:0416246
Ryan Sleevib8d7ea02018-05-07 20:01:0116247 SequencedSocketData data1(reads1, writes1);
[email protected]8450d722012-07-02 19:14:0416248 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5716249 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0416250
Lily Houghton8c2f97d2018-01-22 05:06:5916251 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4916252 ProxyResolutionService::CreateFixedFromPacResult(
16253 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5116254 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0716255 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0416256 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3616257 ssl1.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3316258 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0416259 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3616260 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3316261 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
16262 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0416263
danakj1fd259a02016-04-16 03:17:0916264 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]8450d722012-07-02 19:14:0416265
16266 // Start the first transaction to set up the SpdySession
16267 HttpRequestInfo request1;
16268 request1.method = "GET";
16269 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0416270 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016271 request1.traffic_annotation =
16272 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016273 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0416274 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:2016275 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0416276
mmenke666a6fea2015-12-19 04:16:3316277 // This pause is a hack to avoid running into https://crbug.com/497228.
16278 data1.RunUntilPaused();
16279 base::RunLoop().RunUntilIdle();
16280 data1.Resume();
robpercival214763f2016-07-01 23:27:0116281 EXPECT_THAT(callback1.GetResult(rv), IsOk());
[email protected]8450d722012-07-02 19:14:0416282 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
16283
[email protected]f6c63db52013-02-02 00:35:2216284 LoadTimingInfo load_timing_info1;
16285 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
16286 TestLoadTimingNotReusedWithPac(load_timing_info1,
16287 CONNECT_TIMING_HAS_SSL_TIMES);
16288
mmenke666a6fea2015-12-19 04:16:3316289 // Now, start the HTTP request.
[email protected]8450d722012-07-02 19:14:0416290 HttpRequestInfo request2;
16291 request2.method = "GET";
16292 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0416293 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016294 request2.traffic_annotation =
16295 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016296 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0416297 TestCompletionCallback callback2;
tfarina42834112016-09-22 13:38:2016298 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0416299
mmenke666a6fea2015-12-19 04:16:3316300 // This pause is a hack to avoid running into https://crbug.com/497228.
16301 data1.RunUntilPaused();
16302 base::RunLoop().RunUntilIdle();
16303 data1.Resume();
robpercival214763f2016-07-01 23:27:0116304 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenke666a6fea2015-12-19 04:16:3316305
[email protected]8450d722012-07-02 19:14:0416306 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2216307
16308 LoadTimingInfo load_timing_info2;
16309 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
16310 // The established SPDY sessions is considered reused by the HTTP request.
16311 TestLoadTimingReusedWithPac(load_timing_info2);
16312 // HTTP requests over a SPDY session should have a different connection
16313 // socket_log_id than requests over a tunnel.
16314 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0416315}
16316
[email protected]2d88e7d2012-07-19 17:55:1716317// Test that in the case where we have a SPDY session to a SPDY proxy
16318// that we do not pool other origins that resolve to the same IP when
16319// the certificate does not match the new origin.
16320// http://crbug.com/134690
bncd16676a2016-07-20 16:23:0116321TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2316322 const std::string url1 = "http://www.example.org/";
16323 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1716324 const std::string ip_addr = "1.2.3.4";
16325
rdsmithebb50aa2015-11-12 03:44:3816326 // Second SpdyTestUtil instance for the second socket.
bncd16676a2016-07-20 16:23:0116327 SpdyTestUtil spdy_util_secure;
rdsmithebb50aa2015-11-12 03:44:3816328
[email protected]2d88e7d2012-07-19 17:55:1716329 // SPDY GET for HTTP URL (through SPDY proxy)
Ryan Hamilton0239aac2018-05-19 00:03:1316330 spdy::SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:2316331 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
Ryan Hamilton0239aac2018-05-19 00:03:1316332 spdy::SpdySerializedFrame req1(
bnc42331402016-07-25 13:36:1516333 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
[email protected]2d88e7d2012-07-19 17:55:1716334
16335 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4116336 CreateMockWrite(req1, 0),
[email protected]2d88e7d2012-07-19 17:55:1716337 };
16338
Ryan Hamilton0239aac2018-05-19 00:03:1316339 spdy::SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
16340 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1716341 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4116342 MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(resp1, 2),
16343 CreateMockRead(body1, 3), MockRead(ASYNC, OK, 4), // EOF
[email protected]2d88e7d2012-07-19 17:55:1716344 };
16345
Ryan Sleevib8d7ea02018-05-07 20:01:0116346 SequencedSocketData data1(reads1, writes1);
martijnfe9636e2016-02-06 14:33:3216347 IPAddress ip;
martijn654c8c42016-02-10 22:10:5916348 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
[email protected]2d88e7d2012-07-19 17:55:1716349 IPEndPoint peer_addr = IPEndPoint(ip, 443);
16350 MockConnect connect_data1(ASYNC, OK, peer_addr);
mmenke666a6fea2015-12-19 04:16:3316351 data1.set_connect_data(connect_data1);
[email protected]2d88e7d2012-07-19 17:55:1716352
16353 // SPDY GET for HTTPS URL (direct)
Ryan Hamilton0239aac2018-05-19 00:03:1316354 spdy::SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4916355 spdy_util_secure.ConstructSpdyGet(url2.c_str(), 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1716356
16357 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4116358 CreateMockWrite(req2, 0),
[email protected]2d88e7d2012-07-19 17:55:1716359 };
16360
Ryan Hamilton0239aac2018-05-19 00:03:1316361 spdy::SpdySerializedFrame resp2(
16362 spdy_util_secure.ConstructSpdyGetReply(NULL, 0, 1));
16363 spdy::SpdySerializedFrame body2(
16364 spdy_util_secure.ConstructSpdyDataFrame(1, true));
bncdf80d44fd2016-07-15 20:27:4116365 MockRead reads2[] = {CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
mmenke666a6fea2015-12-19 04:16:3316366 MockRead(ASYNC, OK, 3)};
[email protected]2d88e7d2012-07-19 17:55:1716367
Ryan Sleevib8d7ea02018-05-07 20:01:0116368 SequencedSocketData data2(reads2, writes2);
[email protected]2d88e7d2012-07-19 17:55:1716369 MockConnect connect_data2(ASYNC, OK);
mmenke666a6fea2015-12-19 04:16:3316370 data2.set_connect_data(connect_data2);
[email protected]2d88e7d2012-07-19 17:55:1716371
16372 // Set up a proxy config that sends HTTP requests to a proxy, and
16373 // all others direct.
16374 ProxyConfig proxy_config;
16375 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
Ramin Halavatica8d5252018-03-12 05:33:4916376 session_deps_.proxy_resolution_service =
16377 std::make_unique<ProxyResolutionService>(
16378 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
16379 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
16380 nullptr, nullptr);
[email protected]2d88e7d2012-07-19 17:55:1716381
bncce36dca22015-04-21 22:11:2316382 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3616383 ssl1.next_proto = kProtoHTTP2;
[email protected]2d88e7d2012-07-19 17:55:1716384 // Load a valid cert. Note, that this does not need to
16385 // be valid for proxy because the MockSSLClientSocket does
16386 // not actually verify it. But SpdySession will use this
16387 // to see if it is valid for the new origin
Ryan Sleevi4f832092017-11-21 23:25:4916388 ssl1.ssl_info.cert =
16389 ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
16390 ASSERT_TRUE(ssl1.ssl_info.cert);
mmenke666a6fea2015-12-19 04:16:3316391 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
16392 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d88e7d2012-07-19 17:55:1716393
16394 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3616395 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3316396 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
16397 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d88e7d2012-07-19 17:55:1716398
Jeremy Roman0579ed62017-08-29 15:56:1916399 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
bncce36dca22015-04-21 22:11:2316400 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0716401 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1716402
danakj1fd259a02016-04-16 03:17:0916403 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]2d88e7d2012-07-19 17:55:1716404
16405 // Start the first transaction to set up the SpdySession
16406 HttpRequestInfo request1;
16407 request1.method = "GET";
16408 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1716409 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016410 request1.traffic_annotation =
16411 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016412 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1716413 TestCompletionCallback callback1;
16414 ASSERT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016415 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
mmenke666a6fea2015-12-19 04:16:3316416 // This pause is a hack to avoid running into https://crbug.com/497228.
16417 data1.RunUntilPaused();
16418 base::RunLoop().RunUntilIdle();
16419 data1.Resume();
[email protected]2d88e7d2012-07-19 17:55:1716420
robpercival214763f2016-07-01 23:27:0116421 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1716422 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
16423
16424 // Now, start the HTTP request
16425 HttpRequestInfo request2;
16426 request2.method = "GET";
16427 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1716428 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016429 request2.traffic_annotation =
16430 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016431 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1716432 TestCompletionCallback callback2;
16433 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016434 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5516435 base::RunLoop().RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1716436
16437 ASSERT_TRUE(callback2.have_result());
robpercival214763f2016-07-01 23:27:0116438 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1716439 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
16440}
16441
[email protected]85f97342013-04-17 06:12:2416442// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
16443// error) in SPDY session, removes the socket from pool and closes the SPDY
16444// session. Verify that new url's from the same HttpNetworkSession (and a new
16445// SpdySession) do work. http://crbug.com/224701
bncd16676a2016-07-20 16:23:0116446TEST_F(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2316447 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2416448
16449 MockRead reads1[] = {
16450 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
16451 };
16452
Ryan Sleevib8d7ea02018-05-07 20:01:0116453 SequencedSocketData data1(reads1, base::span<MockWrite>());
[email protected]85f97342013-04-17 06:12:2416454
Ryan Hamilton0239aac2018-05-19 00:03:1316455 spdy::SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4916456 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2416457 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4116458 CreateMockWrite(req2, 0),
[email protected]85f97342013-04-17 06:12:2416459 };
16460
Ryan Hamilton0239aac2018-05-19 00:03:1316461 spdy::SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
16462 spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]85f97342013-04-17 06:12:2416463 MockRead reads2[] = {
bncdf80d44fd2016-07-15 20:27:4116464 CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
16465 MockRead(ASYNC, OK, 3) // EOF
[email protected]85f97342013-04-17 06:12:2416466 };
16467
Ryan Sleevib8d7ea02018-05-07 20:01:0116468 SequencedSocketData data2(reads2, writes2);
[email protected]85f97342013-04-17 06:12:2416469
[email protected]85f97342013-04-17 06:12:2416470 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616471 ssl1.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5016472 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
16473 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]85f97342013-04-17 06:12:2416474
16475 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616476 ssl2.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5016477 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
16478 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]85f97342013-04-17 06:12:2416479
danakj1fd259a02016-04-16 03:17:0916480 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:5016481 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]85f97342013-04-17 06:12:2416482
16483 // Start the first transaction to set up the SpdySession and verify that
16484 // connection was closed.
16485 HttpRequestInfo request1;
16486 request1.method = "GET";
16487 request1.url = GURL(https_url);
16488 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016489 request1.traffic_annotation =
16490 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016491 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2416492 TestCompletionCallback callback1;
16493 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016494 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0116495 EXPECT_THAT(callback1.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]85f97342013-04-17 06:12:2416496
16497 // Now, start the second request and make sure it succeeds.
16498 HttpRequestInfo request2;
16499 request2.method = "GET";
16500 request2.url = GURL(https_url);
16501 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016502 request2.traffic_annotation =
16503 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016504 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2416505 TestCompletionCallback callback2;
16506 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016507 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
[email protected]85f97342013-04-17 06:12:2416508
robpercival214763f2016-07-01 23:27:0116509 ASSERT_THAT(callback2.WaitForResult(), IsOk());
[email protected]85f97342013-04-17 06:12:2416510 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
16511}
16512
bncd16676a2016-07-20 16:23:0116513TEST_F(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]483fa202013-05-14 01:07:0316514 ClientSocketPoolManager::set_max_sockets_per_group(
16515 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16516 ClientSocketPoolManager::set_max_sockets_per_pool(
16517 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16518
16519 // Use two different hosts with different IPs so they don't get pooled.
16520 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
16521 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
danakj1fd259a02016-04-16 03:17:0916522 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]483fa202013-05-14 01:07:0316523
16524 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616525 ssl1.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0316526 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616527 ssl2.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0316528 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
16529 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
16530
Ryan Hamilton0239aac2018-05-19 00:03:1316531 spdy::SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4916532 spdy_util_.ConstructSpdyGet("https://www.a.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0316533 MockWrite spdy1_writes[] = {
bncdf80d44fd2016-07-15 20:27:4116534 CreateMockWrite(host1_req, 0),
[email protected]483fa202013-05-14 01:07:0316535 };
Ryan Hamilton0239aac2018-05-19 00:03:1316536 spdy::SpdySerializedFrame host1_resp(
16537 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
16538 spdy::SpdySerializedFrame host1_resp_body(
bncdf80d44fd2016-07-15 20:27:4116539 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0316540 MockRead spdy1_reads[] = {
bncdf80d44fd2016-07-15 20:27:4116541 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
mmenkee24011922015-12-17 22:12:5916542 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0316543 };
16544
rdsmithebb50aa2015-11-12 03:44:3816545 // Use a separate test instance for the separate SpdySession that will be
16546 // created.
bncd16676a2016-07-20 16:23:0116547 SpdyTestUtil spdy_util_2;
Ryan Sleevib8d7ea02018-05-07 20:01:0116548 SequencedSocketData spdy1_data(spdy1_reads, spdy1_writes);
Bence Béky53a5aef2018-03-29 21:54:1216549 session_deps_.socket_factory->AddSocketDataProvider(&spdy1_data);
[email protected]483fa202013-05-14 01:07:0316550
Ryan Hamilton0239aac2018-05-19 00:03:1316551 spdy::SpdySerializedFrame host2_req(
bnc38dcd392016-02-09 23:19:4916552 spdy_util_2.ConstructSpdyGet("https://www.b.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0316553 MockWrite spdy2_writes[] = {
bncdf80d44fd2016-07-15 20:27:4116554 CreateMockWrite(host2_req, 0),
[email protected]483fa202013-05-14 01:07:0316555 };
Ryan Hamilton0239aac2018-05-19 00:03:1316556 spdy::SpdySerializedFrame host2_resp(
16557 spdy_util_2.ConstructSpdyGetReply(NULL, 0, 1));
16558 spdy::SpdySerializedFrame host2_resp_body(
bncdf80d44fd2016-07-15 20:27:4116559 spdy_util_2.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0316560 MockRead spdy2_reads[] = {
bncdf80d44fd2016-07-15 20:27:4116561 CreateMockRead(host2_resp, 1), CreateMockRead(host2_resp_body, 2),
mmenkee24011922015-12-17 22:12:5916562 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0316563 };
16564
Ryan Sleevib8d7ea02018-05-07 20:01:0116565 SequencedSocketData spdy2_data(spdy2_reads, spdy2_writes);
Bence Béky53a5aef2018-03-29 21:54:1216566 session_deps_.socket_factory->AddSocketDataProvider(&spdy2_data);
[email protected]483fa202013-05-14 01:07:0316567
16568 MockWrite http_write[] = {
16569 MockWrite("GET / HTTP/1.1\r\n"
16570 "Host: www.a.com\r\n"
16571 "Connection: keep-alive\r\n\r\n"),
16572 };
16573
16574 MockRead http_read[] = {
16575 MockRead("HTTP/1.1 200 OK\r\n"),
16576 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
16577 MockRead("Content-Length: 6\r\n\r\n"),
16578 MockRead("hello!"),
16579 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116580 StaticSocketDataProvider http_data(http_read, http_write);
[email protected]483fa202013-05-14 01:07:0316581 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16582
16583 HostPortPair host_port_pair_a("www.a.com", 443);
Matt Menke2436b2f2018-12-11 18:07:1116584 SpdySessionKey spdy_session_key_a(
16585 host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
16586 SpdySessionKey::IsProxySession::kFalse, SocketTag());
[email protected]483fa202013-05-14 01:07:0316587 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616588 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0316589
16590 TestCompletionCallback callback;
16591 HttpRequestInfo request1;
16592 request1.method = "GET";
16593 request1.url = GURL("https://www.a.com/");
16594 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016595 request1.traffic_annotation =
16596 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5816597 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1916598 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0316599
tfarina42834112016-09-22 13:38:2016600 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116601 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16602 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0316603
16604 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5216605 ASSERT_TRUE(response);
16606 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0216607 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0316608 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5216609 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]483fa202013-05-14 01:07:0316610
16611 std::string response_data;
robpercival214763f2016-07-01 23:27:0116612 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0316613 EXPECT_EQ("hello!", response_data);
16614 trans.reset();
16615 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2616616 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0316617
16618 HostPortPair host_port_pair_b("www.b.com", 443);
Matt Menke2436b2f2018-12-11 18:07:1116619 SpdySessionKey spdy_session_key_b(
16620 host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
16621 SpdySessionKey::IsProxySession::kFalse, SocketTag());
[email protected]483fa202013-05-14 01:07:0316622 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616623 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0316624 HttpRequestInfo request2;
16625 request2.method = "GET";
16626 request2.url = GURL("https://www.b.com/");
16627 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016628 request2.traffic_annotation =
16629 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5816630 trans =
Jeremy Roman0579ed62017-08-29 15:56:1916631 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0316632
tfarina42834112016-09-22 13:38:2016633 rv = trans->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116634 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16635 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0316636
16637 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5216638 ASSERT_TRUE(response);
16639 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0216640 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0316641 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5216642 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0116643 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0316644 EXPECT_EQ("hello!", response_data);
16645 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616646 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0316647 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2616648 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0316649
16650 HostPortPair host_port_pair_a1("www.a.com", 80);
Matt Menke2436b2f2018-12-11 18:07:1116651 SpdySessionKey spdy_session_key_a1(
16652 host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
16653 SpdySessionKey::IsProxySession::kFalse, SocketTag());
[email protected]483fa202013-05-14 01:07:0316654 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616655 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0316656 HttpRequestInfo request3;
16657 request3.method = "GET";
16658 request3.url = GURL("http://www.a.com/");
16659 request3.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016660 request3.traffic_annotation =
16661 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5816662 trans =
Jeremy Roman0579ed62017-08-29 15:56:1916663 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0316664
tfarina42834112016-09-22 13:38:2016665 rv = trans->Start(&request3, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116666 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16667 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0316668
16669 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5216670 ASSERT_TRUE(response);
16671 ASSERT_TRUE(response->headers);
[email protected]483fa202013-05-14 01:07:0316672 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
16673 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5216674 EXPECT_FALSE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0116675 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0316676 EXPECT_EQ("hello!", response_data);
16677 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616678 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0316679 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616680 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0316681}
16682
bncd16676a2016-07-20 16:23:0116683TEST_F(HttpNetworkTransactionTest, HttpSyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0416684 HttpRequestInfo request;
16685 request.method = "GET";
bncce36dca22015-04-21 22:11:2316686 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016687 request.traffic_annotation =
16688 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416689
danakj1fd259a02016-04-16 03:17:0916690 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616691 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416692
ttuttled9dbc652015-09-29 20:00:5916693 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0416694 StaticSocketDataProvider data;
16695 data.set_connect_data(mock_connect);
16696 session_deps_.socket_factory->AddSocketDataProvider(&data);
16697
16698 TestCompletionCallback callback;
16699
tfarina42834112016-09-22 13:38:2016700 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116701 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416702
16703 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116704 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0416705
[email protected]79e1fd62013-06-20 06:50:0416706 // We don't care whether this succeeds or fails, but it shouldn't crash.
16707 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616708 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4716709
16710 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1616711 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4716712 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0116713 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5916714
16715 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1616716 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5916717 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0416718}
16719
bncd16676a2016-07-20 16:23:0116720TEST_F(HttpNetworkTransactionTest, HttpAsyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0416721 HttpRequestInfo request;
16722 request.method = "GET";
bncce36dca22015-04-21 22:11:2316723 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016724 request.traffic_annotation =
16725 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416726
danakj1fd259a02016-04-16 03:17:0916727 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616728 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416729
ttuttled9dbc652015-09-29 20:00:5916730 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0416731 StaticSocketDataProvider data;
16732 data.set_connect_data(mock_connect);
16733 session_deps_.socket_factory->AddSocketDataProvider(&data);
16734
16735 TestCompletionCallback callback;
16736
tfarina42834112016-09-22 13:38:2016737 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116738 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416739
16740 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116741 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0416742
[email protected]79e1fd62013-06-20 06:50:0416743 // We don't care whether this succeeds or fails, but it shouldn't crash.
16744 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616745 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4716746
16747 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1616748 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4716749 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0116750 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5916751
16752 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1616753 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5916754 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0416755}
16756
bncd16676a2016-07-20 16:23:0116757TEST_F(HttpNetworkTransactionTest, HttpSyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0416758 HttpRequestInfo request;
16759 request.method = "GET";
bncce36dca22015-04-21 22:11:2316760 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016761 request.traffic_annotation =
16762 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416763
danakj1fd259a02016-04-16 03:17:0916764 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616765 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416766
16767 MockWrite data_writes[] = {
16768 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16769 };
16770 MockRead data_reads[] = {
16771 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
16772 };
16773
Ryan Sleevib8d7ea02018-05-07 20:01:0116774 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0416775 session_deps_.socket_factory->AddSocketDataProvider(&data);
16776
16777 TestCompletionCallback callback;
16778
tfarina42834112016-09-22 13:38:2016779 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116780 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416781
16782 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116783 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416784
[email protected]79e1fd62013-06-20 06:50:0416785 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616786 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416787 EXPECT_TRUE(request_headers.HasHeader("Host"));
16788}
16789
bncd16676a2016-07-20 16:23:0116790TEST_F(HttpNetworkTransactionTest, HttpAsyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0416791 HttpRequestInfo request;
16792 request.method = "GET";
bncce36dca22015-04-21 22:11:2316793 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016794 request.traffic_annotation =
16795 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416796
danakj1fd259a02016-04-16 03:17:0916797 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616798 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416799
16800 MockWrite data_writes[] = {
16801 MockWrite(ASYNC, ERR_CONNECTION_RESET),
16802 };
16803 MockRead data_reads[] = {
16804 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
16805 };
16806
Ryan Sleevib8d7ea02018-05-07 20:01:0116807 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0416808 session_deps_.socket_factory->AddSocketDataProvider(&data);
16809
16810 TestCompletionCallback callback;
16811
tfarina42834112016-09-22 13:38:2016812 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116813 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416814
16815 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116816 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416817
[email protected]79e1fd62013-06-20 06:50:0416818 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616819 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416820 EXPECT_TRUE(request_headers.HasHeader("Host"));
16821}
16822
bncd16676a2016-07-20 16:23:0116823TEST_F(HttpNetworkTransactionTest, HttpSyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0416824 HttpRequestInfo request;
16825 request.method = "GET";
bncce36dca22015-04-21 22:11:2316826 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016827 request.traffic_annotation =
16828 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416829
danakj1fd259a02016-04-16 03:17:0916830 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616831 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416832
16833 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2316834 MockWrite(
16835 "GET / HTTP/1.1\r\n"
16836 "Host: www.example.org\r\n"
16837 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0416838 };
16839 MockRead data_reads[] = {
16840 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
16841 };
16842
Ryan Sleevib8d7ea02018-05-07 20:01:0116843 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0416844 session_deps_.socket_factory->AddSocketDataProvider(&data);
16845
16846 TestCompletionCallback callback;
16847
tfarina42834112016-09-22 13:38:2016848 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116849 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416850
16851 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116852 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416853
[email protected]79e1fd62013-06-20 06:50:0416854 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616855 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416856 EXPECT_TRUE(request_headers.HasHeader("Host"));
16857}
16858
bncd16676a2016-07-20 16:23:0116859TEST_F(HttpNetworkTransactionTest, HttpAsyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0416860 HttpRequestInfo request;
16861 request.method = "GET";
bncce36dca22015-04-21 22:11:2316862 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016863 request.traffic_annotation =
16864 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416865
danakj1fd259a02016-04-16 03:17:0916866 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616867 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416868
16869 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2316870 MockWrite(
16871 "GET / HTTP/1.1\r\n"
16872 "Host: www.example.org\r\n"
16873 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0416874 };
16875 MockRead data_reads[] = {
16876 MockRead(ASYNC, ERR_CONNECTION_RESET),
16877 };
16878
Ryan Sleevib8d7ea02018-05-07 20:01:0116879 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0416880 session_deps_.socket_factory->AddSocketDataProvider(&data);
16881
16882 TestCompletionCallback callback;
16883
tfarina42834112016-09-22 13:38:2016884 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116885 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416886
16887 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116888 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416889
[email protected]79e1fd62013-06-20 06:50:0416890 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616891 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416892 EXPECT_TRUE(request_headers.HasHeader("Host"));
16893}
16894
bncd16676a2016-07-20 16:23:0116895TEST_F(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
[email protected]79e1fd62013-06-20 06:50:0416896 HttpRequestInfo request;
16897 request.method = "GET";
bncce36dca22015-04-21 22:11:2316898 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0416899 request.extra_headers.SetHeader("X-Foo", "bar");
Ramin Halavatib5e433e2018-02-07 07:41:1016900 request.traffic_annotation =
16901 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416902
danakj1fd259a02016-04-16 03:17:0916903 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616904 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416905
16906 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2316907 MockWrite(
16908 "GET / HTTP/1.1\r\n"
16909 "Host: www.example.org\r\n"
16910 "Connection: keep-alive\r\n"
16911 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0416912 };
16913 MockRead data_reads[] = {
16914 MockRead("HTTP/1.1 200 OK\r\n"
16915 "Content-Length: 5\r\n\r\n"
16916 "hello"),
16917 MockRead(ASYNC, ERR_UNEXPECTED),
16918 };
16919
Ryan Sleevib8d7ea02018-05-07 20:01:0116920 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0416921 session_deps_.socket_factory->AddSocketDataProvider(&data);
16922
16923 TestCompletionCallback callback;
16924
tfarina42834112016-09-22 13:38:2016925 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116926 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416927
16928 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116929 EXPECT_THAT(rv, IsOk());
[email protected]79e1fd62013-06-20 06:50:0416930
16931 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616932 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416933 std::string foo;
16934 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
16935 EXPECT_EQ("bar", foo);
16936}
16937
[email protected]043b68c82013-08-22 23:41:5216938// Tests that when a used socket is returned to the SSL socket pool, it's closed
16939// if the transport socket pool is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0116940TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
[email protected]043b68c82013-08-22 23:41:5216941 ClientSocketPoolManager::set_max_sockets_per_group(
16942 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16943 ClientSocketPoolManager::set_max_sockets_per_pool(
16944 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16945
16946 // Set up SSL request.
16947
16948 HttpRequestInfo ssl_request;
16949 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2316950 ssl_request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016951 ssl_request.traffic_annotation =
16952 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5216953
16954 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2316955 MockWrite(
16956 "GET / HTTP/1.1\r\n"
16957 "Host: www.example.org\r\n"
16958 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5216959 };
16960 MockRead ssl_reads[] = {
16961 MockRead("HTTP/1.1 200 OK\r\n"),
16962 MockRead("Content-Length: 11\r\n\r\n"),
16963 MockRead("hello world"),
16964 MockRead(SYNCHRONOUS, OK),
16965 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116966 StaticSocketDataProvider ssl_data(ssl_reads, ssl_writes);
[email protected]043b68c82013-08-22 23:41:5216967 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
16968
16969 SSLSocketDataProvider ssl(ASYNC, OK);
16970 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16971
16972 // Set up HTTP request.
16973
16974 HttpRequestInfo http_request;
16975 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2316976 http_request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016977 http_request.traffic_annotation =
16978 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5216979
16980 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2316981 MockWrite(
16982 "GET / HTTP/1.1\r\n"
16983 "Host: www.example.org\r\n"
16984 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5216985 };
16986 MockRead http_reads[] = {
16987 MockRead("HTTP/1.1 200 OK\r\n"),
16988 MockRead("Content-Length: 7\r\n\r\n"),
16989 MockRead("falafel"),
16990 MockRead(SYNCHRONOUS, OK),
16991 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116992 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]043b68c82013-08-22 23:41:5216993 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16994
danakj1fd259a02016-04-16 03:17:0916995 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5216996
16997 // Start the SSL request.
16998 TestCompletionCallback ssl_callback;
bnc691fda62016-08-12 00:43:1616999 HttpNetworkTransaction ssl_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2017000 ASSERT_EQ(ERR_IO_PENDING,
17001 ssl_trans.Start(&ssl_request, ssl_callback.callback(),
17002 NetLogWithSource()));
[email protected]043b68c82013-08-22 23:41:5217003
17004 // Start the HTTP request. Pool should stall.
17005 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1617006 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2017007 ASSERT_EQ(ERR_IO_PENDING,
17008 http_trans.Start(&http_request, http_callback.callback(),
17009 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4117010 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5217011
17012 // Wait for response from SSL request.
robpercival214763f2016-07-01 23:27:0117013 ASSERT_THAT(ssl_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5217014 std::string response_data;
bnc691fda62016-08-12 00:43:1617015 ASSERT_THAT(ReadTransaction(&ssl_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5217016 EXPECT_EQ("hello world", response_data);
17017
17018 // The SSL socket should automatically be closed, so the HTTP request can
17019 // start.
dcheng48459ac22014-08-26 00:46:4117020 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
17021 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5217022
17023 // The HTTP request can now complete.
robpercival214763f2016-07-01 23:27:0117024 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
bnc691fda62016-08-12 00:43:1617025 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5217026 EXPECT_EQ("falafel", response_data);
17027
dcheng48459ac22014-08-26 00:46:4117028 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5217029}
17030
17031// Tests that when a SSL connection is established but there's no corresponding
17032// request that needs it, the new socket is closed if the transport socket pool
17033// is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0117034TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
[email protected]043b68c82013-08-22 23:41:5217035 ClientSocketPoolManager::set_max_sockets_per_group(
17036 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
17037 ClientSocketPoolManager::set_max_sockets_per_pool(
17038 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
17039
17040 // Set up an ssl request.
17041
17042 HttpRequestInfo ssl_request;
17043 ssl_request.method = "GET";
17044 ssl_request.url = GURL("https://www.foopy.com/");
Ramin Halavatib5e433e2018-02-07 07:41:1017045 ssl_request.traffic_annotation =
17046 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5217047
17048 // No data will be sent on the SSL socket.
17049 StaticSocketDataProvider ssl_data;
17050 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
17051
17052 SSLSocketDataProvider ssl(ASYNC, OK);
17053 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
17054
17055 // Set up HTTP request.
17056
17057 HttpRequestInfo http_request;
17058 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2317059 http_request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017060 http_request.traffic_annotation =
17061 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5217062
17063 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2317064 MockWrite(
17065 "GET / HTTP/1.1\r\n"
17066 "Host: www.example.org\r\n"
17067 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5217068 };
17069 MockRead http_reads[] = {
17070 MockRead("HTTP/1.1 200 OK\r\n"),
17071 MockRead("Content-Length: 7\r\n\r\n"),
17072 MockRead("falafel"),
17073 MockRead(SYNCHRONOUS, OK),
17074 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117075 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]043b68c82013-08-22 23:41:5217076 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
17077
danakj1fd259a02016-04-16 03:17:0917078 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5217079
17080 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
17081 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2917082 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
nharper8cdb0fb2016-04-22 21:34:5917083 http_stream_factory->PreconnectStreams(1, ssl_request);
dcheng48459ac22014-08-26 00:46:4117084 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5217085
17086 // Start the HTTP request. Pool should stall.
17087 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1617088 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2017089 ASSERT_EQ(ERR_IO_PENDING,
17090 http_trans.Start(&http_request, http_callback.callback(),
17091 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4117092 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5217093
17094 // The SSL connection will automatically be closed once the connection is
17095 // established, to let the HTTP request start.
robpercival214763f2016-07-01 23:27:0117096 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5217097 std::string response_data;
bnc691fda62016-08-12 00:43:1617098 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5217099 EXPECT_EQ("falafel", response_data);
17100
dcheng48459ac22014-08-26 00:46:4117101 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5217102}
17103
bncd16676a2016-07-20 16:23:0117104TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0917105 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217106 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917107 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217108 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417109
17110 HttpRequestInfo request;
17111 request.method = "POST";
17112 request.url = GURL("http://www.foo.com/");
17113 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017114 request.traffic_annotation =
17115 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417116
danakj1fd259a02016-04-16 03:17:0917117 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617118 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417119 // Send headers successfully, but get an error while sending the body.
17120 MockWrite data_writes[] = {
17121 MockWrite("POST / HTTP/1.1\r\n"
17122 "Host: www.foo.com\r\n"
17123 "Connection: keep-alive\r\n"
17124 "Content-Length: 3\r\n\r\n"),
17125 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17126 };
17127
17128 MockRead data_reads[] = {
17129 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
17130 MockRead("hello world"),
17131 MockRead(SYNCHRONOUS, OK),
17132 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117133 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417134 session_deps_.socket_factory->AddSocketDataProvider(&data);
17135
17136 TestCompletionCallback callback;
17137
tfarina42834112016-09-22 13:38:2017138 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117139 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417140
17141 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117142 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417143
bnc691fda62016-08-12 00:43:1617144 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5217145 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5417146
wezca1070932016-05-26 20:30:5217147 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5417148 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
17149
17150 std::string response_data;
bnc691fda62016-08-12 00:43:1617151 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0117152 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417153 EXPECT_EQ("hello world", response_data);
17154}
17155
17156// This test makes sure the retry logic doesn't trigger when reading an error
17157// response from a server that rejected a POST with a CONNECTION_RESET.
bncd16676a2016-07-20 16:23:0117158TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5417159 PostReadsErrorResponseAfterResetOnReusedSocket) {
danakj1fd259a02016-04-16 03:17:0917160 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5417161 MockWrite data_writes[] = {
17162 MockWrite("GET / HTTP/1.1\r\n"
17163 "Host: www.foo.com\r\n"
17164 "Connection: keep-alive\r\n\r\n"),
17165 MockWrite("POST / HTTP/1.1\r\n"
17166 "Host: www.foo.com\r\n"
17167 "Connection: keep-alive\r\n"
17168 "Content-Length: 3\r\n\r\n"),
17169 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17170 };
17171
17172 MockRead data_reads[] = {
17173 MockRead("HTTP/1.1 200 Peachy\r\n"
17174 "Content-Length: 14\r\n\r\n"),
17175 MockRead("first response"),
17176 MockRead("HTTP/1.1 400 Not OK\r\n"
17177 "Content-Length: 15\r\n\r\n"),
17178 MockRead("second response"),
17179 MockRead(SYNCHRONOUS, OK),
17180 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117181 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417182 session_deps_.socket_factory->AddSocketDataProvider(&data);
17183
17184 TestCompletionCallback callback;
17185 HttpRequestInfo request1;
17186 request1.method = "GET";
17187 request1.url = GURL("http://www.foo.com/");
17188 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1017189 request1.traffic_annotation =
17190 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417191
bnc87dcefc2017-05-25 12:47:5817192 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:1917193 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2017194 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117195 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417196
17197 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117198 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417199
17200 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:5217201 ASSERT_TRUE(response1);
[email protected]02d74a02014-04-23 18:10:5417202
wezca1070932016-05-26 20:30:5217203 EXPECT_TRUE(response1->headers);
[email protected]02d74a02014-04-23 18:10:5417204 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
17205
17206 std::string response_data1;
17207 rv = ReadTransaction(trans1.get(), &response_data1);
robpercival214763f2016-07-01 23:27:0117208 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417209 EXPECT_EQ("first response", response_data1);
17210 // Delete the transaction to release the socket back into the socket pool.
17211 trans1.reset();
17212
danakj1fd259a02016-04-16 03:17:0917213 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217214 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917215 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217216 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417217
17218 HttpRequestInfo request2;
17219 request2.method = "POST";
17220 request2.url = GURL("http://www.foo.com/");
17221 request2.upload_data_stream = &upload_data_stream;
17222 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1017223 request2.traffic_annotation =
17224 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417225
bnc691fda62016-08-12 00:43:1617226 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2017227 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117228 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417229
17230 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117231 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417232
bnc691fda62016-08-12 00:43:1617233 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5217234 ASSERT_TRUE(response2);
[email protected]02d74a02014-04-23 18:10:5417235
wezca1070932016-05-26 20:30:5217236 EXPECT_TRUE(response2->headers);
[email protected]02d74a02014-04-23 18:10:5417237 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
17238
17239 std::string response_data2;
bnc691fda62016-08-12 00:43:1617240 rv = ReadTransaction(&trans2, &response_data2);
robpercival214763f2016-07-01 23:27:0117241 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417242 EXPECT_EQ("second response", response_data2);
17243}
17244
bncd16676a2016-07-20 16:23:0117245TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5417246 PostReadsErrorResponseAfterResetPartialBodySent) {
danakj1fd259a02016-04-16 03:17:0917247 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217248 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917249 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217250 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417251
17252 HttpRequestInfo request;
17253 request.method = "POST";
17254 request.url = GURL("http://www.foo.com/");
17255 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017256 request.traffic_annotation =
17257 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417258
danakj1fd259a02016-04-16 03:17:0917259 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617260 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417261 // Send headers successfully, but get an error while sending the body.
17262 MockWrite data_writes[] = {
17263 MockWrite("POST / HTTP/1.1\r\n"
17264 "Host: www.foo.com\r\n"
17265 "Connection: keep-alive\r\n"
17266 "Content-Length: 3\r\n\r\n"
17267 "fo"),
17268 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17269 };
17270
17271 MockRead data_reads[] = {
17272 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
17273 MockRead("hello world"),
17274 MockRead(SYNCHRONOUS, OK),
17275 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117276 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417277 session_deps_.socket_factory->AddSocketDataProvider(&data);
17278
17279 TestCompletionCallback callback;
17280
tfarina42834112016-09-22 13:38:2017281 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117282 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417283
17284 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117285 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417286
bnc691fda62016-08-12 00:43:1617287 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5217288 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5417289
wezca1070932016-05-26 20:30:5217290 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5417291 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
17292
17293 std::string response_data;
bnc691fda62016-08-12 00:43:1617294 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0117295 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417296 EXPECT_EQ("hello world", response_data);
17297}
17298
17299// This tests the more common case than the previous test, where headers and
17300// body are not merged into a single request.
bncd16676a2016-07-20 16:23:0117301TEST_F(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
mmenkecbc2b712014-10-09 20:29:0717302 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5417303
17304 HttpRequestInfo request;
17305 request.method = "POST";
17306 request.url = GURL("http://www.foo.com/");
17307 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017308 request.traffic_annotation =
17309 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417310
danakj1fd259a02016-04-16 03:17:0917311 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617312 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417313 // Send headers successfully, but get an error while sending the body.
17314 MockWrite data_writes[] = {
17315 MockWrite("POST / HTTP/1.1\r\n"
17316 "Host: www.foo.com\r\n"
17317 "Connection: keep-alive\r\n"
17318 "Transfer-Encoding: chunked\r\n\r\n"),
17319 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17320 };
17321
17322 MockRead data_reads[] = {
17323 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
17324 MockRead("hello world"),
17325 MockRead(SYNCHRONOUS, OK),
17326 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117327 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417328 session_deps_.socket_factory->AddSocketDataProvider(&data);
17329
17330 TestCompletionCallback callback;
17331
tfarina42834112016-09-22 13:38:2017332 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117333 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417334 // Make sure the headers are sent before adding a chunk. This ensures that
17335 // they can't be merged with the body in a single send. Not currently
17336 // necessary since a chunked body is never merged with headers, but this makes
17337 // the test more future proof.
17338 base::RunLoop().RunUntilIdle();
17339
mmenkecbc2b712014-10-09 20:29:0717340 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5417341
17342 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117343 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417344
bnc691fda62016-08-12 00:43:1617345 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5217346 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5417347
wezca1070932016-05-26 20:30:5217348 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5417349 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
17350
17351 std::string response_data;
bnc691fda62016-08-12 00:43:1617352 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0117353 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417354 EXPECT_EQ("hello world", response_data);
17355}
17356
bncd16676a2016-07-20 16:23:0117357TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0917358 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217359 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917360 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217361 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417362
17363 HttpRequestInfo request;
17364 request.method = "POST";
17365 request.url = GURL("http://www.foo.com/");
17366 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017367 request.traffic_annotation =
17368 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417369
danakj1fd259a02016-04-16 03:17:0917370 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617371 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417372
17373 MockWrite data_writes[] = {
17374 MockWrite("POST / HTTP/1.1\r\n"
17375 "Host: www.foo.com\r\n"
17376 "Connection: keep-alive\r\n"
17377 "Content-Length: 3\r\n\r\n"),
17378 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17379 };
17380
17381 MockRead data_reads[] = {
17382 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
17383 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
17384 MockRead("hello world"),
17385 MockRead(SYNCHRONOUS, OK),
17386 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117387 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417388 session_deps_.socket_factory->AddSocketDataProvider(&data);
17389
17390 TestCompletionCallback callback;
17391
tfarina42834112016-09-22 13:38:2017392 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117393 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417394
17395 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117396 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417397
bnc691fda62016-08-12 00:43:1617398 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5217399 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5417400
wezca1070932016-05-26 20:30:5217401 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5417402 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
17403
17404 std::string response_data;
bnc691fda62016-08-12 00:43:1617405 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0117406 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417407 EXPECT_EQ("hello world", response_data);
17408}
17409
bncd16676a2016-07-20 16:23:0117410TEST_F(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0917411 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217412 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917413 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217414 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417415
17416 HttpRequestInfo request;
17417 request.method = "POST";
17418 request.url = GURL("http://www.foo.com/");
17419 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017420 request.traffic_annotation =
17421 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417422
danakj1fd259a02016-04-16 03:17:0917423 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617424 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417425 // Send headers successfully, but get an error while sending the body.
17426 MockWrite data_writes[] = {
17427 MockWrite("POST / HTTP/1.1\r\n"
17428 "Host: www.foo.com\r\n"
17429 "Connection: keep-alive\r\n"
17430 "Content-Length: 3\r\n\r\n"),
17431 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17432 };
17433
17434 MockRead data_reads[] = {
17435 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
17436 MockRead("hello world"),
17437 MockRead(SYNCHRONOUS, OK),
17438 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117439 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417440 session_deps_.socket_factory->AddSocketDataProvider(&data);
17441
17442 TestCompletionCallback callback;
17443
tfarina42834112016-09-22 13:38:2017444 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117445 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417446
17447 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117448 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417449}
17450
bncd16676a2016-07-20 16:23:0117451TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5417452 PostIgnoresNonErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0917453 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217454 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917455 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217456 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417457
17458 HttpRequestInfo request;
17459 request.method = "POST";
17460 request.url = GURL("http://www.foo.com/");
17461 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017462 request.traffic_annotation =
17463 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417464
danakj1fd259a02016-04-16 03:17:0917465 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617466 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417467 // Send headers successfully, but get an error while sending the body.
17468 MockWrite data_writes[] = {
17469 MockWrite("POST / HTTP/1.1\r\n"
17470 "Host: www.foo.com\r\n"
17471 "Connection: keep-alive\r\n"
17472 "Content-Length: 3\r\n\r\n"),
17473 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17474 };
17475
17476 MockRead data_reads[] = {
17477 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
17478 MockRead("HTTP/1.0 302 Redirect\r\n"),
17479 MockRead("Location: http://somewhere-else.com/\r\n"),
17480 MockRead("Content-Length: 0\r\n\r\n"),
17481 MockRead(SYNCHRONOUS, OK),
17482 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117483 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417484 session_deps_.socket_factory->AddSocketDataProvider(&data);
17485
17486 TestCompletionCallback callback;
17487
tfarina42834112016-09-22 13:38:2017488 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117489 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417490
17491 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117492 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417493}
17494
bncd16676a2016-07-20 16:23:0117495TEST_F(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0917496 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217497 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917498 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217499 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417500
17501 HttpRequestInfo request;
17502 request.method = "POST";
17503 request.url = GURL("http://www.foo.com/");
17504 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017505 request.traffic_annotation =
17506 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417507
danakj1fd259a02016-04-16 03:17:0917508 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617509 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417510 // Send headers successfully, but get an error while sending the body.
17511 MockWrite data_writes[] = {
17512 MockWrite("POST / HTTP/1.1\r\n"
17513 "Host: www.foo.com\r\n"
17514 "Connection: keep-alive\r\n"
17515 "Content-Length: 3\r\n\r\n"),
17516 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17517 };
17518
17519 MockRead data_reads[] = {
17520 MockRead("HTTP 0.9 rocks!"),
17521 MockRead(SYNCHRONOUS, OK),
17522 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117523 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417524 session_deps_.socket_factory->AddSocketDataProvider(&data);
17525
17526 TestCompletionCallback callback;
17527
tfarina42834112016-09-22 13:38:2017528 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117529 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417530
17531 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117532 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417533}
17534
bncd16676a2016-07-20 16:23:0117535TEST_F(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
danakj1fd259a02016-04-16 03:17:0917536 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217537 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917538 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217539 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417540
17541 HttpRequestInfo request;
17542 request.method = "POST";
17543 request.url = GURL("http://www.foo.com/");
17544 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017545 request.traffic_annotation =
17546 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417547
danakj1fd259a02016-04-16 03:17:0917548 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617549 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417550 // Send headers successfully, but get an error while sending the body.
17551 MockWrite data_writes[] = {
17552 MockWrite("POST / HTTP/1.1\r\n"
17553 "Host: www.foo.com\r\n"
17554 "Connection: keep-alive\r\n"
17555 "Content-Length: 3\r\n\r\n"),
17556 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17557 };
17558
17559 MockRead data_reads[] = {
17560 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
17561 MockRead(SYNCHRONOUS, OK),
17562 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117563 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417564 session_deps_.socket_factory->AddSocketDataProvider(&data);
17565
17566 TestCompletionCallback callback;
17567
tfarina42834112016-09-22 13:38:2017568 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117569 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417570
17571 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117572 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417573}
17574
Bence Békydca6bd92018-01-30 13:43:0617575#if BUILDFLAG(ENABLE_WEBSOCKETS)
17576
17577namespace {
17578
17579void AddWebSocketHeaders(HttpRequestHeaders* headers) {
17580 headers->SetHeader("Connection", "Upgrade");
17581 headers->SetHeader("Upgrade", "websocket");
17582 headers->SetHeader("Origin", "http://www.example.org");
17583 headers->SetHeader("Sec-WebSocket-Version", "13");
Bence Békydca6bd92018-01-30 13:43:0617584}
17585
17586} // namespace
17587
17588TEST_F(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
Bence Béky2fcf4fa2018-04-06 20:06:0117589 for (bool secure : {true, false}) {
17590 MockWrite data_writes[] = {
17591 MockWrite("GET / HTTP/1.1\r\n"
17592 "Host: www.example.org\r\n"
17593 "Connection: Upgrade\r\n"
17594 "Upgrade: websocket\r\n"
17595 "Origin: http://www.example.org\r\n"
17596 "Sec-WebSocket-Version: 13\r\n"
17597 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
17598 "Sec-WebSocket-Extensions: permessage-deflate; "
17599 "client_max_window_bits\r\n\r\n")};
17600
17601 MockRead data_reads[] = {
17602 MockRead("HTTP/1.1 101 Switching Protocols\r\n"
17603 "Upgrade: websocket\r\n"
17604 "Connection: Upgrade\r\n"
17605 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
17606
Ryan Sleevib8d7ea02018-05-07 20:01:0117607 StaticSocketDataProvider data(data_reads, data_writes);
Bence Béky2fcf4fa2018-04-06 20:06:0117608 session_deps_.socket_factory->AddSocketDataProvider(&data);
17609 SSLSocketDataProvider ssl(ASYNC, OK);
17610 if (secure)
17611 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
Bence Békydca6bd92018-01-30 13:43:0617612
17613 HttpRequestInfo request;
17614 request.method = "GET";
Bence Béky2fcf4fa2018-04-06 20:06:0117615 request.url =
17616 GURL(secure ? "ws://www.example.org/" : "wss://www.example.org/");
17617 AddWebSocketHeaders(&request.extra_headers);
Ramin Halavatib5e433e2018-02-07 07:41:1017618 request.traffic_annotation =
17619 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Békydca6bd92018-01-30 13:43:0617620
Bence Béky2fcf4fa2018-04-06 20:06:0117621 TestWebSocketHandshakeStreamCreateHelper
17622 websocket_handshake_stream_create_helper;
Bence Béky8d1c6052018-02-07 12:48:1517623
Bence Béky2fcf4fa2018-04-06 20:06:0117624 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Bence Békydca6bd92018-01-30 13:43:0617625 HttpNetworkTransaction trans(LOW, session.get());
17626 trans.SetWebSocketHandshakeStreamCreateHelper(
Bence Béky2fcf4fa2018-04-06 20:06:0117627 &websocket_handshake_stream_create_helper);
Bence Békydca6bd92018-01-30 13:43:0617628
17629 TestCompletionCallback callback;
Bence Béky2fcf4fa2018-04-06 20:06:0117630 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17631 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Bence Békydca6bd92018-01-30 13:43:0617632
Bence Béky2fcf4fa2018-04-06 20:06:0117633 const HttpStreamRequest* stream_request = trans.stream_request_.get();
17634 ASSERT_TRUE(stream_request);
17635 EXPECT_EQ(&websocket_handshake_stream_create_helper,
17636 stream_request->websocket_handshake_stream_create_helper());
17637
17638 rv = callback.WaitForResult();
17639 EXPECT_THAT(rv, IsOk());
17640
17641 EXPECT_TRUE(data.AllReadDataConsumed());
17642 EXPECT_TRUE(data.AllWriteDataConsumed());
Bence Békydca6bd92018-01-30 13:43:0617643 }
17644}
17645
Adam Rice425cf122015-01-19 06:18:2417646// Verify that proxy headers are not sent to the destination server when
17647// establishing a tunnel for a secure WebSocket connection.
bncd16676a2016-07-20 16:23:0117648TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
Adam Rice425cf122015-01-19 06:18:2417649 HttpRequestInfo request;
17650 request.method = "GET";
bncce36dca22015-04-21 22:11:2317651 request.url = GURL("wss://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017652 request.traffic_annotation =
17653 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417654 AddWebSocketHeaders(&request.extra_headers);
17655
17656 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:5917657 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4917658 ProxyResolutionService::CreateFixedFromPacResult(
17659 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417660
danakj1fd259a02016-04-16 03:17:0917661 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2417662
17663 // Since a proxy is configured, try to establish a tunnel.
17664 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1717665 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
17666 "Host: www.example.org:443\r\n"
17667 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417668
17669 // After calling trans->RestartWithAuth(), this is the request we should
17670 // be issuing -- the final header line contains the credentials.
rsleevidb16bb02015-11-12 23:47:1717671 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
17672 "Host: www.example.org:443\r\n"
17673 "Proxy-Connection: keep-alive\r\n"
17674 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417675
rsleevidb16bb02015-11-12 23:47:1717676 MockWrite("GET / HTTP/1.1\r\n"
17677 "Host: www.example.org\r\n"
17678 "Connection: Upgrade\r\n"
17679 "Upgrade: websocket\r\n"
17680 "Origin: http://www.example.org\r\n"
17681 "Sec-WebSocket-Version: 13\r\n"
Bence Béky8d1c6052018-02-07 12:48:1517682 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
17683 "Sec-WebSocket-Extensions: permessage-deflate; "
17684 "client_max_window_bits\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417685
17686 // The proxy responds to the connect with a 407, using a persistent
17687 // connection.
17688 MockRead data_reads[] = {
17689 // No credentials.
Bence Béky8d1c6052018-02-07 12:48:1517690 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"
17691 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
17692 "Content-Length: 0\r\n"
17693 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417694
17695 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
17696
Bence Béky8d1c6052018-02-07 12:48:1517697 MockRead("HTTP/1.1 101 Switching Protocols\r\n"
17698 "Upgrade: websocket\r\n"
17699 "Connection: Upgrade\r\n"
17700 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417701
Ryan Sleevib8d7ea02018-05-07 20:01:0117702 StaticSocketDataProvider data(data_reads, data_writes);
Adam Rice425cf122015-01-19 06:18:2417703 session_deps_.socket_factory->AddSocketDataProvider(&data);
17704 SSLSocketDataProvider ssl(ASYNC, OK);
17705 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
17706
Bence Béky8d1c6052018-02-07 12:48:1517707 TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
17708
bnc87dcefc2017-05-25 12:47:5817709 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917710 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2417711 trans->SetWebSocketHandshakeStreamCreateHelper(
17712 &websocket_stream_create_helper);
17713
17714 {
17715 TestCompletionCallback callback;
17716
tfarina42834112016-09-22 13:38:2017717 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117718 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2417719
17720 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117721 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2417722 }
17723
17724 const HttpResponseInfo* response = trans->GetResponseInfo();
17725 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5217726 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2417727 EXPECT_EQ(407, response->headers->response_code());
17728
17729 {
17730 TestCompletionCallback callback;
17731
17732 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
17733 callback.callback());
robpercival214763f2016-07-01 23:27:0117734 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2417735
17736 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117737 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2417738 }
17739
17740 response = trans->GetResponseInfo();
17741 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5217742 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2417743
17744 EXPECT_EQ(101, response->headers->response_code());
17745
17746 trans.reset();
17747 session->CloseAllConnections();
17748}
17749
17750// Verify that proxy headers are not sent to the destination server when
17751// establishing a tunnel for an insecure WebSocket connection.
17752// This requires the authentication info to be injected into the auth cache
17753// due to crbug.com/395064
17754// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
bncd16676a2016-07-20 16:23:0117755TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
Adam Rice425cf122015-01-19 06:18:2417756 HttpRequestInfo request;
17757 request.method = "GET";
bncce36dca22015-04-21 22:11:2317758 request.url = GURL("ws://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017759 request.traffic_annotation =
17760 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417761 AddWebSocketHeaders(&request.extra_headers);
17762
17763 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:5917764 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4917765 ProxyResolutionService::CreateFixedFromPacResult(
17766 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417767
danakj1fd259a02016-04-16 03:17:0917768 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2417769
17770 MockWrite data_writes[] = {
17771 // Try to establish a tunnel for the WebSocket connection, with
17772 // credentials. Because WebSockets have a separate set of socket pools,
17773 // they cannot and will not use the same TCP/IP connection as the
17774 // preflight HTTP request.
Bence Béky8d1c6052018-02-07 12:48:1517775 MockWrite("CONNECT www.example.org:80 HTTP/1.1\r\n"
17776 "Host: www.example.org:80\r\n"
17777 "Proxy-Connection: keep-alive\r\n"
17778 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417779
Bence Béky8d1c6052018-02-07 12:48:1517780 MockWrite("GET / HTTP/1.1\r\n"
17781 "Host: www.example.org\r\n"
17782 "Connection: Upgrade\r\n"
17783 "Upgrade: websocket\r\n"
17784 "Origin: http://www.example.org\r\n"
17785 "Sec-WebSocket-Version: 13\r\n"
17786 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
17787 "Sec-WebSocket-Extensions: permessage-deflate; "
17788 "client_max_window_bits\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417789
17790 MockRead data_reads[] = {
17791 // HTTP CONNECT with credentials.
17792 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
17793
17794 // WebSocket connection established inside tunnel.
Bence Béky8d1c6052018-02-07 12:48:1517795 MockRead("HTTP/1.1 101 Switching Protocols\r\n"
17796 "Upgrade: websocket\r\n"
17797 "Connection: Upgrade\r\n"
17798 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417799
Ryan Sleevib8d7ea02018-05-07 20:01:0117800 StaticSocketDataProvider data(data_reads, data_writes);
Adam Rice425cf122015-01-19 06:18:2417801 session_deps_.socket_factory->AddSocketDataProvider(&data);
17802
17803 session->http_auth_cache()->Add(
17804 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
17805 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
17806
Bence Béky8d1c6052018-02-07 12:48:1517807 TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
17808
bnc87dcefc2017-05-25 12:47:5817809 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917810 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2417811 trans->SetWebSocketHandshakeStreamCreateHelper(
17812 &websocket_stream_create_helper);
17813
17814 TestCompletionCallback callback;
17815
tfarina42834112016-09-22 13:38:2017816 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117817 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2417818
17819 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117820 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2417821
17822 const HttpResponseInfo* response = trans->GetResponseInfo();
17823 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5217824 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2417825
17826 EXPECT_EQ(101, response->headers->response_code());
17827
17828 trans.reset();
17829 session->CloseAllConnections();
17830}
17831
Bence Békydca6bd92018-01-30 13:43:0617832#endif // BUILDFLAG(ENABLE_WEBSOCKETS)
17833
bncd16676a2016-07-20 16:23:0117834TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost) {
danakj1fd259a02016-04-16 03:17:0917835 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217836 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917837 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217838 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2217839
17840 HttpRequestInfo request;
17841 request.method = "POST";
17842 request.url = GURL("http://www.foo.com/");
17843 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017844 request.traffic_annotation =
17845 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2217846
danakj1fd259a02016-04-16 03:17:0917847 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617848 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2217849 MockWrite data_writes[] = {
17850 MockWrite("POST / HTTP/1.1\r\n"
17851 "Host: www.foo.com\r\n"
17852 "Connection: keep-alive\r\n"
17853 "Content-Length: 3\r\n\r\n"),
17854 MockWrite("foo"),
17855 };
17856
17857 MockRead data_reads[] = {
17858 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
17859 MockRead(SYNCHRONOUS, OK),
17860 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117861 StaticSocketDataProvider data(data_reads, data_writes);
sclittlefb249892015-09-10 21:33:2217862 session_deps_.socket_factory->AddSocketDataProvider(&data);
17863
17864 TestCompletionCallback callback;
17865
17866 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017867 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0117868 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2217869
17870 std::string response_data;
bnc691fda62016-08-12 00:43:1617871 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2217872
Ryan Sleevib8d7ea02018-05-07 20:01:0117873 EXPECT_EQ(CountWriteBytes(data_writes), trans.GetTotalSentBytes());
17874 EXPECT_EQ(CountReadBytes(data_reads), trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2217875}
17876
bncd16676a2016-07-20 16:23:0117877TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost100Continue) {
danakj1fd259a02016-04-16 03:17:0917878 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217879 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917880 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217881 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2217882
17883 HttpRequestInfo request;
17884 request.method = "POST";
17885 request.url = GURL("http://www.foo.com/");
17886 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017887 request.traffic_annotation =
17888 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2217889
danakj1fd259a02016-04-16 03:17:0917890 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617891 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2217892 MockWrite data_writes[] = {
17893 MockWrite("POST / HTTP/1.1\r\n"
17894 "Host: www.foo.com\r\n"
17895 "Connection: keep-alive\r\n"
17896 "Content-Length: 3\r\n\r\n"),
17897 MockWrite("foo"),
17898 };
17899
17900 MockRead data_reads[] = {
17901 MockRead("HTTP/1.1 100 Continue\r\n\r\n"),
17902 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
17903 MockRead(SYNCHRONOUS, OK),
17904 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117905 StaticSocketDataProvider data(data_reads, data_writes);
sclittlefb249892015-09-10 21:33:2217906 session_deps_.socket_factory->AddSocketDataProvider(&data);
17907
17908 TestCompletionCallback callback;
17909
17910 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017911 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0117912 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2217913
17914 std::string response_data;
bnc691fda62016-08-12 00:43:1617915 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2217916
Ryan Sleevib8d7ea02018-05-07 20:01:0117917 EXPECT_EQ(CountWriteBytes(data_writes), trans.GetTotalSentBytes());
17918 EXPECT_EQ(CountReadBytes(data_reads), trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2217919}
17920
bncd16676a2016-07-20 16:23:0117921TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) {
sclittlefb249892015-09-10 21:33:2217922 ChunkedUploadDataStream upload_data_stream(0);
17923
17924 HttpRequestInfo request;
17925 request.method = "POST";
17926 request.url = GURL("http://www.foo.com/");
17927 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017928 request.traffic_annotation =
17929 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2217930
danakj1fd259a02016-04-16 03:17:0917931 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617932 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2217933 // Send headers successfully, but get an error while sending the body.
17934 MockWrite data_writes[] = {
17935 MockWrite("POST / HTTP/1.1\r\n"
17936 "Host: www.foo.com\r\n"
17937 "Connection: keep-alive\r\n"
17938 "Transfer-Encoding: chunked\r\n\r\n"),
17939 MockWrite("1\r\nf\r\n"), MockWrite("2\r\noo\r\n"), MockWrite("0\r\n\r\n"),
17940 };
17941
17942 MockRead data_reads[] = {
17943 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
17944 MockRead(SYNCHRONOUS, OK),
17945 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117946 StaticSocketDataProvider data(data_reads, data_writes);
sclittlefb249892015-09-10 21:33:2217947 session_deps_.socket_factory->AddSocketDataProvider(&data);
17948
17949 TestCompletionCallback callback;
17950
17951 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017952 trans.Start(&request, callback.callback(), NetLogWithSource()));
sclittlefb249892015-09-10 21:33:2217953
17954 base::RunLoop().RunUntilIdle();
17955 upload_data_stream.AppendData("f", 1, false);
17956
17957 base::RunLoop().RunUntilIdle();
17958 upload_data_stream.AppendData("oo", 2, true);
17959
robpercival214763f2016-07-01 23:27:0117960 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2217961
17962 std::string response_data;
bnc691fda62016-08-12 00:43:1617963 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2217964
Ryan Sleevib8d7ea02018-05-07 20:01:0117965 EXPECT_EQ(CountWriteBytes(data_writes), trans.GetTotalSentBytes());
17966 EXPECT_EQ(CountReadBytes(data_reads), trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2217967}
17968
eustasc7d27da2017-04-06 10:33:2017969void CheckContentEncodingMatching(SpdySessionDependencies* session_deps,
17970 const std::string& accept_encoding,
17971 const std::string& content_encoding,
sky50576f32017-05-01 19:28:0317972 const std::string& location,
eustasc7d27da2017-04-06 10:33:2017973 bool should_match) {
17974 HttpRequestInfo request;
17975 request.method = "GET";
17976 request.url = GURL("http://www.foo.com/");
17977 request.extra_headers.SetHeader(HttpRequestHeaders::kAcceptEncoding,
17978 accept_encoding);
Ramin Halavatib5e433e2018-02-07 07:41:1017979 request.traffic_annotation =
17980 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
eustasc7d27da2017-04-06 10:33:2017981
17982 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps));
17983 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17984 // Send headers successfully, but get an error while sending the body.
17985 MockWrite data_writes[] = {
17986 MockWrite("GET / HTTP/1.1\r\n"
17987 "Host: www.foo.com\r\n"
17988 "Connection: keep-alive\r\n"
17989 "Accept-Encoding: "),
17990 MockWrite(accept_encoding.data()), MockWrite("\r\n\r\n"),
17991 };
17992
sky50576f32017-05-01 19:28:0317993 std::string response_code = "200 OK";
17994 std::string extra;
17995 if (!location.empty()) {
17996 response_code = "301 Redirect\r\nLocation: ";
17997 response_code.append(location);
17998 }
17999
eustasc7d27da2017-04-06 10:33:2018000 MockRead data_reads[] = {
sky50576f32017-05-01 19:28:0318001 MockRead("HTTP/1.0 "),
18002 MockRead(response_code.data()),
18003 MockRead("\r\nContent-Encoding: "),
18004 MockRead(content_encoding.data()),
18005 MockRead("\r\n\r\n"),
eustasc7d27da2017-04-06 10:33:2018006 MockRead(SYNCHRONOUS, OK),
18007 };
Ryan Sleevib8d7ea02018-05-07 20:01:0118008 StaticSocketDataProvider data(data_reads, data_writes);
eustasc7d27da2017-04-06 10:33:2018009 session_deps->socket_factory->AddSocketDataProvider(&data);
18010
18011 TestCompletionCallback callback;
18012
18013 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18014 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18015
18016 rv = callback.WaitForResult();
18017 if (should_match) {
18018 EXPECT_THAT(rv, IsOk());
18019 } else {
18020 EXPECT_THAT(rv, IsError(ERR_CONTENT_DECODING_FAILED));
18021 }
18022}
18023
18024TEST_F(HttpNetworkTransactionTest, MatchContentEncoding1) {
sky50576f32017-05-01 19:28:0318025 CheckContentEncodingMatching(&session_deps_, "gzip,sdch", "br", "", false);
eustasc7d27da2017-04-06 10:33:2018026}
18027
18028TEST_F(HttpNetworkTransactionTest, MatchContentEncoding2) {
sky50576f32017-05-01 19:28:0318029 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "", "",
18030 true);
eustasc7d27da2017-04-06 10:33:2018031}
18032
18033TEST_F(HttpNetworkTransactionTest, MatchContentEncoding3) {
18034 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
sky50576f32017-05-01 19:28:0318035 "", false);
18036}
18037
18038TEST_F(HttpNetworkTransactionTest, MatchContentEncoding4) {
18039 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
18040 "www.foo.com/other", true);
eustasc7d27da2017-04-06 10:33:2018041}
18042
xunjieli96f2a402017-06-05 17:24:2718043TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsSync) {
18044 ProxyConfig proxy_config;
18045 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
18046 proxy_config.set_pac_mandatory(true);
18047 MockAsyncProxyResolver resolver;
Lily Houghton8c2f97d2018-01-22 05:06:5918048 session_deps_.proxy_resolution_service.reset(new ProxyResolutionService(
Ramin Halavatica8d5252018-03-12 05:33:4918049 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
18050 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
Bence Béky8f9d7d3952017-10-09 19:58:0418051 std::make_unique<FailingProxyResolverFactory>(), nullptr));
xunjieli96f2a402017-06-05 17:24:2718052
18053 HttpRequestInfo request;
18054 request.method = "GET";
18055 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1018056 request.traffic_annotation =
18057 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2718058
18059 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18060 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18061
18062 TestCompletionCallback callback;
18063
18064 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18065 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18066 EXPECT_THAT(callback.WaitForResult(),
18067 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
18068}
18069
18070TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsAsync) {
18071 ProxyConfig proxy_config;
18072 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
18073 proxy_config.set_pac_mandatory(true);
18074 MockAsyncProxyResolverFactory* proxy_resolver_factory =
18075 new MockAsyncProxyResolverFactory(false);
18076 MockAsyncProxyResolver resolver;
Lily Houghton8c2f97d2018-01-22 05:06:5918077 session_deps_.proxy_resolution_service.reset(new ProxyResolutionService(
Ramin Halavatica8d5252018-03-12 05:33:4918078 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
18079 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
Lily Houghton8c2f97d2018-01-22 05:06:5918080 base::WrapUnique(proxy_resolver_factory), nullptr));
xunjieli96f2a402017-06-05 17:24:2718081 HttpRequestInfo request;
18082 request.method = "GET";
18083 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1018084 request.traffic_annotation =
18085 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2718086
18087 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18088 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18089
18090 TestCompletionCallback callback;
18091 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18092 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18093
18094 proxy_resolver_factory->pending_requests()[0]->CompleteNowWithForwarder(
18095 ERR_FAILED, &resolver);
18096 EXPECT_THAT(callback.WaitForResult(),
18097 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
18098}
18099
18100TEST_F(HttpNetworkTransactionTest, NoSupportedProxies) {
Lily Houghton8c2f97d2018-01-22 05:06:5918101 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4918102 ProxyResolutionService::CreateFixedFromPacResult(
18103 "QUIC myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2718104 session_deps_.enable_quic = false;
18105 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18106
18107 HttpRequestInfo request;
18108 request.method = "GET";
18109 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1018110 request.traffic_annotation =
18111 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2718112
18113 TestCompletionCallback callback;
18114 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18115 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18116 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18117
18118 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NO_SUPPORTED_PROXIES));
18119}
18120
Douglas Creager3cb042052018-11-06 23:08:5218121//-----------------------------------------------------------------------------
Douglas Creager134b52e2018-11-09 18:00:1418122// Reporting tests
18123
18124#if BUILDFLAG(ENABLE_REPORTING)
18125class HttpNetworkTransactionReportingTest : public HttpNetworkTransactionTest {
18126 protected:
18127 void SetUp() override {
Douglas Creageref5eecdc2018-11-09 20:50:3618128 HttpNetworkTransactionTest::SetUp();
Douglas Creager134b52e2018-11-09 18:00:1418129 auto test_reporting_context = std::make_unique<TestReportingContext>(
18130 &clock_, &tick_clock_, ReportingPolicy());
18131 test_reporting_context_ = test_reporting_context.get();
18132 session_deps_.reporting_service =
18133 ReportingService::CreateForTesting(std::move(test_reporting_context));
18134 }
18135
18136 TestReportingContext* reporting_context() const {
18137 return test_reporting_context_;
18138 }
18139
18140 void clear_reporting_service() {
18141 session_deps_.reporting_service.reset();
18142 test_reporting_context_ = nullptr;
18143 }
18144
18145 // Makes an HTTPS request that should install a valid Reporting policy.
Lily Chenfec60d92019-01-24 01:16:4218146 void RequestPolicy(CertStatus cert_status = 0) {
18147 HttpRequestInfo request;
18148 request.method = "GET";
18149 request.url = GURL(url_);
18150 request.traffic_annotation =
18151 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
18152
Douglas Creager134b52e2018-11-09 18:00:1418153 MockRead data_reads[] = {
18154 MockRead("HTTP/1.0 200 OK\r\n"),
18155 MockRead("Report-To: {\"group\": \"nel\", \"max_age\": 86400, "
18156 "\"endpoints\": [{\"url\": "
18157 "\"https://www.example.org/upload/\"}]}\r\n"),
18158 MockRead("\r\n"),
18159 MockRead("hello world"),
18160 MockRead(SYNCHRONOUS, OK),
18161 };
18162 MockWrite data_writes[] = {
18163 MockWrite("GET / HTTP/1.1\r\n"
18164 "Host: www.example.org\r\n"
18165 "Connection: keep-alive\r\n\r\n"),
18166 };
18167
Lily Chenfec60d92019-01-24 01:16:4218168 StaticSocketDataProvider reads(data_reads, data_writes);
18169 session_deps_.socket_factory->AddSocketDataProvider(&reads);
Douglas Creager134b52e2018-11-09 18:00:1418170
18171 SSLSocketDataProvider ssl(ASYNC, OK);
18172 if (request.url.SchemeIsCryptographic()) {
18173 ssl.ssl_info.cert =
18174 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
18175 ASSERT_TRUE(ssl.ssl_info.cert);
Lily Chenfec60d92019-01-24 01:16:4218176 ssl.ssl_info.cert_status = cert_status;
Douglas Creager134b52e2018-11-09 18:00:1418177 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
18178 }
18179
Douglas Creager134b52e2018-11-09 18:00:1418180 TestCompletionCallback callback;
18181 auto session = CreateSession(&session_deps_);
18182 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18183 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
Lily Chenfec60d92019-01-24 01:16:4218184 EXPECT_THAT(callback.GetResult(rv), IsOk());
Douglas Creager134b52e2018-11-09 18:00:1418185 }
18186
18187 protected:
18188 std::string url_ = "https://www.example.org/";
Douglas Creager134b52e2018-11-09 18:00:1418189
18190 private:
18191 TestReportingContext* test_reporting_context_;
18192};
18193
18194TEST_F(HttpNetworkTransactionReportingTest,
18195 DontProcessReportToHeaderNoService) {
18196 base::HistogramTester histograms;
18197 clear_reporting_service();
18198 RequestPolicy();
18199 histograms.ExpectBucketCount(
18200 ReportingHeaderParser::kHeaderOutcomeHistogram,
18201 ReportingHeaderParser::HeaderOutcome::DISCARDED_NO_REPORTING_SERVICE, 1);
18202}
18203
18204TEST_F(HttpNetworkTransactionReportingTest, DontProcessReportToHeaderHttp) {
18205 base::HistogramTester histograms;
18206 url_ = "http://www.example.org/";
18207 RequestPolicy();
18208 histograms.ExpectBucketCount(
18209 ReportingHeaderParser::kHeaderOutcomeHistogram,
18210 ReportingHeaderParser::HeaderOutcome::DISCARDED_INVALID_SSL_INFO, 1);
18211}
18212
18213TEST_F(HttpNetworkTransactionReportingTest, ProcessReportToHeaderHttps) {
18214 RequestPolicy();
18215 std::vector<const ReportingClient*> clients;
18216 reporting_context()->cache()->GetClients(&clients);
18217 ASSERT_EQ(1u, clients.size());
18218 const auto* client = clients[0];
18219 EXPECT_EQ(url::Origin::Create(GURL("https://www.example.org/")),
18220 client->origin);
18221 EXPECT_EQ(GURL("https://www.example.org/upload/"), client->endpoint);
18222 EXPECT_EQ("nel", client->group);
18223}
18224
18225TEST_F(HttpNetworkTransactionReportingTest,
18226 DontProcessReportToHeaderInvalidHttps) {
18227 base::HistogramTester histograms;
Lily Chenfec60d92019-01-24 01:16:4218228 CertStatus cert_status = CERT_STATUS_COMMON_NAME_INVALID;
18229 RequestPolicy(cert_status);
Douglas Creager134b52e2018-11-09 18:00:1418230 histograms.ExpectBucketCount(
18231 ReportingHeaderParser::kHeaderOutcomeHistogram,
18232 ReportingHeaderParser::HeaderOutcome::DISCARDED_CERT_STATUS_ERROR, 1);
18233}
18234#endif // BUILDFLAG(ENABLE_REPORTING)
18235
18236//-----------------------------------------------------------------------------
Douglas Creager3cb042052018-11-06 23:08:5218237// Network Error Logging tests
18238
18239#if BUILDFLAG(ENABLE_REPORTING)
Lily Chenfec60d92019-01-24 01:16:4218240namespace {
18241
18242const char kUserAgent[] = "Mozilla/1.0";
18243const char kReferrer[] = "https://www.referrer.org/";
18244
18245} // namespace
18246
Douglas Creager3cb042052018-11-06 23:08:5218247class HttpNetworkTransactionNetworkErrorLoggingTest
18248 : public HttpNetworkTransactionTest {
18249 protected:
18250 void SetUp() override {
Douglas Creageref5eecdc2018-11-09 20:50:3618251 HttpNetworkTransactionTest::SetUp();
Douglas Creager3cb042052018-11-06 23:08:5218252 auto network_error_logging_service =
18253 std::make_unique<TestNetworkErrorLoggingService>();
18254 test_network_error_logging_service_ = network_error_logging_service.get();
18255 session_deps_.network_error_logging_service =
18256 std::move(network_error_logging_service);
Lily Chenfec60d92019-01-24 01:16:4218257
18258 extra_headers_.SetHeader("User-Agent", kUserAgent);
18259 extra_headers_.SetHeader("Referer", kReferrer);
18260
18261 request_.method = "GET";
18262 request_.url = GURL(url_);
18263 request_.extra_headers = extra_headers_;
18264 request_.reporting_upload_depth = reporting_upload_depth_;
18265 request_.traffic_annotation =
18266 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Douglas Creager3cb042052018-11-06 23:08:5218267 }
18268
18269 TestNetworkErrorLoggingService* network_error_logging_service() const {
18270 return test_network_error_logging_service_;
18271 }
18272
18273 void clear_network_error_logging_service() {
18274 session_deps_.network_error_logging_service.reset();
18275 test_network_error_logging_service_ = nullptr;
18276 }
18277
18278 // Makes an HTTPS request that should install a valid NEL policy.
Lily Chenfec60d92019-01-24 01:16:4218279 void RequestPolicy(CertStatus cert_status = 0) {
Douglas Creageref5eecdc2018-11-09 20:50:3618280 std::string extra_header_string = extra_headers_.ToString();
Douglas Creager3cb042052018-11-06 23:08:5218281 MockRead data_reads[] = {
18282 MockRead("HTTP/1.0 200 OK\r\n"),
18283 MockRead("NEL: {\"report_to\": \"nel\", \"max_age\": 86400}\r\n"),
18284 MockRead("\r\n"),
18285 MockRead("hello world"),
18286 MockRead(SYNCHRONOUS, OK),
18287 };
18288 MockWrite data_writes[] = {
18289 MockWrite("GET / HTTP/1.1\r\n"
18290 "Host: www.example.org\r\n"
Douglas Creageref5eecdc2018-11-09 20:50:3618291 "Connection: keep-alive\r\n"),
18292 MockWrite(ASYNC, extra_header_string.data(),
18293 extra_header_string.size()),
Douglas Creager3cb042052018-11-06 23:08:5218294 };
18295
Lily Chenfec60d92019-01-24 01:16:4218296 StaticSocketDataProvider reads(data_reads, data_writes);
18297 session_deps_.socket_factory->AddSocketDataProvider(&reads);
Douglas Creager3cb042052018-11-06 23:08:5218298
18299 SSLSocketDataProvider ssl(ASYNC, OK);
Lily Chenfec60d92019-01-24 01:16:4218300 if (request_.url.SchemeIsCryptographic()) {
Douglas Creager3cb042052018-11-06 23:08:5218301 ssl.ssl_info.cert =
18302 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
18303 ASSERT_TRUE(ssl.ssl_info.cert);
Lily Chenfec60d92019-01-24 01:16:4218304 ssl.ssl_info.cert_status = cert_status;
Douglas Creager3cb042052018-11-06 23:08:5218305 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
18306 }
18307
Douglas Creager3cb042052018-11-06 23:08:5218308 TestCompletionCallback callback;
18309 auto session = CreateSession(&session_deps_);
18310 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
Lily Chenfec60d92019-01-24 01:16:4218311 int rv = trans.Start(&request_, callback.callback(), NetLogWithSource());
18312 EXPECT_THAT(callback.GetResult(rv), IsOk());
18313
18314 std::string response_data;
18315 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
18316 EXPECT_EQ("hello world", response_data);
18317 }
18318
18319 void CheckReport(size_t index,
18320 int status_code,
18321 int error_type,
18322 IPAddress server_ip = IPAddress::IPv4Localhost()) {
18323 ASSERT_LT(index, network_error_logging_service()->errors().size());
18324
18325 const NetworkErrorLoggingService::RequestDetails& error =
18326 network_error_logging_service()->errors()[index];
18327 EXPECT_EQ(url_, error.uri);
18328 EXPECT_EQ(kReferrer, error.referrer);
18329 EXPECT_EQ(kUserAgent, error.user_agent);
18330 EXPECT_EQ(server_ip, error.server_ip);
18331 EXPECT_EQ("http/1.1", error.protocol);
18332 EXPECT_EQ("GET", error.method);
18333 EXPECT_EQ(status_code, error.status_code);
18334 EXPECT_EQ(error_type, error.type);
18335 EXPECT_EQ(0, error.reporting_upload_depth);
Douglas Creager3cb042052018-11-06 23:08:5218336 }
18337
18338 protected:
18339 std::string url_ = "https://www.example.org/";
18340 CertStatus cert_status_ = 0;
Lily Chenfec60d92019-01-24 01:16:4218341 HttpRequestInfo request_;
Douglas Creageref5eecdc2018-11-09 20:50:3618342 HttpRequestHeaders extra_headers_;
18343 int reporting_upload_depth_ = 0;
Douglas Creager3cb042052018-11-06 23:08:5218344
18345 private:
18346 TestNetworkErrorLoggingService* test_network_error_logging_service_;
18347};
18348
18349TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18350 DontProcessNelHeaderNoService) {
18351 base::HistogramTester histograms;
18352 clear_network_error_logging_service();
18353 RequestPolicy();
18354 histograms.ExpectBucketCount(
18355 NetworkErrorLoggingService::kHeaderOutcomeHistogram,
18356 NetworkErrorLoggingService::HeaderOutcome::
18357 DISCARDED_NO_NETWORK_ERROR_LOGGING_SERVICE,
18358 1);
18359}
18360
18361TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18362 DontProcessNelHeaderHttp) {
18363 base::HistogramTester histograms;
18364 url_ = "http://www.example.org/";
Lily Chenfec60d92019-01-24 01:16:4218365 request_.url = GURL(url_);
Douglas Creager3cb042052018-11-06 23:08:5218366 RequestPolicy();
18367 histograms.ExpectBucketCount(
18368 NetworkErrorLoggingService::kHeaderOutcomeHistogram,
18369 NetworkErrorLoggingService::HeaderOutcome::DISCARDED_INVALID_SSL_INFO, 1);
18370}
18371
18372TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, ProcessNelHeaderHttps) {
18373 RequestPolicy();
18374 ASSERT_EQ(1u, network_error_logging_service()->headers().size());
18375 const auto& header = network_error_logging_service()->headers()[0];
18376 EXPECT_EQ(url::Origin::Create(GURL("https://www.example.org/")),
18377 header.origin);
18378 EXPECT_EQ(IPAddress::IPv4Localhost(), header.received_ip_address);
18379 EXPECT_EQ("{\"report_to\": \"nel\", \"max_age\": 86400}", header.value);
18380}
18381
18382TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18383 DontProcessNelHeaderInvalidHttps) {
18384 base::HistogramTester histograms;
Lily Chenfec60d92019-01-24 01:16:4218385 CertStatus cert_status = CERT_STATUS_COMMON_NAME_INVALID;
18386 RequestPolicy(cert_status);
Douglas Creager3cb042052018-11-06 23:08:5218387 histograms.ExpectBucketCount(
18388 NetworkErrorLoggingService::kHeaderOutcomeHistogram,
18389 NetworkErrorLoggingService::HeaderOutcome::DISCARDED_CERT_STATUS_ERROR,
18390 1);
18391}
Douglas Creageref5eecdc2018-11-09 20:50:3618392
Lily Chenfec60d92019-01-24 01:16:4218393TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, CreateReportSuccess) {
Douglas Creageref5eecdc2018-11-09 20:50:3618394 RequestPolicy();
18395 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
Lily Chenfec60d92019-01-24 01:16:4218396 CheckReport(0 /* index */, 200 /* status_code */, OK);
18397}
18398
18399TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18400 CreateReportErrorAfterStart) {
18401 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18402 auto trans =
18403 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18404
18405 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
18406 StaticSocketDataProvider data;
18407 data.set_connect_data(mock_connect);
18408 session_deps_.socket_factory->AddSocketDataProvider(&data);
18409
18410 TestCompletionCallback callback;
18411
18412 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
18413 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_NAME_NOT_RESOLVED));
18414
18415 trans.reset();
18416
18417 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18418 CheckReport(0 /* index */, 0 /* status_code */, ERR_NAME_NOT_RESOLVED,
18419 IPAddress() /* server_ip */);
18420}
18421
18422// Same as above except the error is ASYNC
18423TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18424 CreateReportErrorAfterStartAsync) {
18425 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18426 auto trans =
18427 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18428
18429 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
18430 StaticSocketDataProvider data;
18431 data.set_connect_data(mock_connect);
18432 session_deps_.socket_factory->AddSocketDataProvider(&data);
18433
18434 TestCompletionCallback callback;
18435
18436 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
18437 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_NAME_NOT_RESOLVED));
18438
18439 trans.reset();
18440
18441 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18442 CheckReport(0 /* index */, 0 /* status_code */, ERR_NAME_NOT_RESOLVED,
18443 IPAddress() /* server_ip */);
18444}
18445
18446TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18447 CreateReportReadBodyError) {
18448 std::string extra_header_string = extra_headers_.ToString();
18449 MockRead data_reads[] = {
18450 MockRead("HTTP/1.0 200 OK\r\n"),
18451 MockRead("Content-Length: 100\r\n\r\n"), // wrong content length
18452 MockRead("hello world"),
18453 MockRead(SYNCHRONOUS, OK),
18454 };
18455 MockWrite data_writes[] = {
18456 MockWrite("GET / HTTP/1.1\r\n"
18457 "Host: www.example.org\r\n"
18458 "Connection: keep-alive\r\n"),
18459 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18460 };
18461
18462 StaticSocketDataProvider reads(data_reads, data_writes);
18463 session_deps_.socket_factory->AddSocketDataProvider(&reads);
18464
18465 SSLSocketDataProvider ssl(ASYNC, OK);
18466 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
18467
18468 // Log start time
18469 base::TimeTicks start_time = base::TimeTicks::Now();
18470
18471 TestCompletionCallback callback;
18472 auto session = CreateSession(&session_deps_);
18473 auto trans =
18474 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18475 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
18476 EXPECT_THAT(callback.GetResult(rv), IsOk());
18477
18478 const HttpResponseInfo* response = trans->GetResponseInfo();
18479 ASSERT_TRUE(response);
18480
18481 EXPECT_TRUE(response->headers);
18482 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
18483
18484 std::string response_data;
18485 rv = ReadTransaction(trans.get(), &response_data);
18486 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
18487
18488 trans.reset();
18489
18490 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18491
18492 CheckReport(0 /* index */, 200 /* status_code */,
18493 ERR_CONTENT_LENGTH_MISMATCH);
18494 const NetworkErrorLoggingService::RequestDetails& error =
18495 network_error_logging_service()->errors()[0];
18496 EXPECT_LE(error.elapsed_time, base::TimeTicks::Now() - start_time);
18497}
18498
18499// Same as above except the final read is ASYNC.
18500TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18501 CreateReportReadBodyErrorAsync) {
18502 std::string extra_header_string = extra_headers_.ToString();
18503 MockRead data_reads[] = {
18504 MockRead("HTTP/1.0 200 OK\r\n"),
18505 MockRead("Content-Length: 100\r\n\r\n"), // wrong content length
18506 MockRead("hello world"),
18507 MockRead(ASYNC, OK),
18508 };
18509 MockWrite data_writes[] = {
18510 MockWrite("GET / HTTP/1.1\r\n"
18511 "Host: www.example.org\r\n"
18512 "Connection: keep-alive\r\n"),
18513 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18514 };
18515
18516 StaticSocketDataProvider reads(data_reads, data_writes);
18517 session_deps_.socket_factory->AddSocketDataProvider(&reads);
18518
18519 SSLSocketDataProvider ssl(ASYNC, OK);
18520 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
18521
18522 // Log start time
18523 base::TimeTicks start_time = base::TimeTicks::Now();
18524
18525 TestCompletionCallback callback;
18526 auto session = CreateSession(&session_deps_);
18527 auto trans =
18528 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18529 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
18530 EXPECT_THAT(callback.GetResult(rv), IsOk());
18531
18532 const HttpResponseInfo* response = trans->GetResponseInfo();
18533 ASSERT_TRUE(response);
18534
18535 EXPECT_TRUE(response->headers);
18536 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
18537
18538 std::string response_data;
18539 rv = ReadTransaction(trans.get(), &response_data);
18540 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
18541
18542 trans.reset();
18543
18544 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18545
18546 CheckReport(0 /* index */, 200 /* status_code */,
18547 ERR_CONTENT_LENGTH_MISMATCH);
18548 const NetworkErrorLoggingService::RequestDetails& error =
18549 network_error_logging_service()->errors()[0];
18550 EXPECT_LE(error.elapsed_time, base::TimeTicks::Now() - start_time);
18551}
18552
18553TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18554 CreateReportRestartWithAuth) {
18555 std::string extra_header_string = extra_headers_.ToString();
18556 static const base::TimeDelta kSleepDuration =
18557 base::TimeDelta::FromMilliseconds(10);
18558
18559 MockWrite data_writes1[] = {
18560 MockWrite("GET / HTTP/1.1\r\n"
18561 "Host: www.example.org\r\n"
18562 "Connection: keep-alive\r\n"),
18563 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18564 };
18565
18566 MockRead data_reads1[] = {
18567 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
18568 // Give a couple authenticate options (only the middle one is actually
18569 // supported).
18570 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
18571 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
18572 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
18573 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
18574 // Large content-length -- won't matter, as connection will be reset.
18575 MockRead("Content-Length: 10000\r\n\r\n"),
18576 MockRead(SYNCHRONOUS, ERR_FAILED),
18577 };
18578
18579 // After calling trans->RestartWithAuth(), this is the request we should
18580 // be issuing -- the final header line contains the credentials.
18581 MockWrite data_writes2[] = {
18582 MockWrite("GET / HTTP/1.1\r\n"
18583 "Host: www.example.org\r\n"
18584 "Connection: keep-alive\r\n"
18585 "Authorization: Basic Zm9vOmJhcg==\r\n"),
18586 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18587 };
18588
18589 // Lastly, the server responds with the actual content.
18590 MockRead data_reads2[] = {
18591 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
18592 MockRead("hello world"),
18593 MockRead(SYNCHRONOUS, OK),
18594 };
18595
18596 StaticSocketDataProvider data1(data_reads1, data_writes1);
18597 StaticSocketDataProvider data2(data_reads2, data_writes2);
18598 session_deps_.socket_factory->AddSocketDataProvider(&data1);
18599 session_deps_.socket_factory->AddSocketDataProvider(&data2);
18600
18601 SSLSocketDataProvider ssl1(ASYNC, OK);
18602 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
18603 SSLSocketDataProvider ssl2(ASYNC, OK);
18604 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
18605
18606 base::TimeTicks start_time = base::TimeTicks::Now();
18607 base::TimeTicks restart_time;
18608
18609 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18610 auto trans =
18611 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18612
18613 TestCompletionCallback callback1;
18614
18615 int rv = trans->Start(&request_, callback1.callback(), NetLogWithSource());
18616 EXPECT_THAT(callback1.GetResult(rv), IsOk());
18617
18618 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18619
18620 TestCompletionCallback callback2;
18621
18622 // Wait 10 ms then restart with auth
18623 FastForwardBy(kSleepDuration);
18624 restart_time = base::TimeTicks::Now();
18625 rv =
18626 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
18627 EXPECT_THAT(callback2.GetResult(rv), IsOk());
18628
18629 std::string response_data;
18630 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
18631 EXPECT_EQ("hello world", response_data);
18632
18633 trans.reset();
18634
18635 // One 401 report for the auth challenge, then a 200 report for the successful
18636 // retry. Note that we don't report the error draining the body, as the first
18637 // request already generated a report for the auth challenge.
18638 ASSERT_EQ(2u, network_error_logging_service()->errors().size());
18639
18640 // Check error report contents
18641 CheckReport(0 /* index */, 401 /* status_code */, OK);
18642 CheckReport(1 /* index */, 200 /* status_code */, OK);
18643
18644 const NetworkErrorLoggingService::RequestDetails& error1 =
18645 network_error_logging_service()->errors()[0];
18646 const NetworkErrorLoggingService::RequestDetails& error2 =
18647 network_error_logging_service()->errors()[1];
18648
18649 // Sanity-check elapsed time values
18650 EXPECT_EQ(error1.elapsed_time, restart_time - start_time - kSleepDuration);
18651 // Check that the start time is refreshed when restarting with auth.
18652 EXPECT_EQ(error2.elapsed_time, base::TimeTicks::Now() - restart_time);
18653}
18654
18655// Same as above, except draining the body before restarting fails
18656// asynchronously.
18657TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18658 CreateReportRestartWithAuthAsync) {
18659 std::string extra_header_string = extra_headers_.ToString();
18660 static const base::TimeDelta kSleepDuration =
18661 base::TimeDelta::FromMilliseconds(10);
18662
18663 MockWrite data_writes1[] = {
18664 MockWrite("GET / HTTP/1.1\r\n"
18665 "Host: www.example.org\r\n"
18666 "Connection: keep-alive\r\n"),
18667 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18668 };
18669
18670 MockRead data_reads1[] = {
18671 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
18672 // Give a couple authenticate options (only the middle one is actually
18673 // supported).
18674 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
18675 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
18676 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
18677 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
18678 // Large content-length -- won't matter, as connection will be reset.
18679 MockRead("Content-Length: 10000\r\n\r\n"),
18680 MockRead(ASYNC, ERR_FAILED),
18681 };
18682
18683 // After calling trans->RestartWithAuth(), this is the request we should
18684 // be issuing -- the final header line contains the credentials.
18685 MockWrite data_writes2[] = {
18686 MockWrite("GET / HTTP/1.1\r\n"
18687 "Host: www.example.org\r\n"
18688 "Connection: keep-alive\r\n"
18689 "Authorization: Basic Zm9vOmJhcg==\r\n"),
18690 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18691 };
18692
18693 // Lastly, the server responds with the actual content.
18694 MockRead data_reads2[] = {
18695 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
18696 MockRead("hello world"),
18697 MockRead(SYNCHRONOUS, OK),
18698 };
18699
18700 StaticSocketDataProvider data1(data_reads1, data_writes1);
18701 StaticSocketDataProvider data2(data_reads2, data_writes2);
18702 session_deps_.socket_factory->AddSocketDataProvider(&data1);
18703 session_deps_.socket_factory->AddSocketDataProvider(&data2);
18704
18705 SSLSocketDataProvider ssl1(ASYNC, OK);
18706 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
18707 SSLSocketDataProvider ssl2(ASYNC, OK);
18708 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
18709
18710 base::TimeTicks start_time = base::TimeTicks::Now();
18711 base::TimeTicks restart_time;
18712
18713 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18714 auto trans =
18715 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18716
18717 TestCompletionCallback callback1;
18718
18719 int rv = trans->Start(&request_, callback1.callback(), NetLogWithSource());
18720 EXPECT_THAT(callback1.GetResult(rv), IsOk());
18721
18722 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18723
18724 TestCompletionCallback callback2;
18725
18726 // Wait 10 ms then restart with auth
18727 FastForwardBy(kSleepDuration);
18728 restart_time = base::TimeTicks::Now();
18729 rv =
18730 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
18731 EXPECT_THAT(callback2.GetResult(rv), IsOk());
18732
18733 std::string response_data;
18734 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
18735 EXPECT_EQ("hello world", response_data);
18736
18737 trans.reset();
18738
18739 // One 401 report for the auth challenge, then a 200 report for the successful
18740 // retry. Note that we don't report the error draining the body, as the first
18741 // request already generated a report for the auth challenge.
18742 ASSERT_EQ(2u, network_error_logging_service()->errors().size());
18743
18744 // Check error report contents
18745 CheckReport(0 /* index */, 401 /* status_code */, OK);
18746 CheckReport(1 /* index */, 200 /* status_code */, OK);
18747
18748 const NetworkErrorLoggingService::RequestDetails& error1 =
18749 network_error_logging_service()->errors()[0];
18750 const NetworkErrorLoggingService::RequestDetails& error2 =
18751 network_error_logging_service()->errors()[1];
18752
18753 // Sanity-check elapsed time values
18754 EXPECT_EQ(error1.elapsed_time, restart_time - start_time - kSleepDuration);
18755 // Check that the start time is refreshed when restarting with auth.
18756 EXPECT_EQ(error2.elapsed_time, base::TimeTicks::Now() - restart_time);
18757}
18758
18759TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18760 CreateReportRetryKeepAliveConnectionReset) {
18761 std::string extra_header_string = extra_headers_.ToString();
18762 MockWrite data_writes1[] = {
18763 MockWrite("GET / HTTP/1.1\r\n"
18764 "Host: www.example.org\r\n"
18765 "Connection: keep-alive\r\n"),
18766 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18767 MockWrite("GET / HTTP/1.1\r\n"
18768 "Host: www.example.org\r\n"
18769 "Connection: keep-alive\r\n"),
18770 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18771 };
18772
18773 MockRead data_reads1[] = {
18774 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
18775 MockRead("hello"),
18776 // Connection is reset
18777 MockRead(ASYNC, ERR_CONNECTION_RESET),
18778 };
18779
18780 // Successful retry
18781 MockRead data_reads2[] = {
18782 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
18783 MockRead("world"),
18784 MockRead(ASYNC, OK),
18785 };
18786
18787 StaticSocketDataProvider data1(data_reads1, data_writes1);
18788 StaticSocketDataProvider data2(data_reads2, base::span<MockWrite>());
18789 session_deps_.socket_factory->AddSocketDataProvider(&data1);
18790 session_deps_.socket_factory->AddSocketDataProvider(&data2);
18791
18792 SSLSocketDataProvider ssl1(ASYNC, OK);
18793 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
18794 SSLSocketDataProvider ssl2(ASYNC, OK);
18795 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
18796
18797 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18798 auto trans1 =
18799 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18800
18801 TestCompletionCallback callback1;
18802
18803 int rv = trans1->Start(&request_, callback1.callback(), NetLogWithSource());
18804 EXPECT_THAT(callback1.GetResult(rv), IsOk());
18805
18806 std::string response_data;
18807 ASSERT_THAT(ReadTransaction(trans1.get(), &response_data), IsOk());
18808 EXPECT_EQ("hello", response_data);
18809
18810 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18811
18812 auto trans2 =
18813 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18814
18815 TestCompletionCallback callback2;
18816
18817 rv = trans2->Start(&request_, callback2.callback(), NetLogWithSource());
18818 EXPECT_THAT(callback2.GetResult(rv), IsOk());
18819
18820 ASSERT_THAT(ReadTransaction(trans2.get(), &response_data), IsOk());
18821 EXPECT_EQ("world", response_data);
18822
18823 trans1.reset();
18824 trans2.reset();
18825
18826 // One OK report from first request, then a ERR_CONNECTION_RESET report from
18827 // the second request, then an OK report from the successful retry.
18828 ASSERT_EQ(3u, network_error_logging_service()->errors().size());
18829
18830 // Check error report contents
18831 CheckReport(0 /* index */, 200 /* status_code */, OK);
18832 CheckReport(1 /* index */, 0 /* status_code */, ERR_CONNECTION_RESET);
18833 CheckReport(2 /* index */, 200 /* status_code */, OK);
18834}
18835
18836TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18837 CreateReportRetryKeepAlive408) {
18838 std::string extra_header_string = extra_headers_.ToString();
18839 MockWrite data_writes1[] = {
18840 MockWrite("GET / HTTP/1.1\r\n"
18841 "Host: www.example.org\r\n"
18842 "Connection: keep-alive\r\n"),
18843 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18844 MockWrite("GET / HTTP/1.1\r\n"
18845 "Host: www.example.org\r\n"
18846 "Connection: keep-alive\r\n"),
18847 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18848 };
18849
18850 MockRead data_reads1[] = {
18851 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
18852 MockRead("hello"),
18853 // 408 Request Timeout
18854 MockRead(SYNCHRONOUS,
18855 "HTTP/1.1 408 Request Timeout\r\n"
18856 "Connection: Keep-Alive\r\n"
18857 "Content-Length: 6\r\n\r\n"
18858 "Pickle"),
18859 };
18860
18861 // Successful retry
18862 MockRead data_reads2[] = {
18863 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
18864 MockRead("world"),
18865 MockRead(ASYNC, OK),
18866 };
18867
18868 StaticSocketDataProvider data1(data_reads1, data_writes1);
18869 StaticSocketDataProvider data2(data_reads2, base::span<MockWrite>());
18870 session_deps_.socket_factory->AddSocketDataProvider(&data1);
18871 session_deps_.socket_factory->AddSocketDataProvider(&data2);
18872
18873 SSLSocketDataProvider ssl1(ASYNC, OK);
18874 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
18875 SSLSocketDataProvider ssl2(ASYNC, OK);
18876 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
18877
18878 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18879 auto trans1 =
18880 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18881
18882 TestCompletionCallback callback1;
18883
18884 int rv = trans1->Start(&request_, callback1.callback(), NetLogWithSource());
18885 EXPECT_THAT(callback1.GetResult(rv), IsOk());
18886
18887 std::string response_data;
18888 ASSERT_THAT(ReadTransaction(trans1.get(), &response_data), IsOk());
18889 EXPECT_EQ("hello", response_data);
18890
18891 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18892
18893 auto trans2 =
18894 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18895
18896 TestCompletionCallback callback2;
18897
18898 rv = trans2->Start(&request_, callback2.callback(), NetLogWithSource());
18899 EXPECT_THAT(callback2.GetResult(rv), IsOk());
18900
18901 ASSERT_THAT(ReadTransaction(trans2.get(), &response_data), IsOk());
18902 EXPECT_EQ("world", response_data);
18903
18904 trans1.reset();
18905 trans2.reset();
18906
18907 // One 200 report from first request, then a 408 report from
18908 // the second request, then a 200 report from the successful retry.
18909 ASSERT_EQ(3u, network_error_logging_service()->errors().size());
18910
18911 // Check error report contents
18912 CheckReport(0 /* index */, 200 /* status_code */, OK);
18913 CheckReport(1 /* index */, 408 /* status_code */, OK);
18914 CheckReport(2 /* index */, 200 /* status_code */, OK);
18915}
18916
18917TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18918 CreateReportRetry421WithoutConnectionPooling) {
18919 // Two hosts resolve to the same IP address.
18920 const std::string ip_addr = "1.2.3.4";
18921 IPAddress ip;
18922 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
18923 IPEndPoint peer_addr = IPEndPoint(ip, 443);
18924
18925 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
18926 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
18927 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
18928
18929 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18930
18931 // Two requests on the first connection.
18932 spdy::SpdySerializedFrame req1(
18933 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
18934 spdy_util_.UpdateWithStreamDestruction(1);
18935 spdy::SpdySerializedFrame req2(
18936 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
18937 spdy::SpdySerializedFrame rst(
18938 spdy_util_.ConstructSpdyRstStream(3, spdy::ERROR_CODE_CANCEL));
18939 MockWrite writes1[] = {
18940 CreateMockWrite(req1, 0),
18941 CreateMockWrite(req2, 3),
18942 CreateMockWrite(rst, 6),
18943 };
18944
18945 // The first one succeeds, the second gets error 421 Misdirected Request.
18946 spdy::SpdySerializedFrame resp1(
18947 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
18948 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
18949 spdy::SpdyHeaderBlock response_headers;
18950 response_headers[spdy::kHttp2StatusHeader] = "421";
18951 spdy::SpdySerializedFrame resp2(
18952 spdy_util_.ConstructSpdyReply(3, std::move(response_headers)));
18953 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
18954 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
18955
18956 MockConnect connect1(ASYNC, OK, peer_addr);
18957 SequencedSocketData data1(connect1, reads1, writes1);
18958 session_deps_.socket_factory->AddSocketDataProvider(&data1);
18959
18960 AddSSLSocketData();
18961
18962 // Retry the second request on a second connection.
18963 SpdyTestUtil spdy_util2;
18964 spdy::SpdySerializedFrame req3(
18965 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
18966 MockWrite writes2[] = {
18967 CreateMockWrite(req3, 0),
18968 };
18969
18970 spdy::SpdySerializedFrame resp3(
18971 spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
18972 spdy::SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
18973 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
18974 MockRead(ASYNC, 0, 3)};
18975
18976 MockConnect connect2(ASYNC, OK, peer_addr);
18977 SequencedSocketData data2(connect2, reads2, writes2);
18978 session_deps_.socket_factory->AddSocketDataProvider(&data2);
18979
18980 AddSSLSocketData();
18981
18982 // Preload mail.example.org into HostCache.
18983 HostPortPair host_port("mail.example.org", 443);
18984 HostResolver::RequestInfo resolve_info(host_port);
18985 AddressList ignored;
18986 std::unique_ptr<HostResolver::Request> request;
18987 TestCompletionCallback callback;
18988 int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
18989 &ignored, callback.callback(),
18990 &request, NetLogWithSource());
18991 EXPECT_THAT(callback.GetResult(rv), IsOk());
18992
18993 HttpRequestInfo request1;
18994 request1.method = "GET";
18995 request1.url = GURL("https://www.example.org/");
18996 request1.load_flags = 0;
18997 request1.traffic_annotation =
18998 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
18999 auto trans1 =
19000 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19001
19002 rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
19003 EXPECT_THAT(callback.GetResult(rv), IsOk());
19004
19005 const HttpResponseInfo* response = trans1->GetResponseInfo();
19006 ASSERT_TRUE(response);
19007 ASSERT_TRUE(response->headers);
19008 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
19009 EXPECT_TRUE(response->was_fetched_via_spdy);
19010 EXPECT_TRUE(response->was_alpn_negotiated);
19011 std::string response_data;
19012 ASSERT_THAT(ReadTransaction(trans1.get(), &response_data), IsOk());
19013 EXPECT_EQ("hello!", response_data);
19014
19015 trans1.reset();
19016
19017 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
19018
19019 HttpRequestInfo request2;
19020 request2.method = "GET";
19021 request2.url = GURL("https://mail.example.org/");
19022 request2.load_flags = 0;
19023 request2.traffic_annotation =
19024 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19025 auto trans2 =
19026 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19027
19028 BoundTestNetLog log;
19029 rv = trans2->Start(&request2, callback.callback(), log.bound());
19030 EXPECT_THAT(callback.GetResult(rv), IsOk());
19031
19032 response = trans2->GetResponseInfo();
19033 ASSERT_TRUE(response);
19034 ASSERT_TRUE(response->headers);
19035 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
19036 EXPECT_TRUE(response->was_fetched_via_spdy);
19037 EXPECT_TRUE(response->was_alpn_negotiated);
19038 ASSERT_THAT(ReadTransaction(trans2.get(), &response_data), IsOk());
19039 EXPECT_EQ("hello!", response_data);
19040
19041 trans2.reset();
19042
19043 // One 200 report from the first request, then a 421 report from the
19044 // second request, then a 200 report from the successful retry.
19045 ASSERT_EQ(3u, network_error_logging_service()->errors().size());
19046
19047 // Check error report contents
19048 const NetworkErrorLoggingService::RequestDetails& error1 =
19049 network_error_logging_service()->errors()[0];
19050 EXPECT_EQ(GURL("https://www.example.org/"), error1.uri);
19051 EXPECT_TRUE(error1.referrer.is_empty());
19052 EXPECT_EQ("", error1.user_agent);
19053 EXPECT_EQ(ip, error1.server_ip);
19054 EXPECT_EQ("h2", error1.protocol);
19055 EXPECT_EQ("GET", error1.method);
19056 EXPECT_EQ(200, error1.status_code);
19057 EXPECT_EQ(OK, error1.type);
19058 EXPECT_EQ(0, error1.reporting_upload_depth);
19059
19060 const NetworkErrorLoggingService::RequestDetails& error2 =
19061 network_error_logging_service()->errors()[1];
19062 EXPECT_EQ(GURL("https://mail.example.org/"), error2.uri);
19063 EXPECT_TRUE(error2.referrer.is_empty());
19064 EXPECT_EQ("", error2.user_agent);
19065 EXPECT_EQ(ip, error2.server_ip);
19066 EXPECT_EQ("h2", error2.protocol);
19067 EXPECT_EQ("GET", error2.method);
19068 EXPECT_EQ(421, error2.status_code);
19069 EXPECT_EQ(OK, error2.type);
19070 EXPECT_EQ(0, error2.reporting_upload_depth);
19071
19072 const NetworkErrorLoggingService::RequestDetails& error3 =
19073 network_error_logging_service()->errors()[2];
19074 EXPECT_EQ(GURL("https://mail.example.org/"), error3.uri);
19075 EXPECT_TRUE(error3.referrer.is_empty());
19076 EXPECT_EQ("", error3.user_agent);
19077 EXPECT_EQ(ip, error3.server_ip);
19078 EXPECT_EQ("h2", error3.protocol);
19079 EXPECT_EQ("GET", error3.method);
19080 EXPECT_EQ(200, error3.status_code);
19081 EXPECT_EQ(OK, error3.type);
19082 EXPECT_EQ(0, error3.reporting_upload_depth);
Douglas Creageref5eecdc2018-11-09 20:50:3619083}
19084
Lily Chen00196ab62018-12-04 19:52:2919085TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, DontCreateReportHttp) {
19086 base::HistogramTester histograms;
19087 RequestPolicy();
19088 EXPECT_EQ(1u, network_error_logging_service()->headers().size());
19089 EXPECT_EQ(1u, network_error_logging_service()->errors().size());
19090
19091 // Make HTTP request
19092 std::string extra_header_string = extra_headers_.ToString();
19093 MockRead data_reads[] = {
19094 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
19095 MockRead("hello world"),
19096 MockRead(SYNCHRONOUS, OK),
19097 };
19098 MockWrite data_writes[] = {
19099 MockWrite("GET / HTTP/1.1\r\n"
19100 "Host: www.example.org\r\n"
19101 "Connection: keep-alive\r\n"),
19102 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
19103 };
19104
Lily Chen00196ab62018-12-04 19:52:2919105 StaticSocketDataProvider reads(data_reads, data_writes);
19106 session_deps_.socket_factory->AddSocketDataProvider(&reads);
19107
Lily Chenfec60d92019-01-24 01:16:4219108 // Insecure url
19109 url_ = "http://www.example.org/";
19110 request_.url = GURL(url_);
19111
Lily Chen00196ab62018-12-04 19:52:2919112 TestCompletionCallback callback;
19113 auto session = CreateSession(&session_deps_);
Lily Chenfec60d92019-01-24 01:16:4219114 auto trans =
19115 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19116 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
19117 EXPECT_THAT(callback.GetResult(rv), IsOk());
19118
19119 std::string response_data;
19120 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
19121 EXPECT_EQ("hello world", response_data);
Lily Chen00196ab62018-12-04 19:52:2919122
19123 // Insecure request does not generate a report
19124 histograms.ExpectBucketCount(
19125 NetworkErrorLoggingService::kRequestOutcomeHistogram,
19126 NetworkErrorLoggingService::RequestOutcome::DISCARDED_INSECURE_ORIGIN, 1);
19127
19128 EXPECT_EQ(1u, network_error_logging_service()->errors().size());
19129}
19130
19131TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
19132 DontCreateReportHttpError) {
19133 base::HistogramTester histograms;
19134 RequestPolicy();
19135 EXPECT_EQ(1u, network_error_logging_service()->headers().size());
19136 EXPECT_EQ(1u, network_error_logging_service()->errors().size());
19137
19138 // Make HTTP request that fails
19139 MockRead data_reads[] = {
19140 MockRead("hello world"),
19141 MockRead(SYNCHRONOUS, OK),
19142 };
19143
19144 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
19145 session_deps_.socket_factory->AddSocketDataProvider(&data);
19146
Lily Chenfec60d92019-01-24 01:16:4219147 url_ = "http://www.originwithoutpolicy.com:2000/";
19148 request_.url = GURL(url_);
19149
Lily Chen00196ab62018-12-04 19:52:2919150 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19151
Lily Chen00196ab62018-12-04 19:52:2919152 auto trans =
19153 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Lily Chen00196ab62018-12-04 19:52:2919154 TestCompletionCallback callback;
Lily Chenfec60d92019-01-24 01:16:4219155 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
Lily Chen00196ab62018-12-04 19:52:2919156 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_INVALID_HTTP_RESPONSE));
19157
19158 // Insecure request does not generate a report, regardless of existence of a
19159 // policy for the origin.
19160 histograms.ExpectBucketCount(
19161 NetworkErrorLoggingService::kRequestOutcomeHistogram,
19162 NetworkErrorLoggingService::RequestOutcome::DISCARDED_INSECURE_ORIGIN, 1);
19163
19164 EXPECT_EQ(1u, network_error_logging_service()->errors().size());
19165}
19166
Douglas Creageref5eecdc2018-11-09 20:50:3619167TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
19168 ReportContainsUploadDepth) {
19169 reporting_upload_depth_ = 7;
Lily Chenfec60d92019-01-24 01:16:4219170 request_.reporting_upload_depth = reporting_upload_depth_;
Douglas Creageref5eecdc2018-11-09 20:50:3619171 RequestPolicy();
19172 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
Lily Chenfec60d92019-01-24 01:16:4219173 const NetworkErrorLoggingService::RequestDetails& error =
19174 network_error_logging_service()->errors()[0];
Douglas Creageref5eecdc2018-11-09 20:50:3619175 EXPECT_EQ(7, error.reporting_upload_depth);
19176}
19177
Lily Chenfec60d92019-01-24 01:16:4219178TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, ReportElapsedTime) {
19179 std::string extra_header_string = extra_headers_.ToString();
19180 static const base::TimeDelta kSleepDuration =
19181 base::TimeDelta::FromMilliseconds(10);
19182
19183 std::vector<MockWrite> data_writes = {
19184 MockWrite(ASYNC, 0,
19185 "GET / HTTP/1.1\r\n"
19186 "Host: www.example.org\r\n"
19187 "Connection: keep-alive\r\n"),
19188 MockWrite(ASYNC, 1, extra_header_string.data()),
19189 };
19190
19191 std::vector<MockRead> data_reads = {
19192 // Write one byte of the status line, followed by a pause.
19193 MockRead(ASYNC, 2, "H"),
19194 MockRead(ASYNC, ERR_IO_PENDING, 3),
19195 MockRead(ASYNC, 4, "TTP/1.1 200 OK\r\n\r\n"),
19196 MockRead(ASYNC, 5, "hello world"),
19197 MockRead(SYNCHRONOUS, OK, 6),
19198 };
19199
19200 SequencedSocketData data(data_reads, data_writes);
19201 session_deps_.socket_factory->AddSocketDataProvider(&data);
19202
19203 SSLSocketDataProvider ssl(ASYNC, OK);
19204 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
19205
19206 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19207
19208 auto trans =
19209 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19210
19211 TestCompletionCallback callback;
19212
19213 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
19214 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
19215
19216 data.RunUntilPaused();
19217 ASSERT_TRUE(data.IsPaused());
19218 FastForwardBy(kSleepDuration);
19219 data.Resume();
19220
19221 EXPECT_THAT(callback.GetResult(rv), IsOk());
19222
19223 std::string response_data;
19224 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
19225 EXPECT_EQ("hello world", response_data);
19226
19227 trans.reset();
19228
Douglas Creageref5eecdc2018-11-09 20:50:3619229 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
Lily Chenfec60d92019-01-24 01:16:4219230
19231 CheckReport(0 /* index */, 200 /* status_code */, OK);
19232
19233 const NetworkErrorLoggingService::RequestDetails& error =
19234 network_error_logging_service()->errors()[0];
19235
19236 // Sanity-check elapsed time in error report
19237 EXPECT_EQ(kSleepDuration, error.elapsed_time);
Douglas Creageref5eecdc2018-11-09 20:50:3619238}
Lily Chenfec60d92019-01-24 01:16:4219239
Douglas Creager3cb042052018-11-06 23:08:5219240#endif // BUILDFLAG(ENABLE_REPORTING)
19241
[email protected]89ceba9a2009-03-21 03:46:0619242} // namespace net