blob: 6d0f47ee77672ac077fbd27d41d094623427d9ab [file] [log] [blame]
[email protected]23e482282013-06-14 16:08:021// Copyright 2013 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit586acc5fe2008-07-26 22:42:524
[email protected]2d731a32010-04-29 01:04:065#include "net/http/http_network_transaction.h"
6
[email protected]77848d12008-11-14 00:00:227#include <math.h> // ceil
[email protected]5285d972011-10-18 18:56:348#include <stdarg.h>
sclittlebe1ccf62015-09-02 19:40:369#include <stdint.h>
danakj1fd259a02016-04-16 03:17:0910
avibf0746c2015-12-09 19:53:1411#include <limits>
rdsmith1d343be52016-10-21 20:37:5012#include <set>
[email protected]5285d972011-10-18 18:56:3413#include <string>
dchengc7eeda422015-12-26 03:56:4814#include <utility>
[email protected]95d88ffe2010-02-04 21:25:3315#include <vector>
[email protected]77848d12008-11-14 00:00:2216
[email protected]68bf9152008-09-25 19:47:3017#include "base/compiler_specific.h"
[email protected]57999812013-02-24 05:40:5218#include "base/files/file_path.h"
thestigd8df0332014-09-04 06:33:2919#include "base/files/file_util.h"
[email protected]f3da152d2012-06-02 01:00:5720#include "base/json/json_writer.h"
Adam Rice425cf122015-01-19 06:18:2421#include "base/logging.h"
Avi Drissman13fc8932015-12-20 04:40:4622#include "base/macros.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"
Bence Békyd74f4382018-02-20 18:26:1926#include "base/strings/string_piece.h"
[email protected]125ef482013-06-11 18:32:4727#include "base/strings/string_util.h"
[email protected]750b2f3c2013-06-07 18:41:0528#include "base/strings/utf_string_conversions.h"
[email protected]f36a8132011-09-02 18:36:3329#include "base/test/test_file_util.h"
gabf767595f2016-05-11 18:50:3530#include "base/threading/thread_task_runner_handle.h"
[email protected]277d5942010-08-11 21:02:3531#include "net/base/auth.h"
mmenkecbc2b712014-10-09 20:29:0732#include "net/base/chunked_upload_data_stream.h"
[email protected]bacff652009-03-31 17:50:3333#include "net/base/completion_callback.h"
Bence Békya25e3f72018-02-13 21:13:3934#include "net/base/completion_once_callback.h"
mmenkecbc2b712014-10-09 20:29:0735#include "net/base/elements_upload_data_stream.h"
[email protected]58e32bb2013-01-21 18:23:2536#include "net/base/load_timing_info.h"
37#include "net/base/load_timing_info_test_util.h"
Adam Rice425cf122015-01-19 06:18:2438#include "net/base/net_errors.h"
tbansal28e68f82016-02-04 02:56:1539#include "net/base/proxy_delegate.h"
Lily Houghton582d4622018-01-22 22:43:4040#include "net/base/proxy_server.h"
[email protected]ac790b42009-12-02 04:31:3141#include "net/base/request_priority.h"
initial.commit586acc5fe2008-07-26 22:42:5242#include "net/base/test_completion_callback.h"
tbansal28e68f82016-02-04 02:56:1543#include "net/base/test_proxy_delegate.h"
[email protected]b2d26cfd2012-12-11 10:36:0644#include "net/base/upload_bytes_element_reader.h"
[email protected]d98961652012-09-11 20:27:2145#include "net/base/upload_file_element_reader.h"
Bence Béky230ac612017-08-30 19:17:0846#include "net/cert/cert_status_flags.h"
[email protected]6e7845ae2013-03-29 21:48:1147#include "net/cert/mock_cert_verifier.h"
[email protected]bc71b8772013-04-10 20:55:1648#include "net/dns/host_cache.h"
[email protected]f2cb3cf2013-03-21 01:40:5349#include "net/dns/mock_host_resolver.h"
[email protected]df41d0d82014-03-13 00:43:2450#include "net/http/http_auth_challenge_tokenizer.h"
[email protected]3c32c5f2010-05-18 15:18:1251#include "net/http/http_auth_handler_digest.h"
[email protected]3fd9dae2010-06-21 11:39:0052#include "net/http/http_auth_handler_mock.h"
[email protected]385a4672009-03-11 22:21:2953#include "net/http/http_auth_handler_ntlm.h"
aberentbba302d2015-12-03 10:20:1954#include "net/http/http_auth_scheme.h"
[email protected]0877e3d2009-10-17 22:29:5755#include "net/http/http_basic_stream.h"
initial.commit586acc5fe2008-07-26 22:42:5256#include "net/http/http_network_session.h"
[email protected]87bfa3f2010-09-30 14:54:5657#include "net/http/http_network_session_peer.h"
Adam Rice425cf122015-01-19 06:18:2458#include "net/http/http_request_headers.h"
mmenke5f94fda2016-06-02 20:54:1359#include "net/http/http_response_info.h"
[email protected]17291a022011-10-10 07:32:5360#include "net/http/http_server_properties_impl.h"
[email protected]0877e3d2009-10-17 22:29:5761#include "net/http/http_stream.h"
[email protected]8e6441ca2010-08-19 05:56:3862#include "net/http/http_stream_factory.h"
[email protected]c41737d2014-05-14 07:47:1963#include "net/http/http_transaction_test_util.h"
eroman87c53d62015-04-02 06:51:0764#include "net/log/net_log.h"
mikecirone8b85c432016-09-08 19:11:0065#include "net/log/net_log_event_type.h"
mikecironef22f9812016-10-04 03:40:1966#include "net/log/net_log_source.h"
vishal.b62985ca92015-04-17 08:45:5167#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4668#include "net/log/test_net_log_entry.h"
69#include "net/log/test_net_log_util.h"
Lily Houghton582d4622018-01-22 22:43:4070#include "net/proxy_resolution/mock_proxy_resolver.h"
71#include "net/proxy_resolution/proxy_config_service_fixed.h"
72#include "net/proxy_resolution/proxy_info.h"
Lily Houghtonffe89daa02018-03-09 18:30:0373#include "net/proxy_resolution/proxy_resolution_service.h"
Lily Houghton582d4622018-01-22 22:43:4074#include "net/proxy_resolution/proxy_resolver.h"
75#include "net/proxy_resolution/proxy_resolver_factory.h"
[email protected]f7984fc62009-06-22 23:26:4476#include "net/socket/client_socket_factory.h"
mmenked3641e12016-01-28 16:06:1577#include "net/socket/client_socket_pool.h"
[email protected]483fa202013-05-14 01:07:0378#include "net/socket/client_socket_pool_manager.h"
ttuttle1f2d7e92015-04-28 16:17:4779#include "net/socket/connection_attempts.h"
[email protected]a42dbd142011-11-17 16:42:0280#include "net/socket/mock_client_socket_pool_manager.h"
[email protected]bb88e1d32013-05-03 23:11:0781#include "net/socket/next_proto.h"
Paul Jensena457017a2018-01-19 23:52:0482#include "net/socket/socket_tag.h"
[email protected]f7984fc62009-06-22 23:26:4483#include "net/socket/socket_test_util.h"
84#include "net/socket/ssl_client_socket.h"
Bence Béky94658bf2018-05-11 19:22:5885#include "net/spdy/spdy_session.h"
86#include "net/spdy/spdy_session_pool.h"
87#include "net/spdy/spdy_test_util_common.h"
nharperb7441ef2016-01-25 23:54:1488#include "net/ssl/default_channel_id_store.h"
[email protected]536fd0b2013-03-14 17:41:5789#include "net/ssl/ssl_cert_request_info.h"
[email protected]e86839fd2013-08-14 18:29:0390#include "net/ssl/ssl_config_service.h"
[email protected]536fd0b2013-03-14 17:41:5791#include "net/ssl/ssl_info.h"
svaldez7872fd02015-11-19 21:10:5492#include "net/ssl/ssl_private_key.h"
[email protected]6e7845ae2013-03-29 21:48:1193#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:0194#include "net/test/gtest_util.h"
rsleevia69c79a2016-06-22 03:28:4395#include "net/test/test_data_directory.h"
Bence Béky98447b12018-05-08 03:14:0196#include "net/test/test_with_scoped_task_environment.h"
Ryan Hamilton2e003eea2018-05-02 00:24:2997#include "net/third_party/spdy/core/spdy_framer.h"
[email protected]baee31a2018-01-18 06:10:2398#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
[email protected]831e4a32013-11-14 02:14:4499#include "net/websockets/websocket_handshake_stream_base.h"
Bence Békydca6bd92018-01-30 13:43:06100#include "net/websockets/websocket_test_util.h"
bncf4588402015-11-24 13:33:18101#include "testing/gmock/include/gmock/gmock.h"
initial.commit586acc5fe2008-07-26 22:42:52102#include "testing/gtest/include/gtest/gtest.h"
[email protected]23887f04f2008-12-02 19:20:15103#include "testing/platform_test.h"
[email protected]795cbf82013-07-22 09:37:27104#include "url/gurl.h"
initial.commit586acc5fe2008-07-26 22:42:52105
Zentaro Kavanagh5b27a6e22017-09-25 23:00:37106#if defined(NTLM_PORTABLE)
107#include "base/base64.h"
108#include "net/ntlm/ntlm_test_data.h"
109#endif
110
robpercival214763f2016-07-01 23:27:01111using net::test::IsError;
112using net::test::IsOk;
113
[email protected]ad65a3e2013-12-25 18:18:01114using base::ASCIIToUTF16;
115
initial.commit586acc5fe2008-07-26 22:42:52116//-----------------------------------------------------------------------------
117
ttuttle859dc7a2015-04-23 19:42:29118namespace net {
119
[email protected]13c8a092010-07-29 06:15:44120namespace {
121
[email protected]42cba2fb2013-03-29 19:58:57122const base::string16 kBar(ASCIIToUTF16("bar"));
123const base::string16 kBar2(ASCIIToUTF16("bar2"));
124const base::string16 kBar3(ASCIIToUTF16("bar3"));
125const base::string16 kBaz(ASCIIToUTF16("baz"));
126const base::string16 kFirst(ASCIIToUTF16("first"));
127const base::string16 kFoo(ASCIIToUTF16("foo"));
128const base::string16 kFoo2(ASCIIToUTF16("foo2"));
129const base::string16 kFoo3(ASCIIToUTF16("foo3"));
130const base::string16 kFou(ASCIIToUTF16("fou"));
131const base::string16 kSecond(ASCIIToUTF16("second"));
[email protected]42cba2fb2013-03-29 19:58:57132const base::string16 kWrongPassword(ASCIIToUTF16("wrongpassword"));
[email protected]13c8a092010-07-29 06:15:44133
bnc2df4b522016-07-08 18:17:43134const char kAlternativeServiceHttpHeader[] =
135 "Alt-Svc: h2=\"mail.example.org:443\"\r\n";
136
ttuttle859dc7a2015-04-23 19:42:29137int GetIdleSocketCountInTransportSocketPool(HttpNetworkSession* session) {
138 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
139 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02140}
141
ttuttle859dc7a2015-04-23 19:42:29142int GetIdleSocketCountInSSLSocketPool(HttpNetworkSession* session) {
143 return session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
144 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02145}
146
ttuttle859dc7a2015-04-23 19:42:29147bool IsTransportSocketPoolStalled(HttpNetworkSession* session) {
148 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
149 ->IsStalled();
[email protected]043b68c82013-08-22 23:41:52150}
151
[email protected]f3da152d2012-06-02 01:00:57152// Takes in a Value created from a NetLogHttpResponseParameter, and returns
153// a JSONified list of headers as a single string. Uses single quotes instead
154// of double quotes for easier comparison. Returns false on failure.
[email protected]ea5ef4c2013-06-13 22:50:27155bool GetHeaders(base::DictionaryValue* params, std::string* headers) {
[email protected]f3da152d2012-06-02 01:00:57156 if (!params)
157 return false;
[email protected]ea5ef4c2013-06-13 22:50:27158 base::ListValue* header_list;
[email protected]f3da152d2012-06-02 01:00:57159 if (!params->GetList("headers", &header_list))
160 return false;
161 std::string double_quote_headers;
estade8d046462015-05-16 01:02:34162 base::JSONWriter::Write(*header_list, &double_quote_headers);
[email protected]466c9862013-12-03 22:05:28163 base::ReplaceChars(double_quote_headers, "\"", "'", headers);
[email protected]f3da152d2012-06-02 01:00:57164 return true;
165}
166
[email protected]029c83b62013-01-24 05:28:20167// Tests LoadTimingInfo in the case a socket is reused and no PAC script is
168// used.
ttuttle859dc7a2015-04-23 19:42:29169void TestLoadTimingReused(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20170 EXPECT_TRUE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19171 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]58e32bb2013-01-21 18:23:25172
[email protected]029c83b62013-01-24 05:28:20173 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
174 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
175
ttuttle859dc7a2015-04-23 19:42:29176 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20177 EXPECT_FALSE(load_timing_info.send_start.is_null());
[email protected]58e32bb2013-01-21 18:23:25178
179 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]58e32bb2013-01-21 18:23:25180
[email protected]3b23a222013-05-15 21:33:25181 // Set at a higher level.
[email protected]58e32bb2013-01-21 18:23:25182 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
183 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25184 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25185}
186
[email protected]029c83b62013-01-24 05:28:20187// Tests LoadTimingInfo in the case a new socket is used and no PAC script is
188// used.
ttuttle859dc7a2015-04-23 19:42:29189void TestLoadTimingNotReused(const LoadTimingInfo& load_timing_info,
[email protected]58e32bb2013-01-21 18:23:25190 int connect_timing_flags) {
[email protected]029c83b62013-01-24 05:28:20191 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19192 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20193
194 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
195 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
196
ttuttle859dc7a2015-04-23 19:42:29197 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
198 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20199 EXPECT_LE(load_timing_info.connect_timing.connect_end,
200 load_timing_info.send_start);
201
202 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20203
[email protected]3b23a222013-05-15 21:33:25204 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20205 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
206 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25207 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20208}
209
210// Tests LoadTimingInfo in the case a socket is reused and a PAC script is
211// used.
ttuttle859dc7a2015-04-23 19:42:29212void TestLoadTimingReusedWithPac(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20213 EXPECT_TRUE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19214 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20215
ttuttle859dc7a2015-04-23 19:42:29216 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20217
218 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
219 EXPECT_LE(load_timing_info.proxy_resolve_start,
220 load_timing_info.proxy_resolve_end);
221 EXPECT_LE(load_timing_info.proxy_resolve_end,
222 load_timing_info.send_start);
223 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20224
[email protected]3b23a222013-05-15 21:33:25225 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20226 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
227 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25228 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20229}
230
231// Tests LoadTimingInfo in the case a new socket is used and a PAC script is
232// used.
ttuttle859dc7a2015-04-23 19:42:29233void TestLoadTimingNotReusedWithPac(const LoadTimingInfo& load_timing_info,
[email protected]029c83b62013-01-24 05:28:20234 int connect_timing_flags) {
235 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19236 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20237
238 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
239 EXPECT_LE(load_timing_info.proxy_resolve_start,
240 load_timing_info.proxy_resolve_end);
241 EXPECT_LE(load_timing_info.proxy_resolve_end,
242 load_timing_info.connect_timing.connect_start);
ttuttle859dc7a2015-04-23 19:42:29243 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
244 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20245 EXPECT_LE(load_timing_info.connect_timing.connect_end,
246 load_timing_info.send_start);
247
248 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20249
[email protected]3b23a222013-05-15 21:33:25250 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20251 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
252 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25253 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25254}
255
danakj1fd259a02016-04-16 03:17:09256std::unique_ptr<HttpNetworkSession> CreateSession(
mmenkee65e7af2015-10-13 17:16:42257 SpdySessionDependencies* session_deps) {
[email protected]c6bf8152012-12-02 07:43:34258 return SpdySessionDependencies::SpdyCreateSession(session_deps);
[email protected]e8d536192008-10-17 22:21:14259}
260
xunjieli96f2a402017-06-05 17:24:27261class FailingProxyResolverFactory : public ProxyResolverFactory {
262 public:
263 FailingProxyResolverFactory() : ProxyResolverFactory(false) {}
264
265 // ProxyResolverFactory override.
Lily Houghton99597862018-03-07 16:40:42266 int CreateProxyResolver(const scoped_refptr<PacFileData>& script_data,
267 std::unique_ptr<ProxyResolver>* result,
Bence Békycc5b88a2018-05-25 20:24:17268 CompletionOnceCallback callback,
Lily Houghton99597862018-03-07 16:40:42269 std::unique_ptr<Request>* request) override {
xunjieli96f2a402017-06-05 17:24:27270 return ERR_PAC_SCRIPT_FAILED;
271 }
272};
273
David Benjamin5cb91132018-04-06 05:54:49274class TestSSLConfigService : public SSLConfigService {
275 public:
276 explicit TestSSLConfigService(const SSLConfig& config) : config_(config) {}
277
278 void GetSSLConfig(SSLConfig* config) override { *config = config_; }
279
280 private:
281 ~TestSSLConfigService() override = default;
282
283 SSLConfig config_;
284};
285
[email protected]448d4ca52012-03-04 04:12:23286} // namespace
287
Bence Béky98447b12018-05-08 03:14:01288class HttpNetworkTransactionTest : public PlatformTest,
289 public WithScopedTaskEnvironment {
[email protected]483fa202013-05-14 01:07:03290 public:
bncd16676a2016-07-20 16:23:01291 ~HttpNetworkTransactionTest() override {
[email protected]483fa202013-05-14 01:07:03292 // Important to restore the per-pool limit first, since the pool limit must
293 // always be greater than group limit, and the tests reduce both limits.
294 ClientSocketPoolManager::set_max_sockets_per_pool(
295 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
296 ClientSocketPoolManager::set_max_sockets_per_group(
297 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
298 }
299
[email protected]e3ceb682011-06-28 23:55:46300 protected:
[email protected]23e482282013-06-14 16:08:02301 HttpNetworkTransactionTest()
bnc032658ba2016-09-26 18:17:15302 : ssl_(ASYNC, OK),
303 old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
[email protected]483fa202013-05-14 01:07:03304 HttpNetworkSession::NORMAL_SOCKET_POOL)),
305 old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
306 HttpNetworkSession::NORMAL_SOCKET_POOL)) {
bnca86731e2017-04-17 12:31:28307 session_deps_.enable_http2_alternative_service = true;
[email protected]483fa202013-05-14 01:07:03308 }
[email protected]bb88e1d32013-05-03 23:11:07309
[email protected]e3ceb682011-06-28 23:55:46310 struct SimpleGetHelperResult {
311 int rv;
312 std::string status_line;
313 std::string response_data;
sclittlefb249892015-09-10 21:33:22314 int64_t total_received_bytes;
315 int64_t total_sent_bytes;
[email protected]58e32bb2013-01-21 18:23:25316 LoadTimingInfo load_timing_info;
ttuttle1f2d7e92015-04-28 16:17:47317 ConnectionAttempts connection_attempts;
ttuttled9dbc652015-09-29 20:00:59318 IPEndPoint remote_endpoint_after_start;
[email protected]e3ceb682011-06-28 23:55:46319 };
320
dcheng67be2b1f2014-10-27 21:47:29321 void SetUp() override {
[email protected]0b0bf032010-09-21 18:08:50322 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55323 base::RunLoop().RunUntilIdle();
[email protected]2ff8b312010-04-26 22:20:54324 }
325
dcheng67be2b1f2014-10-27 21:47:29326 void TearDown() override {
[email protected]0b0bf032010-09-21 18:08:50327 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55328 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09329 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:55330 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09331 PlatformTest::TearDown();
[email protected]0b0bf032010-09-21 18:08:50332 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55333 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09334 }
335
[email protected]202965992011-12-07 23:04:51336 // Either |write_failure| specifies a write failure or |read_failure|
337 // specifies a read failure when using a reused socket. In either case, the
338 // failure should cause the network transaction to resend the request, and the
339 // other argument should be NULL.
340 void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
341 const MockRead* read_failure);
initial.commit586acc5fe2008-07-26 22:42:52342
[email protected]a34f61ee2014-03-18 20:59:49343 // Either |write_failure| specifies a write failure or |read_failure|
344 // specifies a read failure when using a reused socket. In either case, the
345 // failure should cause the network transaction to resend the request, and the
346 // other argument should be NULL.
347 void PreconnectErrorResendRequestTest(const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:10348 const MockRead* read_failure,
349 bool use_spdy);
[email protected]a34f61ee2014-03-18 20:59:49350
Ryan Sleevib8d7ea02018-05-07 20:01:01351 SimpleGetHelperResult SimpleGetHelperForData(
352 base::span<StaticSocketDataProvider*> providers) {
[email protected]ff007e162009-05-23 09:13:15353 SimpleGetHelperResult out;
initial.commit586acc5fe2008-07-26 22:42:52354
[email protected]ff007e162009-05-23 09:13:15355 HttpRequestInfo request;
356 request.method = "GET";
bncce36dca22015-04-21 22:11:23357 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:10358 request.traffic_annotation =
359 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:52360
vishal.b62985ca92015-04-17 08:45:51361 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:07362 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:09363 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16364 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:27365
Ryan Sleevib8d7ea02018-05-07 20:01:01366 for (auto* provider : providers) {
367 session_deps_.socket_factory->AddSocketDataProvider(provider);
[email protected]5a60c8b2011-10-19 20:14:29368 }
initial.commit586acc5fe2008-07-26 22:42:52369
[email protected]49639fa2011-12-20 23:22:41370 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52371
eroman24bc6a12015-05-06 19:55:48372 EXPECT_TRUE(log.bound().IsCapturing());
bnc691fda62016-08-12 00:43:16373 int rv = trans.Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:01374 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:52375
[email protected]ff007e162009-05-23 09:13:15376 out.rv = callback.WaitForResult();
bnc691fda62016-08-12 00:43:16377 out.total_received_bytes = trans.GetTotalReceivedBytes();
378 out.total_sent_bytes = trans.GetTotalSentBytes();
[email protected]58e32bb2013-01-21 18:23:25379
380 // Even in the failure cases that use this function, connections are always
381 // successfully established before the error.
bnc691fda62016-08-12 00:43:16382 EXPECT_TRUE(trans.GetLoadTimingInfo(&out.load_timing_info));
[email protected]58e32bb2013-01-21 18:23:25383 TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
384
[email protected]ff007e162009-05-23 09:13:15385 if (out.rv != OK)
386 return out;
387
bnc691fda62016-08-12 00:43:16388 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50389 // Can't use ASSERT_* inside helper functions like this, so
390 // return an error.
wezca1070932016-05-26 20:30:52391 if (!response || !response->headers) {
[email protected]fe2255a2011-09-20 19:37:50392 out.rv = ERR_UNEXPECTED;
393 return out;
394 }
[email protected]ff007e162009-05-23 09:13:15395 out.status_line = response->headers->GetStatusLine();
396
[email protected]80a09a82012-11-16 17:40:06397 EXPECT_EQ("127.0.0.1", response->socket_address.host());
398 EXPECT_EQ(80, response->socket_address.port());
[email protected]6d81b482011-02-22 19:47:19399
ttuttled9dbc652015-09-29 20:00:59400 bool got_endpoint =
bnc691fda62016-08-12 00:43:16401 trans.GetRemoteEndpoint(&out.remote_endpoint_after_start);
ttuttled9dbc652015-09-29 20:00:59402 EXPECT_EQ(got_endpoint,
403 out.remote_endpoint_after_start.address().size() > 0);
404
bnc691fda62016-08-12 00:43:16405 rv = ReadTransaction(&trans, &out.response_data);
robpercival214763f2016-07-01 23:27:01406 EXPECT_THAT(rv, IsOk());
[email protected]b2fcd0e2010-12-01 15:19:40407
mmenke43758e62015-05-04 21:09:46408 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40409 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:39410 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00411 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
412 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:39413 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00414 entries, pos, NetLogEventType::HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
415 NetLogEventPhase::NONE);
[email protected]ff007e162009-05-23 09:13:15416
[email protected]f3da152d2012-06-02 01:00:57417 std::string line;
418 EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
419 EXPECT_EQ("GET / HTTP/1.1\r\n", line);
420
[email protected]79e1fd62013-06-20 06:50:04421 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:16422 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:04423 std::string value;
424 EXPECT_TRUE(request_headers.GetHeader("Host", &value));
bncce36dca22015-04-21 22:11:23425 EXPECT_EQ("www.example.org", value);
[email protected]79e1fd62013-06-20 06:50:04426 EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
427 EXPECT_EQ("keep-alive", value);
428
429 std::string response_headers;
430 EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
bncce36dca22015-04-21 22:11:23431 EXPECT_EQ("['Host: www.example.org','Connection: keep-alive']",
[email protected]79e1fd62013-06-20 06:50:04432 response_headers);
[email protected]3deb9a52010-11-11 00:24:40433
bnc691fda62016-08-12 00:43:16434 out.total_received_bytes = trans.GetTotalReceivedBytes();
sclittlefb249892015-09-10 21:33:22435 // The total number of sent bytes should not have changed.
bnc691fda62016-08-12 00:43:16436 EXPECT_EQ(out.total_sent_bytes, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:22437
bnc691fda62016-08-12 00:43:16438 trans.GetConnectionAttempts(&out.connection_attempts);
[email protected]aecfbf22008-10-16 02:02:47439 return out;
[email protected]ff007e162009-05-23 09:13:15440 }
initial.commit586acc5fe2008-07-26 22:42:52441
Ryan Sleevib8d7ea02018-05-07 20:01:01442 SimpleGetHelperResult SimpleGetHelper(base::span<const MockRead> data_reads) {
sclittlefb249892015-09-10 21:33:22443 MockWrite data_writes[] = {
444 MockWrite("GET / HTTP/1.1\r\n"
445 "Host: www.example.org\r\n"
446 "Connection: keep-alive\r\n\r\n"),
447 };
[email protected]5a60c8b2011-10-19 20:14:29448
Ryan Sleevib8d7ea02018-05-07 20:01:01449 StaticSocketDataProvider reads(data_reads, data_writes);
sclittlefb249892015-09-10 21:33:22450 StaticSocketDataProvider* data[] = {&reads};
Ryan Sleevib8d7ea02018-05-07 20:01:01451 SimpleGetHelperResult out = SimpleGetHelperForData(data);
sclittlefb249892015-09-10 21:33:22452
Ryan Sleevib8d7ea02018-05-07 20:01:01453 EXPECT_EQ(CountWriteBytes(data_writes), out.total_sent_bytes);
sclittlefb249892015-09-10 21:33:22454 return out;
[email protected]b8015c42013-12-24 15:18:19455 }
456
bnc032658ba2016-09-26 18:17:15457 void AddSSLSocketData() {
458 ssl_.next_proto = kProtoHTTP2;
Ryan Sleevi4f832092017-11-21 23:25:49459 ssl_.ssl_info.cert =
460 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
461 ASSERT_TRUE(ssl_.ssl_info.cert);
bnc032658ba2016-09-26 18:17:15462 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_);
463 }
464
[email protected]ff007e162009-05-23 09:13:15465 void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
466 int expected_status);
initial.commit586acc5fe2008-07-26 22:42:52467
[email protected]ff007e162009-05-23 09:13:15468 void ConnectStatusHelper(const MockRead& status);
[email protected]bb88e1d32013-05-03 23:11:07469
[email protected]bb88e1d32013-05-03 23:11:07470 void CheckErrorIsPassedBack(int error, IoMode mode);
471
[email protected]4bd46222013-05-14 19:32:23472 SpdyTestUtil spdy_util_;
[email protected]bb88e1d32013-05-03 23:11:07473 SpdySessionDependencies session_deps_;
bnc032658ba2016-09-26 18:17:15474 SSLSocketDataProvider ssl_;
[email protected]483fa202013-05-14 01:07:03475
476 // Original socket limits. Some tests set these. Safest to always restore
477 // them once each test has been run.
478 int old_max_group_sockets_;
479 int old_max_pool_sockets_;
[email protected]ff007e162009-05-23 09:13:15480};
[email protected]231d5a32008-09-13 00:45:27481
[email protected]448d4ca52012-03-04 04:12:23482namespace {
483
ryansturm49a8cb12016-06-15 16:51:09484class BeforeHeadersSentHandler {
[email protected]597a1ab2014-06-26 08:12:27485 public:
ryansturm49a8cb12016-06-15 16:51:09486 BeforeHeadersSentHandler()
487 : observed_before_headers_sent_with_proxy_(false),
488 observed_before_headers_sent_(false) {}
[email protected]597a1ab2014-06-26 08:12:27489
ryansturm49a8cb12016-06-15 16:51:09490 void OnBeforeHeadersSent(const ProxyInfo& proxy_info,
491 HttpRequestHeaders* request_headers) {
492 observed_before_headers_sent_ = true;
493 if (!proxy_info.is_http() && !proxy_info.is_https() &&
494 !proxy_info.is_quic()) {
495 return;
496 }
497 observed_before_headers_sent_with_proxy_ = true;
[email protected]597a1ab2014-06-26 08:12:27498 observed_proxy_server_uri_ = proxy_info.proxy_server().ToURI();
499 }
500
ryansturm49a8cb12016-06-15 16:51:09501 bool observed_before_headers_sent_with_proxy() const {
502 return observed_before_headers_sent_with_proxy_;
503 }
504
505 bool observed_before_headers_sent() const {
506 return observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27507 }
508
509 std::string observed_proxy_server_uri() const {
510 return observed_proxy_server_uri_;
511 }
512
513 private:
ryansturm49a8cb12016-06-15 16:51:09514 bool observed_before_headers_sent_with_proxy_;
515 bool observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27516 std::string observed_proxy_server_uri_;
517
ryansturm49a8cb12016-06-15 16:51:09518 DISALLOW_COPY_AND_ASSIGN(BeforeHeadersSentHandler);
[email protected]597a1ab2014-06-26 08:12:27519};
520
[email protected]15a5ccf82008-10-23 19:57:43521// Fill |str| with a long header list that consumes >= |size| bytes.
522void FillLargeHeadersString(std::string* str, int size) {
thestig9d3bb0c2015-01-24 00:49:51523 const char row[] =
[email protected]4ddaf2502008-10-23 18:26:19524 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
525 const int sizeof_row = strlen(row);
526 const int num_rows = static_cast<int>(
527 ceil(static_cast<float>(size) / sizeof_row));
528 const int sizeof_data = num_rows * sizeof_row;
529 DCHECK(sizeof_data >= size);
[email protected]15a5ccf82008-10-23 19:57:43530 str->reserve(sizeof_data);
[email protected]372d34a2008-11-05 21:30:51531
[email protected]4ddaf2502008-10-23 18:26:19532 for (int i = 0; i < num_rows; ++i)
[email protected]15a5ccf82008-10-23 19:57:43533 str->append(row, sizeof_row);
[email protected]4ddaf2502008-10-23 18:26:19534}
535
thakis84dff942015-07-28 20:47:38536#if defined(NTLM_PORTABLE)
Zentaro Kavanagh6ccee512017-09-28 18:34:09537uint64_t MockGetMSTime() {
538 // Tue, 23 May 2017 20:13:07 +0000
539 return 131400439870000000;
540}
541
[email protected]385a4672009-03-11 22:21:29542// Alternative functions that eliminate randomness and dependency on the local
543// host name so that the generated NTLM messages are reproducible.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:37544void MockGenerateRandom(uint8_t* output, size_t n) {
545 // This is set to 0xaa because the client challenge for testing in
546 // [MS-NLMP] Section 4.2.1 is 8 bytes of 0xaa.
547 memset(output, 0xaa, n);
[email protected]385a4672009-03-11 22:21:29548}
549
[email protected]fe2bc6a2009-03-23 16:52:20550std::string MockGetHostName() {
Zentaro Kavanagh5b27a6e22017-09-25 23:00:37551 return ntlm::test::kHostnameAscii;
[email protected]385a4672009-03-11 22:21:29552}
thakis84dff942015-07-28 20:47:38553#endif // defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29554
[email protected]e60e47a2010-07-14 03:37:18555template<typename ParentPool>
556class CaptureGroupNameSocketPool : public ParentPool {
[email protected]04e5be32009-06-26 20:00:31557 public:
[email protected]9e1bdd32011-02-03 21:48:34558 CaptureGroupNameSocketPool(HostResolver* host_resolver,
559 CertVerifier* cert_verifier);
[email protected]e60e47a2010-07-14 03:37:18560
[email protected]d80a4322009-08-14 07:07:49561 const std::string last_group_name_received() const {
562 return last_group_name_;
563 }
564
Tarun Bansal162eabe52018-01-20 01:16:39565 bool socket_requested() const { return socket_requested_; }
566
dmichaeld6e570d2014-12-18 22:30:57567 int RequestSocket(const std::string& group_name,
568 const void* socket_params,
569 RequestPriority priority,
Paul Jensen8d6f87ec2018-01-13 00:46:54570 const SocketTag& socket_tag,
mmenked3641e12016-01-28 16:06:15571 ClientSocketPool::RespectLimits respect_limits,
dmichaeld6e570d2014-12-18 22:30:57572 ClientSocketHandle* handle,
573 const CompletionCallback& callback,
tfarina42834112016-09-22 13:38:20574 const NetLogWithSource& net_log) override {
[email protected]04e5be32009-06-26 20:00:31575 last_group_name_ = group_name;
Tarun Bansal162eabe52018-01-20 01:16:39576 socket_requested_ = true;
[email protected]04e5be32009-06-26 20:00:31577 return ERR_IO_PENDING;
578 }
dmichaeld6e570d2014-12-18 22:30:57579 void CancelRequest(const std::string& group_name,
580 ClientSocketHandle* handle) override {}
581 void ReleaseSocket(const std::string& group_name,
danakj1fd259a02016-04-16 03:17:09582 std::unique_ptr<StreamSocket> socket,
dmichaeld6e570d2014-12-18 22:30:57583 int id) override {}
584 void CloseIdleSockets() override {}
xunjieli92feb332017-03-03 17:19:23585 void CloseIdleSocketsInGroup(const std::string& group_name) override {}
dmichaeld6e570d2014-12-18 22:30:57586 int IdleSocketCount() const override { return 0; }
587 int IdleSocketCountInGroup(const std::string& group_name) const override {
[email protected]04e5be32009-06-26 20:00:31588 return 0;
589 }
dmichaeld6e570d2014-12-18 22:30:57590 LoadState GetLoadState(const std::string& group_name,
591 const ClientSocketHandle* handle) const override {
[email protected]04e5be32009-06-26 20:00:31592 return LOAD_STATE_IDLE;
593 }
dmichaeld6e570d2014-12-18 22:30:57594 base::TimeDelta ConnectionTimeout() const override {
[email protected]a796bcec2010-03-22 17:17:26595 return base::TimeDelta();
596 }
[email protected]d80a4322009-08-14 07:07:49597
598 private:
[email protected]04e5be32009-06-26 20:00:31599 std::string last_group_name_;
Tarun Bansal162eabe52018-01-20 01:16:39600 bool socket_requested_ = false;
[email protected]04e5be32009-06-26 20:00:31601};
602
[email protected]ab739042011-04-07 15:22:28603typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
604CaptureGroupNameTransportSocketPool;
[email protected]e772db3f2010-07-12 18:11:13605typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
606CaptureGroupNameHttpProxySocketPool;
[email protected]2d731a32010-04-29 01:04:06607typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
[email protected]2227c692010-05-04 15:36:11608CaptureGroupNameSOCKSSocketPool;
[email protected]e60e47a2010-07-14 03:37:18609typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
610CaptureGroupNameSSLSocketPool;
611
rkaplowd90695c2015-03-25 22:12:41612template <typename ParentPool>
[email protected]e60e47a2010-07-14 03:37:18613CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34614 HostResolver* host_resolver,
615 CertVerifier* /* cert_verifier */)
tbansal7b403bcc2016-04-13 22:33:21616 : ParentPool(0, 0, host_resolver, NULL, NULL, NULL) {}
[email protected]e60e47a2010-07-14 03:37:18617
hashimoto0d3e4fb2015-01-09 05:02:50618template <>
[email protected]2df19bb2010-08-25 20:13:46619CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21620 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34621 CertVerifier* /* cert_verifier */)
tbansal16196a1e2017-06-09 01:50:09622 : HttpProxyClientSocketPool(0, 0, NULL, NULL, NULL, NULL) {}
[email protected]2df19bb2010-08-25 20:13:46623
[email protected]007b3f82013-04-09 08:46:45624template <>
[email protected]e60e47a2010-07-14 03:37:18625CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21626 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34627 CertVerifier* cert_verifier)
[email protected]007b3f82013-04-09 08:46:45628 : SSLClientSocketPool(0,
629 0,
[email protected]007b3f82013-04-09 08:46:45630 cert_verifier,
631 NULL,
632 NULL,
[email protected]284303b62013-11-28 15:11:54633 NULL,
eranm6571b2b2014-12-03 15:53:23634 NULL,
[email protected]007b3f82013-04-09 08:46:45635 std::string(),
636 NULL,
637 NULL,
638 NULL,
639 NULL,
640 NULL,
[email protected]8e458552014-08-05 00:02:15641 NULL) {
642}
[email protected]2227c692010-05-04 15:36:11643
[email protected]231d5a32008-09-13 00:45:27644//-----------------------------------------------------------------------------
645
[email protected]79cb5c12011-09-12 13:12:04646// Helper functions for validating that AuthChallengeInfo's are correctly
647// configured for common cases.
648bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
649 if (!auth_challenge)
650 return false;
651 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43652 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04653 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19654 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04655 return true;
656}
657
658bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
659 if (!auth_challenge)
660 return false;
661 EXPECT_TRUE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43662 EXPECT_EQ("http://myproxy:70", auth_challenge->challenger.Serialize());
663 EXPECT_EQ("MyRealm1", auth_challenge->realm);
664 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
665 return true;
666}
667
668bool CheckBasicSecureProxyAuth(const AuthChallengeInfo* auth_challenge) {
669 if (!auth_challenge)
670 return false;
671 EXPECT_TRUE(auth_challenge->is_proxy);
672 EXPECT_EQ("https://myproxy:70", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04673 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19674 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04675 return true;
676}
677
678bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
679 if (!auth_challenge)
680 return false;
681 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43682 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04683 EXPECT_EQ("digestive", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19684 EXPECT_EQ(kDigestAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04685 return true;
686}
687
thakis84dff942015-07-28 20:47:38688#if defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04689bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
690 if (!auth_challenge)
691 return false;
692 EXPECT_FALSE(auth_challenge->is_proxy);
Zentaro Kavanagh1890a3d2018-01-29 19:52:55693 EXPECT_EQ("https://server", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04694 EXPECT_EQ(std::string(), auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19695 EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04696 return true;
697}
David Benjamin5cb91132018-04-06 05:54:49698
699bool CheckNTLMProxyAuth(const AuthChallengeInfo* auth_challenge) {
700 if (!auth_challenge)
701 return false;
702 EXPECT_TRUE(auth_challenge->is_proxy);
703 EXPECT_EQ("http://server", auth_challenge->challenger.Serialize());
704 EXPECT_EQ(std::string(), auth_challenge->realm);
705 EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
706 return true;
707}
thakis84dff942015-07-28 20:47:38708#endif // defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04709
[email protected]448d4ca52012-03-04 04:12:23710} // namespace
711
bncd16676a2016-07-20 16:23:01712TEST_F(HttpNetworkTransactionTest, Basic) {
danakj1fd259a02016-04-16 03:17:09713 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16714 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]231d5a32008-09-13 00:45:27715}
716
bncd16676a2016-07-20 16:23:01717TEST_F(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27718 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35719 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
720 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06721 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27722 };
Ryan Sleevib8d7ea02018-05-07 20:01:01723 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01724 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27725 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
726 EXPECT_EQ("hello world", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01727 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22728 EXPECT_EQ(reads_size, out.total_received_bytes);
ttuttle1f2d7e92015-04-28 16:17:47729 EXPECT_EQ(0u, out.connection_attempts.size());
ttuttled9dbc652015-09-29 20:00:59730
731 EXPECT_FALSE(out.remote_endpoint_after_start.address().empty());
[email protected]231d5a32008-09-13 00:45:27732}
733
734// Response with no status line.
bncd16676a2016-07-20 16:23:01735TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27736 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35737 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06738 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27739 };
Ryan Sleevib8d7ea02018-05-07 20:01:01740 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41741 EXPECT_THAT(out.rv, IsOk());
742 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
743 EXPECT_EQ("hello world", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01744 int64_t reads_size = CountReadBytes(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41745 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27746}
747
mmenkea7da6da2016-09-01 21:56:52748// Response with no status line, and a weird port. Should fail by default.
749TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPort) {
750 MockRead data_reads[] = {
751 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
752 };
753
Ryan Sleevib8d7ea02018-05-07 20:01:01754 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
mmenkea7da6da2016-09-01 21:56:52755 session_deps_.socket_factory->AddSocketDataProvider(&data);
756
757 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
758
krasinc06a72a2016-12-21 03:42:46759 HttpRequestInfo request;
bnc87dcefc2017-05-25 12:47:58760 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:19761 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenkea7da6da2016-09-01 21:56:52762
mmenkea7da6da2016-09-01 21:56:52763 request.method = "GET";
764 request.url = GURL("http://www.example.com:2000/");
Ramin Halavatib5e433e62018-02-07 07:41:10765 request.traffic_annotation =
766 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
767
mmenkea7da6da2016-09-01 21:56:52768 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20769 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52770 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_INVALID_HTTP_RESPONSE));
771}
772
Shivani Sharmafdcaefd2017-11-02 00:12:26773// Tests that request info can be destroyed after the headers phase is complete.
774TEST_F(HttpNetworkTransactionTest, SimpleGETNoReadDestroyRequestInfo) {
775 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
776 auto trans =
777 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
778
779 MockRead data_reads[] = {
780 MockRead("HTTP/1.0 200 OK\r\n"), MockRead("Connection: keep-alive\r\n"),
781 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, 0),
782 };
Ryan Sleevib8d7ea02018-05-07 20:01:01783 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
Shivani Sharmafdcaefd2017-11-02 00:12:26784 session_deps_.socket_factory->AddSocketDataProvider(&data);
785
786 TestCompletionCallback callback;
787
788 {
789 auto request = std::make_unique<HttpRequestInfo>();
790 request->method = "GET";
791 request->url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:10792 request->traffic_annotation =
793 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Shivani Sharmafdcaefd2017-11-02 00:12:26794
795 int rv =
796 trans->Start(request.get(), callback.callback(), NetLogWithSource());
797
798 EXPECT_THAT(callback.GetResult(rv), IsOk());
799 } // Let request info be destroyed.
800
801 trans.reset();
802}
803
mmenkea7da6da2016-09-01 21:56:52804// Response with no status line, and a weird port. Option to allow weird ports
805// enabled.
806TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPortAllowed) {
807 MockRead data_reads[] = {
808 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
809 };
810
Ryan Sleevib8d7ea02018-05-07 20:01:01811 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
mmenkea7da6da2016-09-01 21:56:52812 session_deps_.socket_factory->AddSocketDataProvider(&data);
813 session_deps_.http_09_on_non_default_ports_enabled = true;
814 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
815
krasinc06a72a2016-12-21 03:42:46816 HttpRequestInfo request;
bnc87dcefc2017-05-25 12:47:58817 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:19818 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenkea7da6da2016-09-01 21:56:52819
mmenkea7da6da2016-09-01 21:56:52820 request.method = "GET";
821 request.url = GURL("http://www.example.com:2000/");
Ramin Halavatib5e433e62018-02-07 07:41:10822 request.traffic_annotation =
823 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
824
mmenkea7da6da2016-09-01 21:56:52825 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20826 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52827 EXPECT_THAT(callback.GetResult(rv), IsOk());
828
829 const HttpResponseInfo* info = trans->GetResponseInfo();
830 ASSERT_TRUE(info->headers);
831 EXPECT_EQ("HTTP/0.9 200 OK", info->headers->GetStatusLine());
832
833 // Don't bother to read the body - that's verified elsewhere, important thing
834 // is that the option to allow HTTP/0.9 on non-default ports is respected.
835}
836
[email protected]231d5a32008-09-13 00:45:27837// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01838TEST_F(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27839 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35840 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06841 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27842 };
Ryan Sleevib8d7ea02018-05-07 20:01:01843 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01844 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27845 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
846 EXPECT_EQ("DATA", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01847 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22848 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27849}
850
851// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01852TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27853 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35854 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06855 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27856 };
Ryan Sleevib8d7ea02018-05-07 20:01:01857 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01858 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27859 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
860 EXPECT_EQ("DATA", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01861 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22862 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27863}
864
865// Beyond 4 bytes of slop and it should fail to find a status line.
bncd16676a2016-07-20 16:23:01866TEST_F(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27867 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35868 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06869 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27870 };
Ryan Sleevib8d7ea02018-05-07 20:01:01871 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41872 EXPECT_THAT(out.rv, IsOk());
873 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
874 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01875 int64_t reads_size = CountReadBytes(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41876 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27877}
878
879// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
bncd16676a2016-07-20 16:23:01880TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27881 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35882 MockRead("\n"),
883 MockRead("\n"),
884 MockRead("Q"),
885 MockRead("J"),
886 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06887 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27888 };
Ryan Sleevib8d7ea02018-05-07 20:01:01889 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01890 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27891 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
892 EXPECT_EQ("DATA", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01893 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22894 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27895}
896
897// Close the connection before enough bytes to have a status line.
bncd16676a2016-07-20 16:23:01898TEST_F(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:27899 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35900 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:06901 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27902 };
Ryan Sleevib8d7ea02018-05-07 20:01:01903 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41904 EXPECT_THAT(out.rv, IsOk());
905 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
906 EXPECT_EQ("HTT", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01907 int64_t reads_size = CountReadBytes(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41908 EXPECT_EQ(reads_size, out.total_received_bytes);
initial.commit586acc5fe2008-07-26 22:42:52909}
910
[email protected]f9d44aa2008-09-23 23:57:17911// Simulate a 204 response, lacking a Content-Length header, sent over a
912// persistent connection. The response should still terminate since a 204
913// cannot have a response body.
bncd16676a2016-07-20 16:23:01914TEST_F(HttpNetworkTransactionTest, StopsReading204) {
[email protected]b8015c42013-12-24 15:18:19915 char junk[] = "junk";
[email protected]f9d44aa2008-09-23 23:57:17916 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35917 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
[email protected]b8015c42013-12-24 15:18:19918 MockRead(junk), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:06919 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:17920 };
Ryan Sleevib8d7ea02018-05-07 20:01:01921 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01922 EXPECT_THAT(out.rv, IsOk());
[email protected]f9d44aa2008-09-23 23:57:17923 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
924 EXPECT_EQ("", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01925 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22926 int64_t response_size = reads_size - strlen(junk);
927 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]f9d44aa2008-09-23 23:57:17928}
929
[email protected]0877e3d2009-10-17 22:29:57930// A simple request using chunked encoding with some extra data after.
bncd16676a2016-07-20 16:23:01931TEST_F(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]b8015c42013-12-24 15:18:19932 std::string final_chunk = "0\r\n\r\n";
933 std::string extra_data = "HTTP/1.1 200 OK\r\n";
934 std::string last_read = final_chunk + extra_data;
[email protected]0877e3d2009-10-17 22:29:57935 MockRead data_reads[] = {
936 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
937 MockRead("5\r\nHello\r\n"),
938 MockRead("1\r\n"),
939 MockRead(" \r\n"),
940 MockRead("5\r\nworld\r\n"),
[email protected]b8015c42013-12-24 15:18:19941 MockRead(last_read.data()),
[email protected]8ddf8322012-02-23 18:08:06942 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:57943 };
Ryan Sleevib8d7ea02018-05-07 20:01:01944 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01945 EXPECT_THAT(out.rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:57946 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
947 EXPECT_EQ("Hello world", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01948 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22949 int64_t response_size = reads_size - extra_data.size();
950 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]0877e3d2009-10-17 22:29:57951}
952
[email protected]9fe44f52010-09-23 18:36:00953// Next tests deal with http://crbug.com/56344.
954
bncd16676a2016-07-20 16:23:01955TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00956 MultipleContentLengthHeadersNoTransferEncoding) {
957 MockRead data_reads[] = {
958 MockRead("HTTP/1.1 200 OK\r\n"),
959 MockRead("Content-Length: 10\r\n"),
960 MockRead("Content-Length: 5\r\n\r\n"),
961 };
Ryan Sleevib8d7ea02018-05-07 20:01:01962 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01963 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]9fe44f52010-09-23 18:36:00964}
965
bncd16676a2016-07-20 16:23:01966TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04967 DuplicateContentLengthHeadersNoTransferEncoding) {
968 MockRead data_reads[] = {
969 MockRead("HTTP/1.1 200 OK\r\n"),
970 MockRead("Content-Length: 5\r\n"),
971 MockRead("Content-Length: 5\r\n\r\n"),
972 MockRead("Hello"),
973 };
Ryan Sleevib8d7ea02018-05-07 20:01:01974 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01975 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:04976 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
977 EXPECT_EQ("Hello", out.response_data);
978}
979
bncd16676a2016-07-20 16:23:01980TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04981 ComplexContentLengthHeadersNoTransferEncoding) {
982 // More than 2 dupes.
983 {
984 MockRead data_reads[] = {
985 MockRead("HTTP/1.1 200 OK\r\n"),
986 MockRead("Content-Length: 5\r\n"),
987 MockRead("Content-Length: 5\r\n"),
988 MockRead("Content-Length: 5\r\n\r\n"),
989 MockRead("Hello"),
990 };
Ryan Sleevib8d7ea02018-05-07 20:01:01991 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01992 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:04993 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
994 EXPECT_EQ("Hello", out.response_data);
995 }
996 // HTTP/1.0
997 {
998 MockRead data_reads[] = {
999 MockRead("HTTP/1.0 200 OK\r\n"),
1000 MockRead("Content-Length: 5\r\n"),
1001 MockRead("Content-Length: 5\r\n"),
1002 MockRead("Content-Length: 5\r\n\r\n"),
1003 MockRead("Hello"),
1004 };
Ryan Sleevib8d7ea02018-05-07 20:01:011005 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011006 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041007 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
1008 EXPECT_EQ("Hello", out.response_data);
1009 }
1010 // 2 dupes and one mismatched.
1011 {
1012 MockRead data_reads[] = {
1013 MockRead("HTTP/1.1 200 OK\r\n"),
1014 MockRead("Content-Length: 10\r\n"),
1015 MockRead("Content-Length: 10\r\n"),
1016 MockRead("Content-Length: 5\r\n\r\n"),
1017 };
Ryan Sleevib8d7ea02018-05-07 20:01:011018 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011019 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]44b52042010-10-29 22:48:041020 }
1021}
1022
bncd16676a2016-07-20 16:23:011023TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001024 MultipleContentLengthHeadersTransferEncoding) {
1025 MockRead data_reads[] = {
1026 MockRead("HTTP/1.1 200 OK\r\n"),
1027 MockRead("Content-Length: 666\r\n"),
1028 MockRead("Content-Length: 1337\r\n"),
1029 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
1030 MockRead("5\r\nHello\r\n"),
1031 MockRead("1\r\n"),
1032 MockRead(" \r\n"),
1033 MockRead("5\r\nworld\r\n"),
1034 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:061035 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:001036 };
Ryan Sleevib8d7ea02018-05-07 20:01:011037 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011038 EXPECT_THAT(out.rv, IsOk());
[email protected]9fe44f52010-09-23 18:36:001039 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1040 EXPECT_EQ("Hello world", out.response_data);
1041}
1042
[email protected]1628fe92011-10-04 23:04:551043// Next tests deal with http://crbug.com/98895.
1044
1045// Checks that a single Content-Disposition header results in no error.
bncd16676a2016-07-20 16:23:011046TEST_F(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:551047 MockRead data_reads[] = {
1048 MockRead("HTTP/1.1 200 OK\r\n"),
1049 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
1050 MockRead("Content-Length: 5\r\n\r\n"),
1051 MockRead("Hello"),
1052 };
Ryan Sleevib8d7ea02018-05-07 20:01:011053 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011054 EXPECT_THAT(out.rv, IsOk());
[email protected]1628fe92011-10-04 23:04:551055 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1056 EXPECT_EQ("Hello", out.response_data);
1057}
1058
[email protected]54a9c6e52012-03-21 20:10:591059// Checks that two identical Content-Disposition headers result in no error.
bncd16676a2016-07-20 16:23:011060TEST_F(HttpNetworkTransactionTest, TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551061 MockRead data_reads[] = {
1062 MockRead("HTTP/1.1 200 OK\r\n"),
1063 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1064 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1065 MockRead("Content-Length: 5\r\n\r\n"),
1066 MockRead("Hello"),
1067 };
Ryan Sleevib8d7ea02018-05-07 20:01:011068 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011069 EXPECT_THAT(out.rv, IsOk());
[email protected]54a9c6e52012-03-21 20:10:591070 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1071 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:551072}
1073
1074// Checks that two distinct Content-Disposition headers result in an error.
bncd16676a2016-07-20 16:23:011075TEST_F(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551076 MockRead data_reads[] = {
1077 MockRead("HTTP/1.1 200 OK\r\n"),
1078 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1079 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
1080 MockRead("Content-Length: 5\r\n\r\n"),
1081 MockRead("Hello"),
1082 };
Ryan Sleevib8d7ea02018-05-07 20:01:011083 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011084 EXPECT_THAT(out.rv,
1085 IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION));
[email protected]1628fe92011-10-04 23:04:551086}
1087
[email protected]54a9c6e52012-03-21 20:10:591088// Checks that two identical Location headers result in no error.
1089// Also tests Location header behavior.
bncd16676a2016-07-20 16:23:011090TEST_F(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551091 MockRead data_reads[] = {
1092 MockRead("HTTP/1.1 302 Redirect\r\n"),
1093 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:591094 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:551095 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061096 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551097 };
1098
1099 HttpRequestInfo request;
1100 request.method = "GET";
1101 request.url = GURL("http://redirect.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101102 request.traffic_annotation =
1103 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1628fe92011-10-04 23:04:551104
danakj1fd259a02016-04-16 03:17:091105 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161106 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1628fe92011-10-04 23:04:551107
Ryan Sleevib8d7ea02018-05-07 20:01:011108 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071109 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:551110
[email protected]49639fa2011-12-20 23:22:411111 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:551112
tfarina42834112016-09-22 13:38:201113 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011114 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1628fe92011-10-04 23:04:551115
robpercival214763f2016-07-01 23:27:011116 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]1628fe92011-10-04 23:04:551117
bnc691fda62016-08-12 00:43:161118 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521119 ASSERT_TRUE(response);
1120 ASSERT_TRUE(response->headers);
[email protected]1628fe92011-10-04 23:04:551121 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
1122 std::string url;
1123 EXPECT_TRUE(response->headers->IsRedirect(&url));
1124 EXPECT_EQ("http://good.com/", url);
tbansal2ecbbc72016-10-06 17:15:471125 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]1628fe92011-10-04 23:04:551126}
1127
[email protected]1628fe92011-10-04 23:04:551128// Checks that two distinct Location headers result in an error.
bncd16676a2016-07-20 16:23:011129TEST_F(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551130 MockRead data_reads[] = {
1131 MockRead("HTTP/1.1 302 Redirect\r\n"),
1132 MockRead("Location: http://good.com/\r\n"),
1133 MockRead("Location: http://evil.com/\r\n"),
1134 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061135 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551136 };
Ryan Sleevib8d7ea02018-05-07 20:01:011137 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011138 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION));
[email protected]1628fe92011-10-04 23:04:551139}
1140
[email protected]ef0faf2e72009-03-05 23:27:231141// Do a request using the HEAD method. Verify that we don't try to read the
1142// message body (since HEAD has none).
bncd16676a2016-07-20 16:23:011143TEST_F(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:421144 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:231145 request.method = "HEAD";
bncce36dca22015-04-21 22:11:231146 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:101147 request.traffic_annotation =
1148 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ef0faf2e72009-03-05 23:27:231149
danakj1fd259a02016-04-16 03:17:091150 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161151 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:091152 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:161153 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:091154 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
1155 base::Unretained(&headers_handler)));
[email protected]cb9bf6ca2011-01-28 13:15:271156
[email protected]ef0faf2e72009-03-05 23:27:231157 MockWrite data_writes1[] = {
csharrisonf473dd192015-08-18 13:54:131158 MockWrite("HEAD / HTTP/1.1\r\n"
1159 "Host: www.example.org\r\n"
1160 "Connection: keep-alive\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231161 };
1162 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:231163 MockRead("HTTP/1.1 404 Not Found\r\n"), MockRead("Server: Blah\r\n"),
1164 MockRead("Content-Length: 1234\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231165
mmenked39192ee2015-12-09 00:57:231166 // No response body because the test stops reading here.
1167 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]ef0faf2e72009-03-05 23:27:231168 };
1169
Ryan Sleevib8d7ea02018-05-07 20:01:011170 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:071171 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:231172
[email protected]49639fa2011-12-20 23:22:411173 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:231174
tfarina42834112016-09-22 13:38:201175 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011176 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ef0faf2e72009-03-05 23:27:231177
1178 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:011179 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231180
bnc691fda62016-08-12 00:43:161181 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521182 ASSERT_TRUE(response);
[email protected]ef0faf2e72009-03-05 23:27:231183
1184 // Check that the headers got parsed.
wezca1070932016-05-26 20:30:521185 EXPECT_TRUE(response->headers);
[email protected]ef0faf2e72009-03-05 23:27:231186 EXPECT_EQ(1234, response->headers->GetContentLength());
1187 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471188 EXPECT_TRUE(response->proxy_server.is_direct());
ryansturm49a8cb12016-06-15 16:51:091189 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
1190 EXPECT_FALSE(headers_handler.observed_before_headers_sent_with_proxy());
[email protected]ef0faf2e72009-03-05 23:27:231191
1192 std::string server_header;
olli.raulaee489a52016-01-25 08:37:101193 size_t iter = 0;
[email protected]ef0faf2e72009-03-05 23:27:231194 bool has_server_header = response->headers->EnumerateHeader(
1195 &iter, "Server", &server_header);
1196 EXPECT_TRUE(has_server_header);
1197 EXPECT_EQ("Blah", server_header);
1198
1199 // Reading should give EOF right away, since there is no message body
1200 // (despite non-zero content-length).
1201 std::string response_data;
bnc691fda62016-08-12 00:43:161202 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011203 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231204 EXPECT_EQ("", response_data);
1205}
1206
bncd16676a2016-07-20 16:23:011207TEST_F(HttpNetworkTransactionTest, ReuseConnection) {
danakj1fd259a02016-04-16 03:17:091208 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:521209
1210 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351211 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1212 MockRead("hello"),
1213 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1214 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061215 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521216 };
Ryan Sleevib8d7ea02018-05-07 20:01:011217 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071218 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521219
[email protected]0b0bf032010-09-21 18:08:501220 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521221 "hello", "world"
1222 };
1223
1224 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:421225 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521226 request.method = "GET";
bncce36dca22015-04-21 22:11:231227 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:101228 request.traffic_annotation =
1229 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:521230
bnc691fda62016-08-12 00:43:161231 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271232
[email protected]49639fa2011-12-20 23:22:411233 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521234
tfarina42834112016-09-22 13:38:201235 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011236 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521237
1238 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011239 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521240
bnc691fda62016-08-12 00:43:161241 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521242 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521243
wezca1070932016-05-26 20:30:521244 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251245 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471246 EXPECT_TRUE(response->proxy_server.is_direct());
initial.commit586acc5fe2008-07-26 22:42:521247
1248 std::string response_data;
bnc691fda62016-08-12 00:43:161249 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011250 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251251 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521252 }
1253}
1254
bncd16676a2016-07-20 16:23:011255TEST_F(HttpNetworkTransactionTest, Ignores100) {
danakj1fd259a02016-04-16 03:17:091256 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:221257 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:191258 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:221259 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:271260
[email protected]1c773ea12009-04-28 19:58:421261 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521262 request.method = "POST";
1263 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271264 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:101265 request.traffic_annotation =
1266 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:521267
shivanishab9a143952016-09-19 17:23:411268 // Check the upload progress returned before initialization is correct.
1269 UploadProgress progress = request.upload_data_stream->GetUploadProgress();
1270 EXPECT_EQ(0u, progress.size());
1271 EXPECT_EQ(0u, progress.position());
1272
danakj1fd259a02016-04-16 03:17:091273 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161274 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271275
initial.commit586acc5fe2008-07-26 22:42:521276 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351277 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1278 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1279 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061280 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521281 };
Ryan Sleevib8d7ea02018-05-07 20:01:011282 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071283 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521284
[email protected]49639fa2011-12-20 23:22:411285 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521286
tfarina42834112016-09-22 13:38:201287 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011288 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521289
1290 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011291 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521292
bnc691fda62016-08-12 00:43:161293 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521294 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521295
wezca1070932016-05-26 20:30:521296 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251297 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521298
1299 std::string response_data;
bnc691fda62016-08-12 00:43:161300 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011301 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251302 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521303}
1304
[email protected]3a2d3662009-03-27 03:49:141305// This test is almost the same as Ignores100 above, but the response contains
1306// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571307// HTTP/1.1 and the two status headers are read in one read.
bncd16676a2016-07-20 16:23:011308TEST_F(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421309 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141310 request.method = "GET";
1311 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101312 request.traffic_annotation =
1313 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3a2d3662009-03-27 03:49:141314
danakj1fd259a02016-04-16 03:17:091315 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161316 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271317
[email protected]3a2d3662009-03-27 03:49:141318 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571319 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1320 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141321 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061322 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141323 };
Ryan Sleevib8d7ea02018-05-07 20:01:011324 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071325 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141326
[email protected]49639fa2011-12-20 23:22:411327 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141328
tfarina42834112016-09-22 13:38:201329 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011330 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3a2d3662009-03-27 03:49:141331
1332 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011333 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141334
bnc691fda62016-08-12 00:43:161335 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521336 ASSERT_TRUE(response);
[email protected]3a2d3662009-03-27 03:49:141337
wezca1070932016-05-26 20:30:521338 EXPECT_TRUE(response->headers);
[email protected]3a2d3662009-03-27 03:49:141339 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1340
1341 std::string response_data;
bnc691fda62016-08-12 00:43:161342 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011343 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141344 EXPECT_EQ("hello world", response_data);
1345}
1346
bncd16676a2016-07-20 16:23:011347TEST_F(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
zmo9528c9f42015-08-04 22:12:081348 HttpRequestInfo request;
1349 request.method = "POST";
1350 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101351 request.traffic_annotation =
1352 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
zmo9528c9f42015-08-04 22:12:081353
danakj1fd259a02016-04-16 03:17:091354 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161355 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zmo9528c9f42015-08-04 22:12:081356
1357 MockRead data_reads[] = {
1358 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1359 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381360 };
Ryan Sleevib8d7ea02018-05-07 20:01:011361 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
zmo9528c9f42015-08-04 22:12:081362 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381363
zmo9528c9f42015-08-04 22:12:081364 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381365
tfarina42834112016-09-22 13:38:201366 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011367 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381368
zmo9528c9f42015-08-04 22:12:081369 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011370 EXPECT_THAT(rv, IsOk());
[email protected]ee9410e72010-01-07 01:42:381371
zmo9528c9f42015-08-04 22:12:081372 std::string response_data;
bnc691fda62016-08-12 00:43:161373 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011374 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:081375 EXPECT_EQ("", response_data);
[email protected]ee9410e72010-01-07 01:42:381376}
1377
bncd16676a2016-07-20 16:23:011378TEST_F(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381379 HttpRequestInfo request;
1380 request.method = "POST";
1381 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101382 request.traffic_annotation =
1383 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ee9410e72010-01-07 01:42:381384
danakj1fd259a02016-04-16 03:17:091385 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161386 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271387
[email protected]ee9410e72010-01-07 01:42:381388 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061389 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381390 };
Ryan Sleevib8d7ea02018-05-07 20:01:011391 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071392 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381393
[email protected]49639fa2011-12-20 23:22:411394 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381395
tfarina42834112016-09-22 13:38:201396 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011397 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381398
1399 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011400 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]ee9410e72010-01-07 01:42:381401}
1402
[email protected]23e482282013-06-14 16:08:021403void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511404 const MockWrite* write_failure,
1405 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421406 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521407 request.method = "GET";
1408 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101409 request.traffic_annotation =
1410 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:521411
vishal.b62985ca92015-04-17 08:45:511412 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071413 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091414 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271415
[email protected]202965992011-12-07 23:04:511416 // Written data for successfully sending both requests.
1417 MockWrite data1_writes[] = {
1418 MockWrite("GET / HTTP/1.1\r\n"
1419 "Host: www.foo.com\r\n"
1420 "Connection: keep-alive\r\n\r\n"),
1421 MockWrite("GET / HTTP/1.1\r\n"
1422 "Host: www.foo.com\r\n"
1423 "Connection: keep-alive\r\n\r\n")
1424 };
1425
1426 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521427 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351428 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1429 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061430 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521431 };
[email protected]202965992011-12-07 23:04:511432
1433 if (write_failure) {
[email protected]a34f61ee2014-03-18 20:59:491434 ASSERT_FALSE(read_failure);
[email protected]202965992011-12-07 23:04:511435 data1_writes[1] = *write_failure;
1436 } else {
1437 ASSERT_TRUE(read_failure);
1438 data1_reads[2] = *read_failure;
1439 }
1440
Ryan Sleevib8d7ea02018-05-07 20:01:011441 StaticSocketDataProvider data1(data1_reads, data1_writes);
[email protected]bb88e1d32013-05-03 23:11:071442 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521443
1444 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351445 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1446 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061447 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521448 };
Ryan Sleevib8d7ea02018-05-07 20:01:011449 StaticSocketDataProvider data2(data2_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071450 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521451
thestig9d3bb0c2015-01-24 00:49:511452 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521453 "hello", "world"
1454 };
1455
mikecironef22f9812016-10-04 03:40:191456 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521457 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411458 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521459
bnc691fda62016-08-12 00:43:161460 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
initial.commit586acc5fe2008-07-26 22:42:521461
tfarina42834112016-09-22 13:38:201462 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011463 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521464
1465 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011466 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521467
[email protected]58e32bb2013-01-21 18:23:251468 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161469 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:251470 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1471 if (i == 0) {
1472 first_socket_log_id = load_timing_info.socket_log_id;
1473 } else {
1474 // The second request should be using a new socket.
1475 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1476 }
1477
bnc691fda62016-08-12 00:43:161478 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521479 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521480
wezca1070932016-05-26 20:30:521481 EXPECT_TRUE(response->headers);
tbansal2ecbbc72016-10-06 17:15:471482 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]3d2a59b2008-09-26 19:44:251483 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521484
1485 std::string response_data;
bnc691fda62016-08-12 00:43:161486 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011487 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251488 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521489 }
1490}
[email protected]3d2a59b2008-09-26 19:44:251491
[email protected]a34f61ee2014-03-18 20:59:491492void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1493 const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:101494 const MockRead* read_failure,
1495 bool use_spdy) {
[email protected]a34f61ee2014-03-18 20:59:491496 HttpRequestInfo request;
1497 request.method = "GET";
[email protected]09356c652014-03-25 15:36:101498 request.url = GURL("https://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101499 request.traffic_annotation =
1500 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]a34f61ee2014-03-18 20:59:491501
vishal.b62985ca92015-04-17 08:45:511502 TestNetLog net_log;
[email protected]a34f61ee2014-03-18 20:59:491503 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091504 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a34f61ee2014-03-18 20:59:491505
[email protected]09356c652014-03-25 15:36:101506 SSLSocketDataProvider ssl1(ASYNC, OK);
1507 SSLSocketDataProvider ssl2(ASYNC, OK);
1508 if (use_spdy) {
bnc3cf2a592016-08-11 14:48:361509 ssl1.next_proto = kProtoHTTP2;
1510 ssl2.next_proto = kProtoHTTP2;
[email protected]09356c652014-03-25 15:36:101511 }
1512 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1513 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]a34f61ee2014-03-18 20:59:491514
[email protected]09356c652014-03-25 15:36:101515 // SPDY versions of the request and response.
Ryan Hamilton0239aac2018-05-19 00:03:131516 spdy::SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
bnc38dcd392016-02-09 23:19:491517 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
Ryan Hamilton0239aac2018-05-19 00:03:131518 spdy::SpdySerializedFrame spdy_response(
bnc42331402016-07-25 13:36:151519 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:131520 spdy::SpdySerializedFrame spdy_data(
Bence Békyd74f4382018-02-20 18:26:191521 spdy_util_.ConstructSpdyDataFrame(1, "hello", true));
[email protected]a34f61ee2014-03-18 20:59:491522
[email protected]09356c652014-03-25 15:36:101523 // HTTP/1.1 versions of the request and response.
1524 const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1525 "Host: www.foo.com\r\n"
1526 "Connection: keep-alive\r\n\r\n";
1527 const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1528 const char kHttpData[] = "hello";
1529
1530 std::vector<MockRead> data1_reads;
1531 std::vector<MockWrite> data1_writes;
[email protected]a34f61ee2014-03-18 20:59:491532 if (write_failure) {
1533 ASSERT_FALSE(read_failure);
[email protected]09356c652014-03-25 15:36:101534 data1_writes.push_back(*write_failure);
1535 data1_reads.push_back(MockRead(ASYNC, OK));
[email protected]a34f61ee2014-03-18 20:59:491536 } else {
1537 ASSERT_TRUE(read_failure);
[email protected]09356c652014-03-25 15:36:101538 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411539 data1_writes.push_back(CreateMockWrite(spdy_request));
[email protected]09356c652014-03-25 15:36:101540 } else {
1541 data1_writes.push_back(MockWrite(kHttpRequest));
1542 }
1543 data1_reads.push_back(*read_failure);
[email protected]a34f61ee2014-03-18 20:59:491544 }
1545
Ryan Sleevib8d7ea02018-05-07 20:01:011546 StaticSocketDataProvider data1(data1_reads, data1_writes);
[email protected]a34f61ee2014-03-18 20:59:491547 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1548
[email protected]09356c652014-03-25 15:36:101549 std::vector<MockRead> data2_reads;
1550 std::vector<MockWrite> data2_writes;
1551
1552 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411553 data2_writes.push_back(CreateMockWrite(spdy_request, 0, ASYNC));
[email protected]09356c652014-03-25 15:36:101554
bncdf80d44fd2016-07-15 20:27:411555 data2_reads.push_back(CreateMockRead(spdy_response, 1, ASYNC));
1556 data2_reads.push_back(CreateMockRead(spdy_data, 2, ASYNC));
[email protected]09356c652014-03-25 15:36:101557 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1558 } else {
1559 data2_writes.push_back(
1560 MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1561
1562 data2_reads.push_back(
1563 MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1564 data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1565 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1566 }
Ryan Sleevib8d7ea02018-05-07 20:01:011567 SequencedSocketData data2(data2_reads, data2_writes);
[email protected]a34f61ee2014-03-18 20:59:491568 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1569
1570 // Preconnect a socket.
nharper8cdb0fb2016-04-22 21:34:591571 session->http_stream_factory()->PreconnectStreams(1, request);
[email protected]a34f61ee2014-03-18 20:59:491572 // Wait for the preconnect to complete.
1573 // TODO(davidben): Some way to wait for an idle socket count might be handy.
1574 base::RunLoop().RunUntilIdle();
[email protected]09356c652014-03-25 15:36:101575 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]a34f61ee2014-03-18 20:59:491576
1577 // Make the request.
1578 TestCompletionCallback callback;
1579
bnc691fda62016-08-12 00:43:161580 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a34f61ee2014-03-18 20:59:491581
tfarina42834112016-09-22 13:38:201582 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011583 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a34f61ee2014-03-18 20:59:491584
1585 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011586 EXPECT_THAT(rv, IsOk());
[email protected]a34f61ee2014-03-18 20:59:491587
1588 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161589 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]09356c652014-03-25 15:36:101590 TestLoadTimingNotReused(
1591 load_timing_info,
1592 CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]a34f61ee2014-03-18 20:59:491593
bnc691fda62016-08-12 00:43:161594 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521595 ASSERT_TRUE(response);
[email protected]a34f61ee2014-03-18 20:59:491596
wezca1070932016-05-26 20:30:521597 EXPECT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:021598 if (response->was_fetched_via_spdy) {
1599 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
1600 } else {
1601 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1602 }
[email protected]a34f61ee2014-03-18 20:59:491603
1604 std::string response_data;
bnc691fda62016-08-12 00:43:161605 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011606 EXPECT_THAT(rv, IsOk());
[email protected]09356c652014-03-25 15:36:101607 EXPECT_EQ(kHttpData, response_data);
[email protected]a34f61ee2014-03-18 20:59:491608}
1609
Biljith Jayan45a41722017-08-16 18:43:141610// Test that we do not retry indefinitely when a server sends an error like
1611// ERR_SPDY_PING_FAILED, ERR_SPDY_SERVER_REFUSED_STREAM,
1612// ERR_QUIC_HANDSHAKE_FAILED or ERR_QUIC_PROTOCOL_ERROR.
1613TEST_F(HttpNetworkTransactionTest, FiniteRetriesOnIOError) {
1614 HttpRequestInfo request;
1615 request.method = "GET";
1616 request.url = GURL("https://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101617 request.traffic_annotation =
1618 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Biljith Jayan45a41722017-08-16 18:43:141619
1620 // Check whether we give up after the third try.
1621
1622 // Construct an HTTP2 request and a "Go away" response.
Ryan Hamilton0239aac2018-05-19 00:03:131623 spdy::SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
Biljith Jayan45a41722017-08-16 18:43:141624 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
Ryan Hamilton0239aac2018-05-19 00:03:131625 spdy::SpdySerializedFrame spdy_response_go_away(
1626 spdy_util_.ConstructSpdyGoAway(0));
Ryan Sleevib8d7ea02018-05-07 20:01:011627 MockRead data_read1[] = {CreateMockRead(spdy_response_go_away)};
1628 MockWrite data_write[] = {CreateMockWrite(spdy_request, 0)};
Biljith Jayan45a41722017-08-16 18:43:141629
1630 // Three go away responses.
Ryan Sleevib8d7ea02018-05-07 20:01:011631 StaticSocketDataProvider data1(data_read1, data_write);
1632 StaticSocketDataProvider data2(data_read1, data_write);
1633 StaticSocketDataProvider data3(data_read1, data_write);
Biljith Jayan45a41722017-08-16 18:43:141634
1635 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1636 AddSSLSocketData();
1637 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1638 AddSSLSocketData();
1639 session_deps_.socket_factory->AddSocketDataProvider(&data3);
1640 AddSSLSocketData();
1641
1642 TestCompletionCallback callback;
1643 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1644 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1645
1646 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1647 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1648
1649 rv = callback.WaitForResult();
1650 EXPECT_THAT(rv, IsError(ERR_SPDY_SERVER_REFUSED_STREAM));
1651}
1652
1653TEST_F(HttpNetworkTransactionTest, RetryTwiceOnIOError) {
1654 HttpRequestInfo request;
1655 request.method = "GET";
1656 request.url = GURL("https://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101657 request.traffic_annotation =
1658 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Biljith Jayan45a41722017-08-16 18:43:141659
1660 // Check whether we try atleast thrice before giving up.
1661
1662 // Construct an HTTP2 request and a "Go away" response.
Ryan Hamilton0239aac2018-05-19 00:03:131663 spdy::SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
Biljith Jayan45a41722017-08-16 18:43:141664 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
Ryan Hamilton0239aac2018-05-19 00:03:131665 spdy::SpdySerializedFrame spdy_response_go_away(
1666 spdy_util_.ConstructSpdyGoAway(0));
Ryan Sleevib8d7ea02018-05-07 20:01:011667 MockRead data_read1[] = {CreateMockRead(spdy_response_go_away)};
1668 MockWrite data_write[] = {CreateMockWrite(spdy_request, 0)};
Biljith Jayan45a41722017-08-16 18:43:141669
1670 // Construct a non error HTTP2 response.
Ryan Hamilton0239aac2018-05-19 00:03:131671 spdy::SpdySerializedFrame spdy_response_no_error(
Biljith Jayan45a41722017-08-16 18:43:141672 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:131673 spdy::SpdySerializedFrame spdy_data(
1674 spdy_util_.ConstructSpdyDataFrame(1, true));
Biljith Jayan45a41722017-08-16 18:43:141675 MockRead data_read2[] = {CreateMockRead(spdy_response_no_error, 1),
1676 CreateMockRead(spdy_data, 2)};
1677
1678 // Two error responses.
Ryan Sleevib8d7ea02018-05-07 20:01:011679 StaticSocketDataProvider data1(data_read1, data_write);
1680 StaticSocketDataProvider data2(data_read1, data_write);
Biljith Jayan45a41722017-08-16 18:43:141681 // Followed by a success response.
Ryan Sleevib8d7ea02018-05-07 20:01:011682 SequencedSocketData data3(data_read2, data_write);
Biljith Jayan45a41722017-08-16 18:43:141683
1684 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1685 AddSSLSocketData();
1686 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1687 AddSSLSocketData();
1688 session_deps_.socket_factory->AddSocketDataProvider(&data3);
1689 AddSSLSocketData();
1690
1691 TestCompletionCallback callback;
1692 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1693 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1694
1695 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1696 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1697
1698 rv = callback.WaitForResult();
1699 EXPECT_THAT(rv, IsOk());
1700}
1701
bncd16676a2016-07-20 16:23:011702TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061703 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]202965992011-12-07 23:04:511704 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1705}
1706
bncd16676a2016-07-20 16:23:011707TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061708 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]202965992011-12-07 23:04:511709 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251710}
1711
bncd16676a2016-07-20 16:23:011712TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061713 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]202965992011-12-07 23:04:511714 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251715}
1716
[email protected]d58ceea82014-06-04 10:55:541717// Make sure that on a 408 response (Request Timeout), the request is retried,
1718// if the socket was a reused keep alive socket.
bncd16676a2016-07-20 16:23:011719TEST_F(HttpNetworkTransactionTest, KeepAlive408) {
[email protected]d58ceea82014-06-04 10:55:541720 MockRead read_failure(SYNCHRONOUS,
1721 "HTTP/1.1 408 Request Timeout\r\n"
1722 "Connection: Keep-Alive\r\n"
1723 "Content-Length: 6\r\n\r\n"
1724 "Pickle");
1725 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1726}
1727
bncd16676a2016-07-20 16:23:011728TEST_F(HttpNetworkTransactionTest, PreconnectErrorNotConnectedOnWrite) {
[email protected]a34f61ee2014-03-18 20:59:491729 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]09356c652014-03-25 15:36:101730 PreconnectErrorResendRequestTest(&write_failure, NULL, false);
[email protected]a34f61ee2014-03-18 20:59:491731}
1732
bncd16676a2016-07-20 16:23:011733TEST_F(HttpNetworkTransactionTest, PreconnectErrorReset) {
[email protected]a34f61ee2014-03-18 20:59:491734 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]09356c652014-03-25 15:36:101735 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
[email protected]a34f61ee2014-03-18 20:59:491736}
1737
bncd16676a2016-07-20 16:23:011738TEST_F(HttpNetworkTransactionTest, PreconnectErrorEOF) {
[email protected]a34f61ee2014-03-18 20:59:491739 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]09356c652014-03-25 15:36:101740 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1741}
1742
bncd16676a2016-07-20 16:23:011743TEST_F(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:101744 MockRead read_failure(ASYNC, OK); // EOF
1745 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1746}
1747
[email protected]d58ceea82014-06-04 10:55:541748// Make sure that on a 408 response (Request Timeout), the request is retried,
1749// if the socket was a preconnected (UNUSED_IDLE) socket.
bncd16676a2016-07-20 16:23:011750TEST_F(HttpNetworkTransactionTest, RetryOnIdle408) {
[email protected]d58ceea82014-06-04 10:55:541751 MockRead read_failure(SYNCHRONOUS,
1752 "HTTP/1.1 408 Request Timeout\r\n"
1753 "Connection: Keep-Alive\r\n"
1754 "Content-Length: 6\r\n\r\n"
1755 "Pickle");
1756 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1757 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1758}
1759
bncd16676a2016-07-20 16:23:011760TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorNotConnectedOnWrite) {
[email protected]09356c652014-03-25 15:36:101761 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1762 PreconnectErrorResendRequestTest(&write_failure, NULL, true);
1763}
1764
bncd16676a2016-07-20 16:23:011765TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
[email protected]09356c652014-03-25 15:36:101766 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1767 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1768}
1769
bncd16676a2016-07-20 16:23:011770TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
[email protected]09356c652014-03-25 15:36:101771 MockRead read_failure(SYNCHRONOUS, OK); // EOF
1772 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1773}
1774
bncd16676a2016-07-20 16:23:011775TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:101776 MockRead read_failure(ASYNC, OK); // EOF
1777 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
[email protected]a34f61ee2014-03-18 20:59:491778}
1779
bncd16676a2016-07-20 16:23:011780TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:421781 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:251782 request.method = "GET";
bncce36dca22015-04-21 22:11:231783 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:101784 request.traffic_annotation =
1785 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3d2a59b2008-09-26 19:44:251786
danakj1fd259a02016-04-16 03:17:091787 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161788 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271789
[email protected]3d2a59b2008-09-26 19:44:251790 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061791 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:351792 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1793 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061794 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251795 };
Ryan Sleevib8d7ea02018-05-07 20:01:011796 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071797 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:251798
[email protected]49639fa2011-12-20 23:22:411799 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:251800
tfarina42834112016-09-22 13:38:201801 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011802 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3d2a59b2008-09-26 19:44:251803
1804 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011805 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:591806
1807 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:161808 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:591809 EXPECT_LT(0u, endpoint.address().size());
[email protected]3d2a59b2008-09-26 19:44:251810}
1811
1812// What do various browsers do when the server closes a non-keepalive
1813// connection without sending any response header or body?
1814//
1815// IE7: error page
1816// Safari 3.1.2 (Windows): error page
1817// Firefox 3.0.1: blank page
1818// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:421819// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1820// Us: error page (EMPTY_RESPONSE)
bncd16676a2016-07-20 16:23:011821TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:251822 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061823 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:351824 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1825 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061826 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251827 };
Ryan Sleevib8d7ea02018-05-07 20:01:011828 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011829 EXPECT_THAT(out.rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]3d2a59b2008-09-26 19:44:251830}
[email protected]1826a402014-01-08 15:40:481831
[email protected]7a5378b2012-11-04 03:25:171832// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
1833// tests. There was a bug causing HttpNetworkTransaction to hang in the
1834// destructor in such situations.
1835// See http://crbug.com/154712 and http://crbug.com/156609.
bncd16676a2016-07-20 16:23:011836TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:171837 HttpRequestInfo request;
1838 request.method = "GET";
bncce36dca22015-04-21 22:11:231839 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:101840 request.traffic_annotation =
1841 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7a5378b2012-11-04 03:25:171842
danakj1fd259a02016-04-16 03:17:091843 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:581844 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:191845 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:171846
1847 MockRead data_reads[] = {
1848 MockRead("HTTP/1.0 200 OK\r\n"),
1849 MockRead("Connection: keep-alive\r\n"),
1850 MockRead("Content-Length: 100\r\n\r\n"),
1851 MockRead("hello"),
1852 MockRead(SYNCHRONOUS, 0),
1853 };
Ryan Sleevib8d7ea02018-05-07 20:01:011854 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071855 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171856
1857 TestCompletionCallback callback;
1858
tfarina42834112016-09-22 13:38:201859 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011860 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:171861
1862 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011863 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:171864
1865 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501866 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171867 if (rv == ERR_IO_PENDING)
1868 rv = callback.WaitForResult();
1869 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:501870 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
robpercival214763f2016-07-01 23:27:011871 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:171872
1873 trans.reset();
fdoray92e35a72016-06-10 15:54:551874 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171875 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1876}
1877
bncd16676a2016-07-20 16:23:011878TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:171879 HttpRequestInfo request;
1880 request.method = "GET";
bncce36dca22015-04-21 22:11:231881 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:101882 request.traffic_annotation =
1883 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7a5378b2012-11-04 03:25:171884
danakj1fd259a02016-04-16 03:17:091885 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:581886 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:191887 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:171888
1889 MockRead data_reads[] = {
1890 MockRead("HTTP/1.0 200 OK\r\n"),
1891 MockRead("Connection: keep-alive\r\n"),
1892 MockRead("Content-Length: 100\r\n\r\n"),
1893 MockRead(SYNCHRONOUS, 0),
1894 };
Ryan Sleevib8d7ea02018-05-07 20:01:011895 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071896 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171897
1898 TestCompletionCallback callback;
1899
tfarina42834112016-09-22 13:38:201900 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011901 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:171902
1903 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011904 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:171905
1906 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501907 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171908 if (rv == ERR_IO_PENDING)
1909 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011910 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:171911
1912 trans.reset();
fdoray92e35a72016-06-10 15:54:551913 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171914 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1915}
1916
[email protected]0b0bf032010-09-21 18:08:501917// Test that we correctly reuse a keep-alive connection after not explicitly
1918// reading the body.
bncd16676a2016-07-20 16:23:011919TEST_F(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:131920 HttpRequestInfo request;
1921 request.method = "GET";
1922 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101923 request.traffic_annotation =
1924 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]fc31d6a42010-06-24 18:05:131925
vishal.b62985ca92015-04-17 08:45:511926 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071927 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091928 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271929
mmenkecc2298e2015-12-07 18:20:181930 const char* request_data =
1931 "GET / HTTP/1.1\r\n"
1932 "Host: www.foo.com\r\n"
1933 "Connection: keep-alive\r\n\r\n";
1934 MockWrite data_writes[] = {
1935 MockWrite(ASYNC, 0, request_data), MockWrite(ASYNC, 2, request_data),
1936 MockWrite(ASYNC, 4, request_data), MockWrite(ASYNC, 6, request_data),
1937 MockWrite(ASYNC, 8, request_data), MockWrite(ASYNC, 10, request_data),
1938 MockWrite(ASYNC, 12, request_data), MockWrite(ASYNC, 14, request_data),
1939 MockWrite(ASYNC, 17, request_data), MockWrite(ASYNC, 20, request_data),
1940 };
1941
[email protected]0b0bf032010-09-21 18:08:501942 // Note that because all these reads happen in the same
1943 // StaticSocketDataProvider, it shows that the same socket is being reused for
1944 // all transactions.
mmenkecc2298e2015-12-07 18:20:181945 MockRead data_reads[] = {
1946 MockRead(ASYNC, 1, "HTTP/1.1 204 No Content\r\n\r\n"),
1947 MockRead(ASYNC, 3, "HTTP/1.1 205 Reset Content\r\n\r\n"),
1948 MockRead(ASYNC, 5, "HTTP/1.1 304 Not Modified\r\n\r\n"),
1949 MockRead(ASYNC, 7,
1950 "HTTP/1.1 302 Found\r\n"
1951 "Content-Length: 0\r\n\r\n"),
1952 MockRead(ASYNC, 9,
1953 "HTTP/1.1 302 Found\r\n"
1954 "Content-Length: 5\r\n\r\n"
1955 "hello"),
1956 MockRead(ASYNC, 11,
1957 "HTTP/1.1 301 Moved Permanently\r\n"
1958 "Content-Length: 0\r\n\r\n"),
1959 MockRead(ASYNC, 13,
1960 "HTTP/1.1 301 Moved Permanently\r\n"
1961 "Content-Length: 5\r\n\r\n"
1962 "hello"),
[email protected]fc31d6a42010-06-24 18:05:131963
mmenkecc2298e2015-12-07 18:20:181964 // In the next two rounds, IsConnectedAndIdle returns false, due to
1965 // the set_busy_before_sync_reads(true) call, while the
1966 // HttpNetworkTransaction is being shut down, but the socket is still
1967 // reuseable. See http://crbug.com/544255.
1968 MockRead(ASYNC, 15,
1969 "HTTP/1.1 200 Hunky-Dory\r\n"
1970 "Content-Length: 5\r\n\r\n"),
1971 MockRead(SYNCHRONOUS, 16, "hello"),
[email protected]fc31d6a42010-06-24 18:05:131972
mmenkecc2298e2015-12-07 18:20:181973 MockRead(ASYNC, 18,
1974 "HTTP/1.1 200 Hunky-Dory\r\n"
1975 "Content-Length: 5\r\n\r\n"
1976 "he"),
1977 MockRead(SYNCHRONOUS, 19, "llo"),
1978
1979 // The body of the final request is actually read.
1980 MockRead(ASYNC, 21, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1981 MockRead(ASYNC, 22, "hello"),
1982 };
Ryan Sleevib8d7ea02018-05-07 20:01:011983 SequencedSocketData data(data_reads, data_writes);
mmenkecc2298e2015-12-07 18:20:181984 data.set_busy_before_sync_reads(true);
1985 session_deps_.socket_factory->AddSocketDataProvider(&data);
1986
1987 const int kNumUnreadBodies = arraysize(data_writes) - 1;
[email protected]0b0bf032010-09-21 18:08:501988 std::string response_lines[kNumUnreadBodies];
1989
mikecironef22f9812016-10-04 03:40:191990 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
mmenkecc2298e2015-12-07 18:20:181991 for (size_t i = 0; i < kNumUnreadBodies; ++i) {
[email protected]49639fa2011-12-20 23:22:411992 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:131993
Jeremy Roman0579ed62017-08-29 15:56:191994 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
bnc87dcefc2017-05-25 12:47:581995 session.get());
[email protected]fc31d6a42010-06-24 18:05:131996
tfarina42834112016-09-22 13:38:201997 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011998 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]fc31d6a42010-06-24 18:05:131999
[email protected]58e32bb2013-01-21 18:23:252000 LoadTimingInfo load_timing_info;
2001 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2002 if (i == 0) {
2003 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
2004 first_socket_log_id = load_timing_info.socket_log_id;
2005 } else {
2006 TestLoadTimingReused(load_timing_info);
2007 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
2008 }
2009
[email protected]fc31d6a42010-06-24 18:05:132010 const HttpResponseInfo* response = trans->GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182011 ASSERT_TRUE(response);
[email protected]fc31d6a42010-06-24 18:05:132012
mmenkecc2298e2015-12-07 18:20:182013 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502014 response_lines[i] = response->headers->GetStatusLine();
2015
mmenkecc2298e2015-12-07 18:20:182016 // Delete the transaction without reading the response bodies. Then spin
2017 // the message loop, so the response bodies are drained.
2018 trans.reset();
2019 base::RunLoop().RunUntilIdle();
[email protected]fc31d6a42010-06-24 18:05:132020 }
[email protected]0b0bf032010-09-21 18:08:502021
2022 const char* const kStatusLines[] = {
mmenkecc2298e2015-12-07 18:20:182023 "HTTP/1.1 204 No Content",
2024 "HTTP/1.1 205 Reset Content",
2025 "HTTP/1.1 304 Not Modified",
2026 "HTTP/1.1 302 Found",
2027 "HTTP/1.1 302 Found",
2028 "HTTP/1.1 301 Moved Permanently",
2029 "HTTP/1.1 301 Moved Permanently",
2030 "HTTP/1.1 200 Hunky-Dory",
2031 "HTTP/1.1 200 Hunky-Dory",
[email protected]0b0bf032010-09-21 18:08:502032 };
2033
mostynb91e0da982015-01-20 19:17:272034 static_assert(kNumUnreadBodies == arraysize(kStatusLines),
2035 "forgot to update kStatusLines");
[email protected]0b0bf032010-09-21 18:08:502036
2037 for (int i = 0; i < kNumUnreadBodies; ++i)
2038 EXPECT_EQ(kStatusLines[i], response_lines[i]);
2039
[email protected]49639fa2011-12-20 23:22:412040 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:162041 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202042 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012043 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:162044 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182045 ASSERT_TRUE(response);
2046 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502047 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2048 std::string response_data;
bnc691fda62016-08-12 00:43:162049 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:012050 EXPECT_THAT(rv, IsOk());
[email protected]0b0bf032010-09-21 18:08:502051 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:132052}
2053
mmenke5f94fda2016-06-02 20:54:132054// Sockets that receive extra data after a response is complete should not be
2055// reused.
bncd16676a2016-07-20 16:23:012056TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData1) {
mmenke5f94fda2016-06-02 20:54:132057 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2058 MockWrite data_writes1[] = {
2059 MockWrite("HEAD / HTTP/1.1\r\n"
2060 "Host: www.borked.com\r\n"
2061 "Connection: keep-alive\r\n\r\n"),
2062 };
2063
2064 MockRead data_reads1[] = {
2065 MockRead("HTTP/1.1 200 OK\r\n"
2066 "Connection: keep-alive\r\n"
2067 "Content-Length: 22\r\n\r\n"
2068 "This server is borked."),
2069 };
2070
2071 MockWrite data_writes2[] = {
2072 MockWrite("GET /foo HTTP/1.1\r\n"
2073 "Host: www.borked.com\r\n"
2074 "Connection: keep-alive\r\n\r\n"),
2075 };
2076
2077 MockRead data_reads2[] = {
2078 MockRead("HTTP/1.1 200 OK\r\n"
2079 "Content-Length: 3\r\n\r\n"
2080 "foo"),
2081 };
Ryan Sleevib8d7ea02018-05-07 20:01:012082 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke5f94fda2016-06-02 20:54:132083 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:012084 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke5f94fda2016-06-02 20:54:132085 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2086
2087 TestCompletionCallback callback;
2088 HttpRequestInfo request1;
2089 request1.method = "HEAD";
2090 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e62018-02-07 07:41:102091 request1.traffic_annotation =
2092 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132093
bnc87dcefc2017-05-25 12:47:582094 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192095 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202096 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012097 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132098
2099 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2100 ASSERT_TRUE(response1);
2101 ASSERT_TRUE(response1->headers);
2102 EXPECT_EQ(200, response1->headers->response_code());
2103 EXPECT_TRUE(response1->headers->IsKeepAlive());
2104
2105 std::string response_data1;
robpercival214763f2016-07-01 23:27:012106 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132107 EXPECT_EQ("", response_data1);
2108 // Deleting the transaction attempts to release the socket back into the
2109 // socket pool.
2110 trans1.reset();
2111
2112 HttpRequestInfo request2;
2113 request2.method = "GET";
2114 request2.url = GURL("http://www.borked.com/foo");
Ramin Halavatib5e433e62018-02-07 07:41:102115 request2.traffic_annotation =
2116 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132117
bnc87dcefc2017-05-25 12:47:582118 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192119 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202120 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012121 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132122
2123 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2124 ASSERT_TRUE(response2);
2125 ASSERT_TRUE(response2->headers);
2126 EXPECT_EQ(200, response2->headers->response_code());
2127
2128 std::string response_data2;
robpercival214763f2016-07-01 23:27:012129 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132130 EXPECT_EQ("foo", response_data2);
2131}
2132
bncd16676a2016-07-20 16:23:012133TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData2) {
mmenke5f94fda2016-06-02 20:54:132134 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2135 MockWrite data_writes1[] = {
2136 MockWrite("GET / HTTP/1.1\r\n"
2137 "Host: www.borked.com\r\n"
2138 "Connection: keep-alive\r\n\r\n"),
2139 };
2140
2141 MockRead data_reads1[] = {
2142 MockRead("HTTP/1.1 200 OK\r\n"
2143 "Connection: keep-alive\r\n"
2144 "Content-Length: 22\r\n\r\n"
2145 "This server is borked."
2146 "Bonus data!"),
2147 };
2148
2149 MockWrite data_writes2[] = {
2150 MockWrite("GET /foo HTTP/1.1\r\n"
2151 "Host: www.borked.com\r\n"
2152 "Connection: keep-alive\r\n\r\n"),
2153 };
2154
2155 MockRead data_reads2[] = {
2156 MockRead("HTTP/1.1 200 OK\r\n"
2157 "Content-Length: 3\r\n\r\n"
2158 "foo"),
2159 };
Ryan Sleevib8d7ea02018-05-07 20:01:012160 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke5f94fda2016-06-02 20:54:132161 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:012162 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke5f94fda2016-06-02 20:54:132163 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2164
2165 TestCompletionCallback callback;
2166 HttpRequestInfo request1;
2167 request1.method = "GET";
2168 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e62018-02-07 07:41:102169 request1.traffic_annotation =
2170 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132171
bnc87dcefc2017-05-25 12:47:582172 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192173 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202174 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012175 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132176
2177 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2178 ASSERT_TRUE(response1);
2179 ASSERT_TRUE(response1->headers);
2180 EXPECT_EQ(200, response1->headers->response_code());
2181 EXPECT_TRUE(response1->headers->IsKeepAlive());
2182
2183 std::string response_data1;
robpercival214763f2016-07-01 23:27:012184 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132185 EXPECT_EQ("This server is borked.", response_data1);
2186 // Deleting the transaction attempts to release the socket back into the
2187 // socket pool.
2188 trans1.reset();
2189
2190 HttpRequestInfo request2;
2191 request2.method = "GET";
2192 request2.url = GURL("http://www.borked.com/foo");
Ramin Halavatib5e433e62018-02-07 07:41:102193 request2.traffic_annotation =
2194 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132195
bnc87dcefc2017-05-25 12:47:582196 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192197 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202198 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012199 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132200
2201 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2202 ASSERT_TRUE(response2);
2203 ASSERT_TRUE(response2->headers);
2204 EXPECT_EQ(200, response2->headers->response_code());
2205
2206 std::string response_data2;
robpercival214763f2016-07-01 23:27:012207 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132208 EXPECT_EQ("foo", response_data2);
2209}
2210
bncd16676a2016-07-20 16:23:012211TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData3) {
mmenke5f94fda2016-06-02 20:54:132212 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2213 MockWrite data_writes1[] = {
2214 MockWrite("GET / HTTP/1.1\r\n"
2215 "Host: www.borked.com\r\n"
2216 "Connection: keep-alive\r\n\r\n"),
2217 };
2218
2219 MockRead data_reads1[] = {
2220 MockRead("HTTP/1.1 200 OK\r\n"
2221 "Connection: keep-alive\r\n"
2222 "Transfer-Encoding: chunked\r\n\r\n"),
2223 MockRead("16\r\nThis server is borked.\r\n"),
2224 MockRead("0\r\n\r\nBonus data!"),
2225 };
2226
2227 MockWrite data_writes2[] = {
2228 MockWrite("GET /foo HTTP/1.1\r\n"
2229 "Host: www.borked.com\r\n"
2230 "Connection: keep-alive\r\n\r\n"),
2231 };
2232
2233 MockRead data_reads2[] = {
2234 MockRead("HTTP/1.1 200 OK\r\n"
2235 "Content-Length: 3\r\n\r\n"
2236 "foo"),
2237 };
Ryan Sleevib8d7ea02018-05-07 20:01:012238 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke5f94fda2016-06-02 20:54:132239 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:012240 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke5f94fda2016-06-02 20:54:132241 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2242
2243 TestCompletionCallback callback;
2244 HttpRequestInfo request1;
2245 request1.method = "GET";
2246 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e62018-02-07 07:41:102247 request1.traffic_annotation =
2248 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132249
bnc87dcefc2017-05-25 12:47:582250 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192251 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202252 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012253 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132254
2255 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2256 ASSERT_TRUE(response1);
2257 ASSERT_TRUE(response1->headers);
2258 EXPECT_EQ(200, response1->headers->response_code());
2259 EXPECT_TRUE(response1->headers->IsKeepAlive());
2260
2261 std::string response_data1;
robpercival214763f2016-07-01 23:27:012262 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132263 EXPECT_EQ("This server is borked.", response_data1);
2264 // Deleting the transaction attempts to release the socket back into the
2265 // socket pool.
2266 trans1.reset();
2267
2268 HttpRequestInfo request2;
2269 request2.method = "GET";
2270 request2.url = GURL("http://www.borked.com/foo");
Ramin Halavatib5e433e62018-02-07 07:41:102271 request2.traffic_annotation =
2272 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132273
bnc87dcefc2017-05-25 12:47:582274 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192275 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202276 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012277 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132278
2279 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2280 ASSERT_TRUE(response2);
2281 ASSERT_TRUE(response2->headers);
2282 EXPECT_EQ(200, response2->headers->response_code());
2283
2284 std::string response_data2;
robpercival214763f2016-07-01 23:27:012285 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132286 EXPECT_EQ("foo", response_data2);
2287}
2288
2289// This is a little different from the others - it tests the case that the
2290// HttpStreamParser doesn't know if there's extra data on a socket or not when
2291// the HttpNetworkTransaction is torn down, because the response body hasn't
2292// been read from yet, but the request goes through the HttpResponseBodyDrainer.
bncd16676a2016-07-20 16:23:012293TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData4) {
mmenke5f94fda2016-06-02 20:54:132294 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2295 MockWrite data_writes1[] = {
2296 MockWrite("GET / HTTP/1.1\r\n"
2297 "Host: www.borked.com\r\n"
2298 "Connection: keep-alive\r\n\r\n"),
2299 };
2300
2301 MockRead data_reads1[] = {
2302 MockRead("HTTP/1.1 200 OK\r\n"
2303 "Connection: keep-alive\r\n"
2304 "Transfer-Encoding: chunked\r\n\r\n"),
2305 MockRead("16\r\nThis server is borked.\r\n"),
2306 MockRead("0\r\n\r\nBonus data!"),
2307 };
Ryan Sleevib8d7ea02018-05-07 20:01:012308 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke5f94fda2016-06-02 20:54:132309 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2310
2311 TestCompletionCallback callback;
2312 HttpRequestInfo request1;
2313 request1.method = "GET";
2314 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e62018-02-07 07:41:102315 request1.traffic_annotation =
2316 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132317
bnc87dcefc2017-05-25 12:47:582318 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:192319 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
bnc87dcefc2017-05-25 12:47:582320 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012321 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132322
bnc87dcefc2017-05-25 12:47:582323 const HttpResponseInfo* response1 = trans->GetResponseInfo();
mmenke5f94fda2016-06-02 20:54:132324 ASSERT_TRUE(response1);
2325 ASSERT_TRUE(response1->headers);
2326 EXPECT_EQ(200, response1->headers->response_code());
2327 EXPECT_TRUE(response1->headers->IsKeepAlive());
2328
2329 // Deleting the transaction creates an HttpResponseBodyDrainer to read the
2330 // response body.
bnc87dcefc2017-05-25 12:47:582331 trans.reset();
mmenke5f94fda2016-06-02 20:54:132332
2333 // Let the HttpResponseBodyDrainer drain the socket. It should determine the
2334 // socket can't be reused, rather than returning it to the socket pool.
2335 base::RunLoop().RunUntilIdle();
2336
2337 // There should be no idle sockets in the pool.
2338 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2339}
2340
[email protected]038e9a32008-10-08 22:40:162341// Test the request-challenge-retry sequence for basic auth.
2342// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012343TEST_F(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:422344 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:162345 request.method = "GET";
bncce36dca22015-04-21 22:11:232346 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:102347 request.traffic_annotation =
2348 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]038e9a32008-10-08 22:40:162349
vishal.b62985ca92015-04-17 08:45:512350 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072351 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092352 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162353 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272354
[email protected]f9ee6b52008-11-08 06:46:232355 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232356 MockWrite(
2357 "GET / HTTP/1.1\r\n"
2358 "Host: www.example.org\r\n"
2359 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:232360 };
2361
[email protected]038e9a32008-10-08 22:40:162362 MockRead data_reads1[] = {
2363 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2364 // Give a couple authenticate options (only the middle one is actually
2365 // supported).
[email protected]22927ad2009-09-21 19:56:192366 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:162367 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2368 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2369 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2370 // Large content-length -- won't matter, as connection will be reset.
2371 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062372 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:162373 };
2374
2375 // After calling trans->RestartWithAuth(), this is the request we should
2376 // be issuing -- the final header line contains the credentials.
2377 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232378 MockWrite(
2379 "GET / HTTP/1.1\r\n"
2380 "Host: www.example.org\r\n"
2381 "Connection: keep-alive\r\n"
2382 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:162383 };
2384
2385 // Lastly, the server responds with the actual content.
2386 MockRead data_reads2[] = {
2387 MockRead("HTTP/1.0 200 OK\r\n"),
2388 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2389 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062390 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:162391 };
2392
Ryan Sleevib8d7ea02018-05-07 20:01:012393 StaticSocketDataProvider data1(data_reads1, data_writes1);
2394 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:072395 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2396 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:162397
[email protected]49639fa2011-12-20 23:22:412398 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:162399
tfarina42834112016-09-22 13:38:202400 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012401 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162402
2403 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012404 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162405
[email protected]58e32bb2013-01-21 18:23:252406 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162407 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
[email protected]58e32bb2013-01-21 18:23:252408 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2409
Ryan Sleevib8d7ea02018-05-07 20:01:012410 int64_t writes_size1 = CountWriteBytes(data_writes1);
bnc691fda62016-08-12 00:43:162411 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012412 int64_t reads_size1 = CountReadBytes(data_reads1);
bnc691fda62016-08-12 00:43:162413 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192414
bnc691fda62016-08-12 00:43:162415 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522416 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042417 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:162418
[email protected]49639fa2011-12-20 23:22:412419 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:162420
bnc691fda62016-08-12 00:43:162421 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012422 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162423
2424 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012425 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162426
[email protected]58e32bb2013-01-21 18:23:252427 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162428 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
[email protected]58e32bb2013-01-21 18:23:252429 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2430 // The load timing after restart should have a new socket ID, and times after
2431 // those of the first load timing.
2432 EXPECT_LE(load_timing_info1.receive_headers_end,
2433 load_timing_info2.connect_timing.connect_start);
2434 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2435
Ryan Sleevib8d7ea02018-05-07 20:01:012436 int64_t writes_size2 = CountWriteBytes(data_writes2);
bnc691fda62016-08-12 00:43:162437 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012438 int64_t reads_size2 = CountReadBytes(data_reads2);
bnc691fda62016-08-12 00:43:162439 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192440
bnc691fda62016-08-12 00:43:162441 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522442 ASSERT_TRUE(response);
2443 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:162444 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:162445}
2446
ttuttled9dbc652015-09-29 20:00:592447// Test the request-challenge-retry sequence for basic auth.
2448// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012449TEST_F(HttpNetworkTransactionTest, BasicAuthWithAddressChange) {
ttuttled9dbc652015-09-29 20:00:592450 HttpRequestInfo request;
2451 request.method = "GET";
2452 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:102453 request.traffic_annotation =
2454 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttled9dbc652015-09-29 20:00:592455
2456 TestNetLog log;
2457 MockHostResolver* resolver = new MockHostResolver();
2458 session_deps_.net_log = &log;
2459 session_deps_.host_resolver.reset(resolver);
danakj1fd259a02016-04-16 03:17:092460 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
bnc691fda62016-08-12 00:43:162461 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttled9dbc652015-09-29 20:00:592462
2463 resolver->rules()->ClearRules();
2464 resolver->rules()->AddRule("www.example.org", "127.0.0.1");
2465
2466 MockWrite data_writes1[] = {
2467 MockWrite("GET / HTTP/1.1\r\n"
2468 "Host: www.example.org\r\n"
2469 "Connection: keep-alive\r\n\r\n"),
2470 };
2471
2472 MockRead data_reads1[] = {
2473 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2474 // Give a couple authenticate options (only the middle one is actually
2475 // supported).
2476 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
2477 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2478 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2479 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2480 // Large content-length -- won't matter, as connection will be reset.
2481 MockRead("Content-Length: 10000\r\n\r\n"),
2482 MockRead(SYNCHRONOUS, ERR_FAILED),
2483 };
2484
2485 // After calling trans->RestartWithAuth(), this is the request we should
2486 // be issuing -- the final header line contains the credentials.
2487 MockWrite data_writes2[] = {
2488 MockWrite("GET / HTTP/1.1\r\n"
2489 "Host: www.example.org\r\n"
2490 "Connection: keep-alive\r\n"
2491 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2492 };
2493
2494 // Lastly, the server responds with the actual content.
2495 MockRead data_reads2[] = {
2496 MockRead("HTTP/1.0 200 OK\r\n"),
2497 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2498 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, OK),
2499 };
2500
Ryan Sleevib8d7ea02018-05-07 20:01:012501 StaticSocketDataProvider data1(data_reads1, data_writes1);
2502 StaticSocketDataProvider data2(data_reads2, data_writes2);
ttuttled9dbc652015-09-29 20:00:592503 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2504 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2505
2506 TestCompletionCallback callback1;
2507
bnc691fda62016-08-12 00:43:162508 EXPECT_EQ(OK, callback1.GetResult(trans.Start(&request, callback1.callback(),
tfarina42834112016-09-22 13:38:202509 NetLogWithSource())));
ttuttled9dbc652015-09-29 20:00:592510
2511 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162512 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
ttuttled9dbc652015-09-29 20:00:592513 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2514
Ryan Sleevib8d7ea02018-05-07 20:01:012515 int64_t writes_size1 = CountWriteBytes(data_writes1);
bnc691fda62016-08-12 00:43:162516 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012517 int64_t reads_size1 = CountReadBytes(data_reads1);
bnc691fda62016-08-12 00:43:162518 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592519
bnc691fda62016-08-12 00:43:162520 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592521 ASSERT_TRUE(response);
2522 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2523
2524 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:162525 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592526 ASSERT_FALSE(endpoint.address().empty());
2527 EXPECT_EQ("127.0.0.1:80", endpoint.ToString());
2528
2529 resolver->rules()->ClearRules();
2530 resolver->rules()->AddRule("www.example.org", "127.0.0.2");
2531
2532 TestCompletionCallback callback2;
2533
bnc691fda62016-08-12 00:43:162534 EXPECT_EQ(OK, callback2.GetResult(trans.RestartWithAuth(
ttuttled9dbc652015-09-29 20:00:592535 AuthCredentials(kFoo, kBar), callback2.callback())));
2536
2537 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162538 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
ttuttled9dbc652015-09-29 20:00:592539 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2540 // The load timing after restart should have a new socket ID, and times after
2541 // those of the first load timing.
2542 EXPECT_LE(load_timing_info1.receive_headers_end,
2543 load_timing_info2.connect_timing.connect_start);
2544 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2545
Ryan Sleevib8d7ea02018-05-07 20:01:012546 int64_t writes_size2 = CountWriteBytes(data_writes2);
bnc691fda62016-08-12 00:43:162547 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012548 int64_t reads_size2 = CountReadBytes(data_reads2);
bnc691fda62016-08-12 00:43:162549 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592550
bnc691fda62016-08-12 00:43:162551 response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592552 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:522553 EXPECT_FALSE(response->auth_challenge);
ttuttled9dbc652015-09-29 20:00:592554 EXPECT_EQ(100, response->headers->GetContentLength());
2555
bnc691fda62016-08-12 00:43:162556 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592557 ASSERT_FALSE(endpoint.address().empty());
2558 EXPECT_EQ("127.0.0.2:80", endpoint.ToString());
2559}
2560
David Benjamin83ddfb32018-03-30 01:07:522561// Test that, if the server requests auth indefinitely, HttpNetworkTransaction
2562// will eventually give up.
2563TEST_F(HttpNetworkTransactionTest, BasicAuthForever) {
2564 HttpRequestInfo request;
2565 request.method = "GET";
2566 request.url = GURL("http://www.example.org/");
2567 request.traffic_annotation =
2568 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2569
2570 TestNetLog log;
2571 session_deps_.net_log = &log;
2572 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2573 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
2574
2575 MockWrite data_writes[] = {
2576 MockWrite("GET / HTTP/1.1\r\n"
2577 "Host: www.example.org\r\n"
2578 "Connection: keep-alive\r\n\r\n"),
2579 };
2580
2581 MockRead data_reads[] = {
2582 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2583 // Give a couple authenticate options (only the middle one is actually
2584 // supported).
2585 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
2586 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2587 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2588 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2589 // Large content-length -- won't matter, as connection will be reset.
2590 MockRead("Content-Length: 10000\r\n\r\n"),
2591 MockRead(SYNCHRONOUS, ERR_FAILED),
2592 };
2593
2594 // After calling trans->RestartWithAuth(), this is the request we should
2595 // be issuing -- the final header line contains the credentials.
2596 MockWrite data_writes_restart[] = {
2597 MockWrite("GET / HTTP/1.1\r\n"
2598 "Host: www.example.org\r\n"
2599 "Connection: keep-alive\r\n"
2600 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2601 };
2602
Ryan Sleevib8d7ea02018-05-07 20:01:012603 StaticSocketDataProvider data(data_reads, data_writes);
David Benjamin83ddfb32018-03-30 01:07:522604 session_deps_.socket_factory->AddSocketDataProvider(&data);
2605
2606 TestCompletionCallback callback;
2607 int rv = callback.GetResult(
2608 trans.Start(&request, callback.callback(), NetLogWithSource()));
2609
2610 std::vector<std::unique_ptr<StaticSocketDataProvider>> data_restarts;
2611 for (int i = 0; i < 32; i++) {
2612 // Check the previous response was a 401.
2613 EXPECT_THAT(rv, IsOk());
2614 const HttpResponseInfo* response = trans.GetResponseInfo();
2615 ASSERT_TRUE(response);
2616 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2617
2618 data_restarts.push_back(std::make_unique<StaticSocketDataProvider>(
Ryan Sleevib8d7ea02018-05-07 20:01:012619 data_reads, data_writes_restart));
David Benjamin83ddfb32018-03-30 01:07:522620 session_deps_.socket_factory->AddSocketDataProvider(
2621 data_restarts.back().get());
2622 rv = callback.GetResult(trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
2623 callback.callback()));
2624 }
2625
2626 // After too many tries, the transaction should have given up.
2627 EXPECT_THAT(rv, IsError(ERR_TOO_MANY_RETRIES));
2628}
2629
bncd16676a2016-07-20 16:23:012630TEST_F(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:462631 HttpRequestInfo request;
2632 request.method = "GET";
bncce36dca22015-04-21 22:11:232633 request.url = GURL("http://www.example.org/");
ttuttle859dc7a2015-04-23 19:42:292634 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:102635 request.traffic_annotation =
2636 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]861fcd52009-08-26 02:33:462637
danakj1fd259a02016-04-16 03:17:092638 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162639 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272640
[email protected]861fcd52009-08-26 02:33:462641 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:232642 MockWrite(
2643 "GET / HTTP/1.1\r\n"
2644 "Host: www.example.org\r\n"
2645 "Connection: keep-alive\r\n\r\n"),
[email protected]861fcd52009-08-26 02:33:462646 };
2647
2648 MockRead data_reads[] = {
2649 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2650 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2651 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2652 // Large content-length -- won't matter, as connection will be reset.
2653 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062654 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:462655 };
2656
Ryan Sleevib8d7ea02018-05-07 20:01:012657 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:072658 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:412659 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:462660
tfarina42834112016-09-22 13:38:202661 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012662 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]861fcd52009-08-26 02:33:462663
2664 rv = callback.WaitForResult();
2665 EXPECT_EQ(0, rv);
2666
Ryan Sleevib8d7ea02018-05-07 20:01:012667 int64_t writes_size = CountWriteBytes(data_writes);
bnc691fda62016-08-12 00:43:162668 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012669 int64_t reads_size = CountReadBytes(data_reads);
bnc691fda62016-08-12 00:43:162670 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192671
bnc691fda62016-08-12 00:43:162672 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522673 ASSERT_TRUE(response);
2674 EXPECT_FALSE(response->auth_challenge);
[email protected]861fcd52009-08-26 02:33:462675}
2676
[email protected]2d2697f92009-02-18 21:00:322677// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2678// connection.
bncd16676a2016-07-20 16:23:012679TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
mmenkecc2298e2015-12-07 18:20:182680 // On the second pass, the body read of the auth challenge is synchronous, so
2681 // IsConnectedAndIdle returns false. The socket should still be drained and
2682 // reused. See http://crbug.com/544255.
2683 for (int i = 0; i < 2; ++i) {
2684 HttpRequestInfo request;
2685 request.method = "GET";
2686 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:102687 request.traffic_annotation =
2688 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:322689
mmenkecc2298e2015-12-07 18:20:182690 TestNetLog log;
2691 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092692 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272693
mmenkecc2298e2015-12-07 18:20:182694 MockWrite data_writes[] = {
2695 MockWrite(ASYNC, 0,
2696 "GET / HTTP/1.1\r\n"
2697 "Host: www.example.org\r\n"
2698 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322699
bnc691fda62016-08-12 00:43:162700 // After calling trans.RestartWithAuth(), this is the request we should
mmenkecc2298e2015-12-07 18:20:182701 // be issuing -- the final header line contains the credentials.
2702 MockWrite(ASYNC, 6,
2703 "GET / HTTP/1.1\r\n"
2704 "Host: www.example.org\r\n"
2705 "Connection: keep-alive\r\n"
2706 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2707 };
[email protected]2d2697f92009-02-18 21:00:322708
mmenkecc2298e2015-12-07 18:20:182709 MockRead data_reads[] = {
2710 MockRead(ASYNC, 1, "HTTP/1.1 401 Unauthorized\r\n"),
2711 MockRead(ASYNC, 2, "WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2712 MockRead(ASYNC, 3, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2713 MockRead(ASYNC, 4, "Content-Length: 14\r\n\r\n"),
2714 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 5, "Unauthorized\r\n"),
[email protected]2d2697f92009-02-18 21:00:322715
mmenkecc2298e2015-12-07 18:20:182716 // Lastly, the server responds with the actual content.
2717 MockRead(ASYNC, 7, "HTTP/1.1 200 OK\r\n"),
2718 MockRead(ASYNC, 8, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2719 MockRead(ASYNC, 9, "Content-Length: 5\r\n\r\n"),
2720 MockRead(ASYNC, 10, "Hello"),
2721 };
[email protected]2d2697f92009-02-18 21:00:322722
Ryan Sleevib8d7ea02018-05-07 20:01:012723 SequencedSocketData data(data_reads, data_writes);
mmenkecc2298e2015-12-07 18:20:182724 data.set_busy_before_sync_reads(true);
2725 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]2d0a4f92011-05-05 16:38:462726
mmenkecc2298e2015-12-07 18:20:182727 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322728
bnc691fda62016-08-12 00:43:162729 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202730 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012731 ASSERT_THAT(callback1.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322732
mmenkecc2298e2015-12-07 18:20:182733 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162734 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
mmenkecc2298e2015-12-07 18:20:182735 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
[email protected]2d2697f92009-02-18 21:00:322736
bnc691fda62016-08-12 00:43:162737 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182738 ASSERT_TRUE(response);
2739 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322740
mmenkecc2298e2015-12-07 18:20:182741 TestCompletionCallback callback2;
[email protected]58e32bb2013-01-21 18:23:252742
bnc691fda62016-08-12 00:43:162743 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
2744 callback2.callback());
robpercival214763f2016-07-01 23:27:012745 ASSERT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322746
mmenkecc2298e2015-12-07 18:20:182747 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162748 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
mmenkecc2298e2015-12-07 18:20:182749 TestLoadTimingReused(load_timing_info2);
2750 // The load timing after restart should have the same socket ID, and times
2751 // those of the first load timing.
2752 EXPECT_LE(load_timing_info1.receive_headers_end,
2753 load_timing_info2.send_start);
2754 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]2d2697f92009-02-18 21:00:322755
bnc691fda62016-08-12 00:43:162756 response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182757 ASSERT_TRUE(response);
2758 EXPECT_FALSE(response->auth_challenge);
2759 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322760
mmenkecc2298e2015-12-07 18:20:182761 std::string response_data;
bnc691fda62016-08-12 00:43:162762 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]2d2697f92009-02-18 21:00:322763
Ryan Sleevib8d7ea02018-05-07 20:01:012764 int64_t writes_size = CountWriteBytes(data_writes);
bnc691fda62016-08-12 00:43:162765 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012766 int64_t reads_size = CountReadBytes(data_reads);
bnc691fda62016-08-12 00:43:162767 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
mmenkecc2298e2015-12-07 18:20:182768 }
[email protected]2d2697f92009-02-18 21:00:322769}
2770
2771// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2772// connection and with no response body to drain.
bncd16676a2016-07-20 16:23:012773TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:422774 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322775 request.method = "GET";
bncce36dca22015-04-21 22:11:232776 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:102777 request.traffic_annotation =
2778 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:322779
danakj1fd259a02016-04-16 03:17:092780 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272781
[email protected]2d2697f92009-02-18 21:00:322782 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:162783 MockWrite("GET / HTTP/1.1\r\n"
2784 "Host: www.example.org\r\n"
2785 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322786
bnc691fda62016-08-12 00:43:162787 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:232788 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:162789 MockWrite("GET / HTTP/1.1\r\n"
2790 "Host: www.example.org\r\n"
2791 "Connection: keep-alive\r\n"
2792 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322793 };
2794
[email protected]2d2697f92009-02-18 21:00:322795 MockRead data_reads1[] = {
2796 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2797 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:312798 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:322799
2800 // Lastly, the server responds with the actual content.
2801 MockRead("HTTP/1.1 200 OK\r\n"),
2802 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502803 MockRead("Content-Length: 5\r\n\r\n"),
2804 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322805 };
2806
[email protected]2d0a4f92011-05-05 16:38:462807 // An incorrect reconnect would cause this to be read.
2808 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062809 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462810 };
2811
Ryan Sleevib8d7ea02018-05-07 20:01:012812 StaticSocketDataProvider data1(data_reads1, data_writes1);
2813 StaticSocketDataProvider data2(data_reads2, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:072814 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2815 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322816
[email protected]49639fa2011-12-20 23:22:412817 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322818
bnc691fda62016-08-12 00:43:162819 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202820 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012821 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322822
2823 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012824 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322825
bnc691fda62016-08-12 00:43:162826 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522827 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042828 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322829
[email protected]49639fa2011-12-20 23:22:412830 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322831
bnc691fda62016-08-12 00:43:162832 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012833 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322834
2835 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012836 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322837
bnc691fda62016-08-12 00:43:162838 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522839 ASSERT_TRUE(response);
2840 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502841 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322842}
2843
2844// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2845// connection and with a large response body to drain.
bncd16676a2016-07-20 16:23:012846TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:422847 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322848 request.method = "GET";
bncce36dca22015-04-21 22:11:232849 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:102850 request.traffic_annotation =
2851 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:322852
danakj1fd259a02016-04-16 03:17:092853 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272854
[email protected]2d2697f92009-02-18 21:00:322855 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:162856 MockWrite("GET / HTTP/1.1\r\n"
2857 "Host: www.example.org\r\n"
2858 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322859
bnc691fda62016-08-12 00:43:162860 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:232861 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:162862 MockWrite("GET / HTTP/1.1\r\n"
2863 "Host: www.example.org\r\n"
2864 "Connection: keep-alive\r\n"
2865 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322866 };
2867
2868 // Respond with 5 kb of response body.
2869 std::string large_body_string("Unauthorized");
2870 large_body_string.append(5 * 1024, ' ');
2871 large_body_string.append("\r\n");
2872
2873 MockRead data_reads1[] = {
2874 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2875 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2876 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2877 // 5134 = 12 + 5 * 1024 + 2
2878 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062879 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:322880
2881 // Lastly, the server responds with the actual content.
2882 MockRead("HTTP/1.1 200 OK\r\n"),
2883 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502884 MockRead("Content-Length: 5\r\n\r\n"),
2885 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322886 };
2887
[email protected]2d0a4f92011-05-05 16:38:462888 // An incorrect reconnect would cause this to be read.
2889 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062890 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462891 };
2892
Ryan Sleevib8d7ea02018-05-07 20:01:012893 StaticSocketDataProvider data1(data_reads1, data_writes1);
2894 StaticSocketDataProvider data2(data_reads2, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:072895 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2896 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322897
[email protected]49639fa2011-12-20 23:22:412898 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322899
bnc691fda62016-08-12 00:43:162900 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202901 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012902 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322903
2904 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012905 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322906
bnc691fda62016-08-12 00:43:162907 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522908 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042909 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322910
[email protected]49639fa2011-12-20 23:22:412911 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322912
bnc691fda62016-08-12 00:43:162913 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012914 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322915
2916 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012917 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322918
bnc691fda62016-08-12 00:43:162919 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522920 ASSERT_TRUE(response);
2921 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502922 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322923}
2924
2925// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:312926// connection, but the server gets impatient and closes the connection.
bncd16676a2016-07-20 16:23:012927TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:312928 HttpRequestInfo request;
2929 request.method = "GET";
bncce36dca22015-04-21 22:11:232930 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:102931 request.traffic_annotation =
2932 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]11203f012009-11-12 23:02:312933
danakj1fd259a02016-04-16 03:17:092934 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272935
[email protected]11203f012009-11-12 23:02:312936 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232937 MockWrite(
2938 "GET / HTTP/1.1\r\n"
2939 "Host: www.example.org\r\n"
2940 "Connection: keep-alive\r\n\r\n"),
2941 // This simulates the seemingly successful write to a closed connection
2942 // if the bug is not fixed.
2943 MockWrite(
2944 "GET / HTTP/1.1\r\n"
2945 "Host: www.example.org\r\n"
2946 "Connection: keep-alive\r\n"
2947 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312948 };
2949
2950 MockRead data_reads1[] = {
2951 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2952 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2953 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2954 MockRead("Content-Length: 14\r\n\r\n"),
2955 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:062956 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:312957 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:062958 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:312959 };
2960
bnc691fda62016-08-12 00:43:162961 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]11203f012009-11-12 23:02:312962 // be issuing -- the final header line contains the credentials.
2963 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232964 MockWrite(
2965 "GET / HTTP/1.1\r\n"
2966 "Host: www.example.org\r\n"
2967 "Connection: keep-alive\r\n"
2968 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312969 };
2970
2971 // Lastly, the server responds with the actual content.
2972 MockRead data_reads2[] = {
2973 MockRead("HTTP/1.1 200 OK\r\n"),
2974 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502975 MockRead("Content-Length: 5\r\n\r\n"),
2976 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:312977 };
2978
Ryan Sleevib8d7ea02018-05-07 20:01:012979 StaticSocketDataProvider data1(data_reads1, data_writes1);
2980 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:072981 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2982 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:312983
[email protected]49639fa2011-12-20 23:22:412984 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:312985
bnc691fda62016-08-12 00:43:162986 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202987 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012988 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:312989
2990 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012991 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:312992
bnc691fda62016-08-12 00:43:162993 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522994 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042995 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:312996
[email protected]49639fa2011-12-20 23:22:412997 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:312998
bnc691fda62016-08-12 00:43:162999 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013000 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:313001
3002 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013003 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:313004
bnc691fda62016-08-12 00:43:163005 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523006 ASSERT_TRUE(response);
3007 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503008 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:313009}
3010
[email protected]394816e92010-08-03 07:38:593011// Test the request-challenge-retry sequence for basic auth, over a connection
3012// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013013TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
ttuttle34f63b52015-03-05 04:33:013014 HttpRequestInfo request;
3015 request.method = "GET";
bncce36dca22015-04-21 22:11:233016 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:013017 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293018 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:103019 request.traffic_annotation =
3020 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle34f63b52015-03-05 04:33:013021
3022 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593023 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493024 ProxyResolutionService::CreateFixedFromPacResult(
3025 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513026 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:013027 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093028 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013029
3030 // Since we have proxy, should try to establish tunnel.
3031 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543032 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173033 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543034 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013035 };
3036
mmenkee71e15332015-10-07 16:39:543037 // The proxy responds to the connect with a 407, using a non-persistent
ttuttle34f63b52015-03-05 04:33:013038 // connection.
3039 MockRead data_reads1[] = {
3040 // No credentials.
3041 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
3042 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
mmenkee71e15332015-10-07 16:39:543043 };
ttuttle34f63b52015-03-05 04:33:013044
mmenkee71e15332015-10-07 16:39:543045 // Since the first connection couldn't be reused, need to establish another
3046 // once given credentials.
3047 MockWrite data_writes2[] = {
3048 // After calling trans->RestartWithAuth(), this is the request we should
3049 // be issuing -- the final header line contains the credentials.
3050 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173051 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543052 "Proxy-Connection: keep-alive\r\n"
3053 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3054
3055 MockWrite("GET / HTTP/1.1\r\n"
3056 "Host: www.example.org\r\n"
3057 "Connection: keep-alive\r\n\r\n"),
3058 };
3059
3060 MockRead data_reads2[] = {
ttuttle34f63b52015-03-05 04:33:013061 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3062
3063 MockRead("HTTP/1.1 200 OK\r\n"),
3064 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3065 MockRead("Content-Length: 5\r\n\r\n"),
3066 MockRead(SYNCHRONOUS, "hello"),
3067 };
3068
Ryan Sleevib8d7ea02018-05-07 20:01:013069 StaticSocketDataProvider data1(data_reads1, data_writes1);
ttuttle34f63b52015-03-05 04:33:013070 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:013071 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenkee71e15332015-10-07 16:39:543072 session_deps_.socket_factory->AddSocketDataProvider(&data2);
ttuttle34f63b52015-03-05 04:33:013073 SSLSocketDataProvider ssl(ASYNC, OK);
3074 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3075
3076 TestCompletionCallback callback1;
3077
bnc87dcefc2017-05-25 12:47:583078 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193079 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013080
3081 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013082 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:013083
3084 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013085 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463086 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:013087 log.GetEntries(&entries);
3088 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003089 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3090 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013091 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003092 entries, pos,
3093 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3094 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013095
3096 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523097 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013098 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523099 ASSERT_TRUE(response->headers);
ttuttle34f63b52015-03-05 04:33:013100 EXPECT_EQ(407, response->headers->response_code());
3101 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3102 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3103
3104 LoadTimingInfo load_timing_info;
3105 // CONNECT requests and responses are handled at the connect job level, so
3106 // the transaction does not yet have a connection.
3107 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3108
3109 TestCompletionCallback callback2;
3110
3111 rv =
3112 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013113 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:013114
3115 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013116 EXPECT_THAT(rv, IsOk());
ttuttle34f63b52015-03-05 04:33:013117
3118 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523119 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013120
3121 EXPECT_TRUE(response->headers->IsKeepAlive());
3122 EXPECT_EQ(200, response->headers->response_code());
3123 EXPECT_EQ(5, response->headers->GetContentLength());
3124 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3125
3126 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523127 EXPECT_FALSE(response->auth_challenge);
ttuttle34f63b52015-03-05 04:33:013128
3129 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3130 TestLoadTimingNotReusedWithPac(load_timing_info,
3131 CONNECT_TIMING_HAS_SSL_TIMES);
3132
3133 trans.reset();
3134 session->CloseAllConnections();
3135}
3136
3137// Test the request-challenge-retry sequence for basic auth, over a connection
3138// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013139TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) {
[email protected]394816e92010-08-03 07:38:593140 HttpRequestInfo request;
3141 request.method = "GET";
bncce36dca22015-04-21 22:11:233142 request.url = GURL("https://www.example.org/");
[email protected]394816e92010-08-03 07:38:593143 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293144 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:103145 request.traffic_annotation =
3146 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]394816e92010-08-03 07:38:593147
[email protected]cb9bf6ca2011-01-28 13:15:273148 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593149 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493150 ProxyResolutionService::CreateFixedFromPacResult(
3151 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513152 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073153 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093154 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273155
[email protected]394816e92010-08-03 07:38:593156 // Since we have proxy, should try to establish tunnel.
3157 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543158 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173159 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543160 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenkee0b5c882015-08-26 20:29:113161 };
3162
mmenkee71e15332015-10-07 16:39:543163 // The proxy responds to the connect with a 407, using a non-persistent
mmenke0fd148d2015-09-30 23:00:083164 // connection.
3165 MockRead data_reads1[] = {
mmenkee71e15332015-10-07 16:39:543166 // No credentials.
3167 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3168 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3169 MockRead("Proxy-Connection: close\r\n\r\n"),
3170 };
mmenkee0b5c882015-08-26 20:29:113171
mmenkee71e15332015-10-07 16:39:543172 MockWrite data_writes2[] = {
3173 // After calling trans->RestartWithAuth(), this is the request we should
3174 // be issuing -- the final header line contains the credentials.
3175 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173176 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543177 "Proxy-Connection: keep-alive\r\n"
3178 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
mmenke0fd148d2015-09-30 23:00:083179
mmenkee71e15332015-10-07 16:39:543180 MockWrite("GET / HTTP/1.1\r\n"
3181 "Host: www.example.org\r\n"
3182 "Connection: keep-alive\r\n\r\n"),
3183 };
3184
3185 MockRead data_reads2[] = {
3186 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3187
3188 MockRead("HTTP/1.1 200 OK\r\n"),
3189 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3190 MockRead("Content-Length: 5\r\n\r\n"),
3191 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:593192 };
3193
Ryan Sleevib8d7ea02018-05-07 20:01:013194 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:073195 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:013196 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenkee71e15332015-10-07 16:39:543197 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8ddf8322012-02-23 18:08:063198 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073199 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:593200
[email protected]49639fa2011-12-20 23:22:413201 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:593202
bnc87dcefc2017-05-25 12:47:583203 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193204 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:503205
[email protected]49639fa2011-12-20 23:22:413206 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013207 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593208
3209 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013210 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463211 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403212 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:593213 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003214 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3215 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593216 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403217 entries, pos,
mikecirone8b85c432016-09-08 19:11:003218 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3219 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593220
3221 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523222 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013223 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523224 ASSERT_TRUE(response->headers);
[email protected]394816e92010-08-03 07:38:593225 EXPECT_EQ(407, response->headers->response_code());
3226 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043227 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:593228
[email protected]029c83b62013-01-24 05:28:203229 LoadTimingInfo load_timing_info;
3230 // CONNECT requests and responses are handled at the connect job level, so
3231 // the transaction does not yet have a connection.
3232 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3233
[email protected]49639fa2011-12-20 23:22:413234 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:593235
[email protected]49639fa2011-12-20 23:22:413236 rv = trans->RestartWithAuth(
3237 AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013238 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593239
3240 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013241 EXPECT_THAT(rv, IsOk());
[email protected]394816e92010-08-03 07:38:593242
3243 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523244 ASSERT_TRUE(response);
[email protected]394816e92010-08-03 07:38:593245
3246 EXPECT_TRUE(response->headers->IsKeepAlive());
3247 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:503248 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:593249 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3250
3251 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523252 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503253
[email protected]029c83b62013-01-24 05:28:203254 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3255 TestLoadTimingNotReusedWithPac(load_timing_info,
3256 CONNECT_TIMING_HAS_SSL_TIMES);
3257
[email protected]0b0bf032010-09-21 18:08:503258 trans.reset();
[email protected]102e27c2011-02-23 01:01:313259 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:593260}
3261
[email protected]11203f012009-11-12 23:02:313262// Test the request-challenge-retry sequence for basic auth, over a keep-alive
ttuttle34f63b52015-03-05 04:33:013263// proxy connection with HTTP/1.0 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013264TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
mmenked39192ee2015-12-09 00:57:233265 // On the second pass, the body read of the auth challenge is synchronous, so
3266 // IsConnectedAndIdle returns false. The socket should still be drained and
3267 // reused. See http://crbug.com/544255.
3268 for (int i = 0; i < 2; ++i) {
3269 HttpRequestInfo request;
3270 request.method = "GET";
3271 request.url = GURL("https://www.example.org/");
3272 // Ensure that proxy authentication is attempted even
3273 // when the no authentication data flag is set.
3274 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:103275 request.traffic_annotation =
3276 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle34f63b52015-03-05 04:33:013277
mmenked39192ee2015-12-09 00:57:233278 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593279 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493280 ProxyResolutionService::CreateFixed("myproxy:70",
3281 TRAFFIC_ANNOTATION_FOR_TESTS);
mmenked39192ee2015-12-09 00:57:233282 BoundTestNetLog log;
3283 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093284 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013285
bnc691fda62016-08-12 00:43:163286 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013287
mmenked39192ee2015-12-09 00:57:233288 // Since we have proxy, should try to establish tunnel.
3289 MockWrite data_writes1[] = {
3290 MockWrite(ASYNC, 0,
3291 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3292 "Host: www.example.org:443\r\n"
3293 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013294
bnc691fda62016-08-12 00:43:163295 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233296 // be issuing -- the final header line contains the credentials.
3297 MockWrite(ASYNC, 3,
3298 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3299 "Host: www.example.org:443\r\n"
3300 "Proxy-Connection: keep-alive\r\n"
3301 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3302 };
ttuttle34f63b52015-03-05 04:33:013303
mmenked39192ee2015-12-09 00:57:233304 // The proxy responds to the connect with a 407, using a persistent
3305 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3306 MockRead data_reads1[] = {
3307 // No credentials.
3308 MockRead(ASYNC, 1,
3309 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3310 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3311 "Proxy-Connection: keep-alive\r\n"
3312 "Content-Length: 10\r\n\r\n"),
3313 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
ttuttle34f63b52015-03-05 04:33:013314
mmenked39192ee2015-12-09 00:57:233315 // Wrong credentials (wrong password).
3316 MockRead(ASYNC, 4,
3317 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3318 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3319 "Proxy-Connection: keep-alive\r\n"
3320 "Content-Length: 10\r\n\r\n"),
3321 // No response body because the test stops reading here.
3322 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3323 };
ttuttle34f63b52015-03-05 04:33:013324
Ryan Sleevib8d7ea02018-05-07 20:01:013325 SequencedSocketData data1(data_reads1, data_writes1);
mmenked39192ee2015-12-09 00:57:233326 data1.set_busy_before_sync_reads(true);
3327 session_deps_.socket_factory->AddSocketDataProvider(&data1);
ttuttle34f63b52015-03-05 04:33:013328
mmenked39192ee2015-12-09 00:57:233329 TestCompletionCallback callback1;
ttuttle34f63b52015-03-05 04:33:013330
bnc691fda62016-08-12 00:43:163331 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013332 EXPECT_THAT(callback1.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013333
mmenked39192ee2015-12-09 00:57:233334 TestNetLogEntry::List entries;
3335 log.GetEntries(&entries);
3336 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003337 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3338 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233339 ExpectLogContainsSomewhere(
3340 entries, pos,
mikecirone8b85c432016-09-08 19:11:003341 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3342 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013343
bnc691fda62016-08-12 00:43:163344 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233345 ASSERT_TRUE(response);
3346 ASSERT_TRUE(response->headers);
3347 EXPECT_TRUE(response->headers->IsKeepAlive());
3348 EXPECT_EQ(407, response->headers->response_code());
3349 EXPECT_EQ(10, response->headers->GetContentLength());
3350 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3351 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013352
mmenked39192ee2015-12-09 00:57:233353 TestCompletionCallback callback2;
ttuttle34f63b52015-03-05 04:33:013354
mmenked39192ee2015-12-09 00:57:233355 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163356 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3357 callback2.callback());
robpercival214763f2016-07-01 23:27:013358 EXPECT_THAT(callback2.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013359
bnc691fda62016-08-12 00:43:163360 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233361 ASSERT_TRUE(response);
3362 ASSERT_TRUE(response->headers);
3363 EXPECT_TRUE(response->headers->IsKeepAlive());
3364 EXPECT_EQ(407, response->headers->response_code());
3365 EXPECT_EQ(10, response->headers->GetContentLength());
3366 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3367 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013368
mmenked39192ee2015-12-09 00:57:233369 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3370 // out of scope.
3371 session->CloseAllConnections();
3372 }
ttuttle34f63b52015-03-05 04:33:013373}
3374
3375// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3376// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013377TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
mmenked39192ee2015-12-09 00:57:233378 // On the second pass, the body read of the auth challenge is synchronous, so
3379 // IsConnectedAndIdle returns false. The socket should still be drained and
3380 // reused. See http://crbug.com/544255.
3381 for (int i = 0; i < 2; ++i) {
3382 HttpRequestInfo request;
3383 request.method = "GET";
3384 request.url = GURL("https://www.example.org/");
3385 // Ensure that proxy authentication is attempted even
3386 // when the no authentication data flag is set.
3387 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:103388 request.traffic_annotation =
3389 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenked39192ee2015-12-09 00:57:233390
3391 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593392 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493393 ProxyResolutionService::CreateFixed("myproxy:70",
3394 TRAFFIC_ANNOTATION_FOR_TESTS);
mmenked39192ee2015-12-09 00:57:233395 BoundTestNetLog log;
3396 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093397 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenked39192ee2015-12-09 00:57:233398
bnc691fda62016-08-12 00:43:163399 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenked39192ee2015-12-09 00:57:233400
3401 // Since we have proxy, should try to establish tunnel.
3402 MockWrite data_writes1[] = {
3403 MockWrite(ASYNC, 0,
3404 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3405 "Host: www.example.org:443\r\n"
3406 "Proxy-Connection: keep-alive\r\n\r\n"),
3407
bnc691fda62016-08-12 00:43:163408 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233409 // be issuing -- the final header line contains the credentials.
3410 MockWrite(ASYNC, 3,
3411 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3412 "Host: www.example.org:443\r\n"
3413 "Proxy-Connection: keep-alive\r\n"
3414 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3415 };
3416
3417 // The proxy responds to the connect with a 407, using a persistent
3418 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3419 MockRead data_reads1[] = {
3420 // No credentials.
3421 MockRead(ASYNC, 1,
3422 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3423 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3424 "Content-Length: 10\r\n\r\n"),
3425 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
3426
3427 // Wrong credentials (wrong password).
3428 MockRead(ASYNC, 4,
3429 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3430 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3431 "Content-Length: 10\r\n\r\n"),
3432 // No response body because the test stops reading here.
3433 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3434 };
3435
Ryan Sleevib8d7ea02018-05-07 20:01:013436 SequencedSocketData data1(data_reads1, data_writes1);
mmenked39192ee2015-12-09 00:57:233437 data1.set_busy_before_sync_reads(true);
3438 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3439
3440 TestCompletionCallback callback1;
3441
bnc691fda62016-08-12 00:43:163442 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013443 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233444
3445 TestNetLogEntry::List entries;
3446 log.GetEntries(&entries);
3447 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003448 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3449 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233450 ExpectLogContainsSomewhere(
3451 entries, pos,
mikecirone8b85c432016-09-08 19:11:003452 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3453 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233454
bnc691fda62016-08-12 00:43:163455 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233456 ASSERT_TRUE(response);
3457 ASSERT_TRUE(response->headers);
3458 EXPECT_TRUE(response->headers->IsKeepAlive());
3459 EXPECT_EQ(407, response->headers->response_code());
3460 EXPECT_EQ(10, response->headers->GetContentLength());
3461 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3462 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3463
3464 TestCompletionCallback callback2;
3465
3466 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163467 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3468 callback2.callback());
robpercival214763f2016-07-01 23:27:013469 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233470
bnc691fda62016-08-12 00:43:163471 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233472 ASSERT_TRUE(response);
3473 ASSERT_TRUE(response->headers);
3474 EXPECT_TRUE(response->headers->IsKeepAlive());
3475 EXPECT_EQ(407, response->headers->response_code());
3476 EXPECT_EQ(10, response->headers->GetContentLength());
3477 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3478 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3479
3480 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3481 // out of scope.
3482 session->CloseAllConnections();
3483 }
3484}
3485
3486// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3487// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel, in
3488// the case the server sends extra data on the original socket, so it can't be
3489// reused.
bncd16676a2016-07-20 16:23:013490TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveExtraData) {
[email protected]cb9bf6ca2011-01-28 13:15:273491 HttpRequestInfo request;
3492 request.method = "GET";
bncce36dca22015-04-21 22:11:233493 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273494 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293495 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:103496 request.traffic_annotation =
3497 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:273498
[email protected]2d2697f92009-02-18 21:00:323499 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593500 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493501 ProxyResolutionService::CreateFixedFromPacResult(
3502 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513503 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073504 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093505 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:323506
[email protected]2d2697f92009-02-18 21:00:323507 // Since we have proxy, should try to establish tunnel.
3508 MockWrite data_writes1[] = {
mmenked39192ee2015-12-09 00:57:233509 MockWrite(ASYNC, 0,
3510 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173511 "Host: www.example.org:443\r\n"
3512 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233513 };
[email protected]2d2697f92009-02-18 21:00:323514
mmenked39192ee2015-12-09 00:57:233515 // The proxy responds to the connect with a 407, using a persistent, but sends
3516 // extra data, so the socket cannot be reused.
3517 MockRead data_reads1[] = {
3518 // No credentials.
3519 MockRead(ASYNC, 1,
3520 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3521 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3522 "Content-Length: 10\r\n\r\n"),
3523 MockRead(SYNCHRONOUS, 2, "0123456789"),
3524 MockRead(SYNCHRONOUS, 3, "I'm broken!"),
3525 };
3526
3527 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:233528 // After calling trans->RestartWithAuth(), this is the request we should
3529 // be issuing -- the final header line contains the credentials.
mmenked39192ee2015-12-09 00:57:233530 MockWrite(ASYNC, 0,
3531 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173532 "Host: www.example.org:443\r\n"
3533 "Proxy-Connection: keep-alive\r\n"
mmenked39192ee2015-12-09 00:57:233534 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3535
3536 MockWrite(ASYNC, 2,
3537 "GET / HTTP/1.1\r\n"
3538 "Host: www.example.org\r\n"
3539 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323540 };
3541
mmenked39192ee2015-12-09 00:57:233542 MockRead data_reads2[] = {
3543 MockRead(ASYNC, 1, "HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323544
mmenked39192ee2015-12-09 00:57:233545 MockRead(ASYNC, 3,
3546 "HTTP/1.1 200 OK\r\n"
3547 "Content-Type: text/html; charset=iso-8859-1\r\n"
3548 "Content-Length: 5\r\n\r\n"),
3549 // No response body because the test stops reading here.
3550 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 4),
[email protected]2d2697f92009-02-18 21:00:323551 };
3552
Ryan Sleevib8d7ea02018-05-07 20:01:013553 SequencedSocketData data1(data_reads1, data_writes1);
mmenked39192ee2015-12-09 00:57:233554 data1.set_busy_before_sync_reads(true);
[email protected]bb88e1d32013-05-03 23:11:073555 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:013556 SequencedSocketData data2(data_reads2, data_writes2);
mmenked39192ee2015-12-09 00:57:233557 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3558 SSLSocketDataProvider ssl(ASYNC, OK);
3559 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d2697f92009-02-18 21:00:323560
[email protected]49639fa2011-12-20 23:22:413561 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323562
bnc87dcefc2017-05-25 12:47:583563 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193564 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d2697f92009-02-18 21:00:323565
mmenked39192ee2015-12-09 00:57:233566 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013567 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233568
mmenke43758e62015-05-04 21:09:463569 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403570 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:393571 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003572 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3573 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:393574 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403575 entries, pos,
mikecirone8b85c432016-09-08 19:11:003576 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3577 NetLogEventPhase::NONE);
[email protected]2d2697f92009-02-18 21:00:323578
[email protected]1c773ea12009-04-28 19:58:423579 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243580 ASSERT_TRUE(response);
3581 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:323582 EXPECT_TRUE(response->headers->IsKeepAlive());
3583 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423584 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043585 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:323586
mmenked39192ee2015-12-09 00:57:233587 LoadTimingInfo load_timing_info;
3588 // CONNECT requests and responses are handled at the connect job level, so
3589 // the transaction does not yet have a connection.
3590 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3591
[email protected]49639fa2011-12-20 23:22:413592 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323593
mmenked39192ee2015-12-09 00:57:233594 rv =
3595 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013596 EXPECT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:323597
[email protected]2d2697f92009-02-18 21:00:323598 EXPECT_TRUE(response->headers->IsKeepAlive());
mmenked39192ee2015-12-09 00:57:233599 EXPECT_EQ(200, response->headers->response_code());
3600 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:423601 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]e772db3f2010-07-12 18:11:133602
mmenked39192ee2015-12-09 00:57:233603 // The password prompt info should not be set.
3604 EXPECT_FALSE(response->auth_challenge);
3605
3606 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3607 TestLoadTimingNotReusedWithPac(load_timing_info,
3608 CONNECT_TIMING_HAS_SSL_TIMES);
3609
3610 trans.reset();
[email protected]102e27c2011-02-23 01:01:313611 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:323612}
3613
mmenkee71e15332015-10-07 16:39:543614// Test the case a proxy closes a socket while the challenge body is being
3615// drained.
bncd16676a2016-07-20 16:23:013616TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHangupDuringBody) {
mmenkee71e15332015-10-07 16:39:543617 HttpRequestInfo request;
3618 request.method = "GET";
3619 request.url = GURL("https://www.example.org/");
3620 // Ensure that proxy authentication is attempted even
3621 // when the no authentication data flag is set.
3622 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:103623 request.traffic_annotation =
3624 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenkee71e15332015-10-07 16:39:543625
3626 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:493627 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
3628 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:093629 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenkee71e15332015-10-07 16:39:543630
bnc691fda62016-08-12 00:43:163631 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkee71e15332015-10-07 16:39:543632
3633 // Since we have proxy, should try to establish tunnel.
3634 MockWrite data_writes1[] = {
3635 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173636 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543637 "Proxy-Connection: keep-alive\r\n\r\n"),
3638 };
3639
3640 // The proxy responds to the connect with a 407, using a persistent
3641 // connection.
3642 MockRead data_reads1[] = {
3643 // No credentials.
3644 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3645 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3646 MockRead("Content-Length: 10\r\n\r\n"), MockRead("spam!"),
3647 // Server hands up in the middle of the body.
3648 MockRead(ASYNC, ERR_CONNECTION_CLOSED),
3649 };
3650
3651 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:163652 // After calling trans.RestartWithAuth(), this is the request we should
mmenkee71e15332015-10-07 16:39:543653 // be issuing -- the final header line contains the credentials.
3654 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173655 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543656 "Proxy-Connection: keep-alive\r\n"
3657 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3658
3659 MockWrite("GET / HTTP/1.1\r\n"
3660 "Host: www.example.org\r\n"
3661 "Connection: keep-alive\r\n\r\n"),
3662 };
3663
3664 MockRead data_reads2[] = {
3665 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3666
3667 MockRead("HTTP/1.1 200 OK\r\n"),
3668 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3669 MockRead("Content-Length: 5\r\n\r\n"),
3670 MockRead(SYNCHRONOUS, "hello"),
3671 };
3672
Ryan Sleevib8d7ea02018-05-07 20:01:013673 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenkee71e15332015-10-07 16:39:543674 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:013675 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenkee71e15332015-10-07 16:39:543676 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3677 SSLSocketDataProvider ssl(ASYNC, OK);
3678 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3679
3680 TestCompletionCallback callback;
3681
tfarina42834112016-09-22 13:38:203682 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013683 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543684
bnc691fda62016-08-12 00:43:163685 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543686 ASSERT_TRUE(response);
3687 ASSERT_TRUE(response->headers);
3688 EXPECT_TRUE(response->headers->IsKeepAlive());
3689 EXPECT_EQ(407, response->headers->response_code());
3690 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3691
bnc691fda62016-08-12 00:43:163692 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
robpercival214763f2016-07-01 23:27:013693 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543694
bnc691fda62016-08-12 00:43:163695 response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543696 ASSERT_TRUE(response);
3697 ASSERT_TRUE(response->headers);
3698 EXPECT_TRUE(response->headers->IsKeepAlive());
3699 EXPECT_EQ(200, response->headers->response_code());
3700 std::string body;
bnc691fda62016-08-12 00:43:163701 EXPECT_THAT(ReadTransaction(&trans, &body), IsOk());
mmenkee71e15332015-10-07 16:39:543702 EXPECT_EQ("hello", body);
3703}
3704
[email protected]a8e9b162009-03-12 00:06:443705// Test that we don't read the response body when we fail to establish a tunnel,
3706// even if the user cancels the proxy's auth attempt.
bncd16676a2016-07-20 16:23:013707TEST_F(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:273708 HttpRequestInfo request;
3709 request.method = "GET";
bncce36dca22015-04-21 22:11:233710 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:103711 request.traffic_annotation =
3712 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:273713
[email protected]a8e9b162009-03-12 00:06:443714 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:493715 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
3716 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]a8e9b162009-03-12 00:06:443717
danakj1fd259a02016-04-16 03:17:093718 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:443719
bnc691fda62016-08-12 00:43:163720 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a8e9b162009-03-12 00:06:443721
[email protected]a8e9b162009-03-12 00:06:443722 // Since we have proxy, should try to establish tunnel.
3723 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173724 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3725 "Host: www.example.org:443\r\n"
3726 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:443727 };
3728
3729 // The proxy responds to the connect with a 407.
3730 MockRead data_reads[] = {
ttuttle7933c112015-01-06 00:55:243731 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3732 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3733 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233734 MockRead("0123456789"),
ttuttle7933c112015-01-06 00:55:243735 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]a8e9b162009-03-12 00:06:443736 };
3737
Ryan Sleevib8d7ea02018-05-07 20:01:013738 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:073739 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:443740
[email protected]49639fa2011-12-20 23:22:413741 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:443742
tfarina42834112016-09-22 13:38:203743 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013744 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a8e9b162009-03-12 00:06:443745
3746 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013747 EXPECT_THAT(rv, IsOk());
[email protected]a8e9b162009-03-12 00:06:443748
bnc691fda62016-08-12 00:43:163749 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243750 ASSERT_TRUE(response);
3751 ASSERT_TRUE(response->headers);
[email protected]a8e9b162009-03-12 00:06:443752 EXPECT_TRUE(response->headers->IsKeepAlive());
3753 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423754 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:443755
3756 std::string response_data;
bnc691fda62016-08-12 00:43:163757 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:013758 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]e60e47a2010-07-14 03:37:183759
3760 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:313761 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:443762}
3763
ttuttle7933c112015-01-06 00:55:243764// Test that we don't pass extraneous headers from the proxy's response to the
3765// caller when the proxy responds to CONNECT with 407.
bncd16676a2016-07-20 16:23:013766TEST_F(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
ttuttle7933c112015-01-06 00:55:243767 HttpRequestInfo request;
3768 request.method = "GET";
bncce36dca22015-04-21 22:11:233769 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:103770 request.traffic_annotation =
3771 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle7933c112015-01-06 00:55:243772
3773 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:493774 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
3775 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle7933c112015-01-06 00:55:243776
danakj1fd259a02016-04-16 03:17:093777 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle7933c112015-01-06 00:55:243778
bnc691fda62016-08-12 00:43:163779 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle7933c112015-01-06 00:55:243780
3781 // Since we have proxy, should try to establish tunnel.
3782 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173783 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3784 "Host: www.example.org:443\r\n"
3785 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle7933c112015-01-06 00:55:243786 };
3787
3788 // The proxy responds to the connect with a 407.
3789 MockRead data_reads[] = {
3790 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3791 MockRead("X-Foo: bar\r\n"),
3792 MockRead("Set-Cookie: foo=bar\r\n"),
3793 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3794 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233795 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
ttuttle7933c112015-01-06 00:55:243796 };
3797
Ryan Sleevib8d7ea02018-05-07 20:01:013798 StaticSocketDataProvider data(data_reads, data_writes);
ttuttle7933c112015-01-06 00:55:243799 session_deps_.socket_factory->AddSocketDataProvider(&data);
3800
3801 TestCompletionCallback callback;
3802
tfarina42834112016-09-22 13:38:203803 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013804 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle7933c112015-01-06 00:55:243805
3806 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013807 EXPECT_THAT(rv, IsOk());
ttuttle7933c112015-01-06 00:55:243808
bnc691fda62016-08-12 00:43:163809 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243810 ASSERT_TRUE(response);
3811 ASSERT_TRUE(response->headers);
3812 EXPECT_TRUE(response->headers->IsKeepAlive());
3813 EXPECT_EQ(407, response->headers->response_code());
3814 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3815 EXPECT_FALSE(response->headers->HasHeader("X-Foo"));
3816 EXPECT_FALSE(response->headers->HasHeader("Set-Cookie"));
3817
3818 std::string response_data;
bnc691fda62016-08-12 00:43:163819 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:013820 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
ttuttle7933c112015-01-06 00:55:243821
3822 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
3823 session->CloseAllConnections();
3824}
3825
[email protected]8fdbcd22010-05-05 02:54:523826// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
3827// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
bncd16676a2016-07-20 16:23:013828TEST_F(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:523829 HttpRequestInfo request;
3830 request.method = "GET";
bncce36dca22015-04-21 22:11:233831 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:103832 request.traffic_annotation =
3833 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8fdbcd22010-05-05 02:54:523834
[email protected]cb9bf6ca2011-01-28 13:15:273835 // We are using a DIRECT connection (i.e. no proxy) for this session.
danakj1fd259a02016-04-16 03:17:093836 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:163837 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:273838
[email protected]8fdbcd22010-05-05 02:54:523839 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233840 MockWrite(
3841 "GET / HTTP/1.1\r\n"
3842 "Host: www.example.org\r\n"
3843 "Connection: keep-alive\r\n\r\n"),
[email protected]8fdbcd22010-05-05 02:54:523844 };
3845
3846 MockRead data_reads1[] = {
3847 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
3848 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3849 // Large content-length -- won't matter, as connection will be reset.
3850 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063851 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:523852 };
3853
Ryan Sleevib8d7ea02018-05-07 20:01:013854 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:073855 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:523856
[email protected]49639fa2011-12-20 23:22:413857 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:523858
tfarina42834112016-09-22 13:38:203859 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013860 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8fdbcd22010-05-05 02:54:523861
3862 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013863 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
[email protected]8fdbcd22010-05-05 02:54:523864}
3865
[email protected]7a67a8152010-11-05 18:31:103866// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
3867// through a non-authenticating proxy. The request should fail with
3868// ERR_UNEXPECTED_PROXY_AUTH.
3869// Note that it is impossible to detect if an HTTP server returns a 407 through
3870// a non-authenticating proxy - there is nothing to indicate whether the
3871// response came from the proxy or the server, so it is treated as if the proxy
3872// issued the challenge.
bncd16676a2016-07-20 16:23:013873TEST_F(HttpNetworkTransactionTest, HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:273874 HttpRequestInfo request;
3875 request.method = "GET";
bncce36dca22015-04-21 22:11:233876 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:103877 request.traffic_annotation =
3878 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:273879
Ramin Halavatica8d5252018-03-12 05:33:493880 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
3881 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513882 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073883 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093884 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:103885
[email protected]7a67a8152010-11-05 18:31:103886 // Since we have proxy, should try to establish tunnel.
3887 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:173888 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3889 "Host: www.example.org:443\r\n"
3890 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103891
rsleevidb16bb02015-11-12 23:47:173892 MockWrite("GET / HTTP/1.1\r\n"
3893 "Host: www.example.org\r\n"
3894 "Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103895 };
3896
3897 MockRead data_reads1[] = {
3898 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3899
3900 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
3901 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3902 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:063903 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:103904 };
3905
Ryan Sleevib8d7ea02018-05-07 20:01:013906 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:073907 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063908 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073909 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:103910
[email protected]49639fa2011-12-20 23:22:413911 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:103912
bnc691fda62016-08-12 00:43:163913 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]7a67a8152010-11-05 18:31:103914
bnc691fda62016-08-12 00:43:163915 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013916 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a67a8152010-11-05 18:31:103917
3918 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013919 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
mmenke43758e62015-05-04 21:09:463920 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403921 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:103922 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003923 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3924 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:103925 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403926 entries, pos,
mikecirone8b85c432016-09-08 19:11:003927 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3928 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:103929}
[email protected]2df19bb2010-08-25 20:13:463930
mmenke2a1781d2015-10-07 19:25:333931// Test a proxy auth scheme that allows default credentials and a proxy server
3932// that uses non-persistent connections.
bncd16676a2016-07-20 16:23:013933TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:333934 AuthAllowsDefaultCredentialsTunnelConnectionClose) {
3935 HttpRequestInfo request;
3936 request.method = "GET";
3937 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:103938 request.traffic_annotation =
3939 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:333940
3941 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593942 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493943 ProxyResolutionService::CreateFixedFromPacResult(
3944 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:333945
Jeremy Roman0579ed62017-08-29 15:56:193946 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:333947 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:193948 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:333949 mock_handler->set_allows_default_credentials(true);
3950 auth_handler_factory->AddMockHandler(mock_handler.release(),
3951 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:483952 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:333953
3954 // Add NetLog just so can verify load timing information gets a NetLog ID.
3955 NetLog net_log;
3956 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:093957 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:333958
3959 // Since we have proxy, should try to establish tunnel.
3960 MockWrite data_writes1[] = {
3961 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173962 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333963 "Proxy-Connection: keep-alive\r\n\r\n"),
3964 };
3965
3966 // The proxy responds to the connect with a 407, using a non-persistent
3967 // connection.
3968 MockRead data_reads1[] = {
3969 // No credentials.
3970 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3971 MockRead("Proxy-Authenticate: Mock\r\n"),
3972 MockRead("Proxy-Connection: close\r\n\r\n"),
3973 };
3974
3975 // Since the first connection couldn't be reused, need to establish another
3976 // once given credentials.
3977 MockWrite data_writes2[] = {
3978 // After calling trans->RestartWithAuth(), this is the request we should
3979 // be issuing -- the final header line contains the credentials.
3980 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173981 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333982 "Proxy-Connection: keep-alive\r\n"
3983 "Proxy-Authorization: auth_token\r\n\r\n"),
3984
3985 MockWrite("GET / HTTP/1.1\r\n"
3986 "Host: www.example.org\r\n"
3987 "Connection: keep-alive\r\n\r\n"),
3988 };
3989
3990 MockRead data_reads2[] = {
3991 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3992
3993 MockRead("HTTP/1.1 200 OK\r\n"),
3994 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3995 MockRead("Content-Length: 5\r\n\r\n"),
3996 MockRead(SYNCHRONOUS, "hello"),
3997 };
3998
Ryan Sleevib8d7ea02018-05-07 20:01:013999 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke2a1781d2015-10-07 19:25:334000 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:014001 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke2a1781d2015-10-07 19:25:334002 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4003 SSLSocketDataProvider ssl(ASYNC, OK);
4004 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4005
bnc87dcefc2017-05-25 12:47:584006 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194007 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334008
4009 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204010 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014011 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334012
4013 const HttpResponseInfo* response = trans->GetResponseInfo();
4014 ASSERT_TRUE(response);
4015 ASSERT_TRUE(response->headers);
4016 EXPECT_FALSE(response->headers->IsKeepAlive());
4017 EXPECT_EQ(407, response->headers->response_code());
4018 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4019 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
wezca1070932016-05-26 20:30:524020 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:334021
4022 LoadTimingInfo load_timing_info;
4023 // CONNECT requests and responses are handled at the connect job level, so
4024 // the transaction does not yet have a connection.
4025 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4026
4027 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014028 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334029 response = trans->GetResponseInfo();
4030 ASSERT_TRUE(response);
4031 ASSERT_TRUE(response->headers);
4032 EXPECT_TRUE(response->headers->IsKeepAlive());
4033 EXPECT_EQ(200, response->headers->response_code());
4034 EXPECT_EQ(5, response->headers->GetContentLength());
4035 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4036
4037 // The password prompt info should not be set.
4038 EXPECT_FALSE(response->auth_challenge);
4039
4040 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4041 TestLoadTimingNotReusedWithPac(load_timing_info,
4042 CONNECT_TIMING_HAS_SSL_TIMES);
4043
4044 trans.reset();
4045 session->CloseAllConnections();
4046}
4047
4048// Test a proxy auth scheme that allows default credentials and a proxy server
4049// that hangs up when credentials are initially sent.
bncd16676a2016-07-20 16:23:014050TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334051 AuthAllowsDefaultCredentialsTunnelServerClosesConnection) {
4052 HttpRequestInfo request;
4053 request.method = "GET";
4054 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104055 request.traffic_annotation =
4056 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334057
4058 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594059 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494060 ProxyResolutionService::CreateFixedFromPacResult(
4061 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334062
Jeremy Roman0579ed62017-08-29 15:56:194063 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334064 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194065 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334066 mock_handler->set_allows_default_credentials(true);
4067 auth_handler_factory->AddMockHandler(mock_handler.release(),
4068 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484069 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334070
4071 // Add NetLog just so can verify load timing information gets a NetLog ID.
4072 NetLog net_log;
4073 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094074 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334075
4076 // Should try to establish tunnel.
4077 MockWrite data_writes1[] = {
4078 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174079 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334080 "Proxy-Connection: keep-alive\r\n\r\n"),
4081
4082 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174083 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334084 "Proxy-Connection: keep-alive\r\n"
4085 "Proxy-Authorization: auth_token\r\n\r\n"),
4086 };
4087
4088 // The proxy responds to the connect with a 407, using a non-persistent
4089 // connection.
4090 MockRead data_reads1[] = {
4091 // No credentials.
4092 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4093 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4094 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4095 };
4096
4097 // Since the first connection was closed, need to establish another once given
4098 // credentials.
4099 MockWrite data_writes2[] = {
4100 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174101 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334102 "Proxy-Connection: keep-alive\r\n"
4103 "Proxy-Authorization: auth_token\r\n\r\n"),
4104
4105 MockWrite("GET / HTTP/1.1\r\n"
4106 "Host: www.example.org\r\n"
4107 "Connection: keep-alive\r\n\r\n"),
4108 };
4109
4110 MockRead data_reads2[] = {
4111 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
4112
4113 MockRead("HTTP/1.1 200 OK\r\n"),
4114 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4115 MockRead("Content-Length: 5\r\n\r\n"),
4116 MockRead(SYNCHRONOUS, "hello"),
4117 };
4118
Ryan Sleevib8d7ea02018-05-07 20:01:014119 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke2a1781d2015-10-07 19:25:334120 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:014121 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke2a1781d2015-10-07 19:25:334122 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4123 SSLSocketDataProvider ssl(ASYNC, OK);
4124 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4125
bnc87dcefc2017-05-25 12:47:584126 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194127 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334128
4129 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204130 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014131 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334132
4133 const HttpResponseInfo* response = trans->GetResponseInfo();
4134 ASSERT_TRUE(response);
4135 ASSERT_TRUE(response->headers);
4136 EXPECT_TRUE(response->headers->IsKeepAlive());
4137 EXPECT_EQ(407, response->headers->response_code());
4138 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4139 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4140 EXPECT_FALSE(response->auth_challenge);
4141
4142 LoadTimingInfo load_timing_info;
4143 // CONNECT requests and responses are handled at the connect job level, so
4144 // the transaction does not yet have a connection.
4145 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4146
4147 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014148 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334149
4150 response = trans->GetResponseInfo();
4151 ASSERT_TRUE(response);
4152 ASSERT_TRUE(response->headers);
4153 EXPECT_TRUE(response->headers->IsKeepAlive());
4154 EXPECT_EQ(200, response->headers->response_code());
4155 EXPECT_EQ(5, response->headers->GetContentLength());
4156 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4157
4158 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524159 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:334160
4161 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4162 TestLoadTimingNotReusedWithPac(load_timing_info,
4163 CONNECT_TIMING_HAS_SSL_TIMES);
4164
4165 trans.reset();
4166 session->CloseAllConnections();
4167}
4168
4169// Test a proxy auth scheme that allows default credentials and a proxy server
4170// that hangs up when credentials are initially sent, and hangs up again when
4171// they are retried.
bncd16676a2016-07-20 16:23:014172TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334173 AuthAllowsDefaultCredentialsTunnelServerClosesConnectionTwice) {
4174 HttpRequestInfo request;
4175 request.method = "GET";
4176 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104177 request.traffic_annotation =
4178 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334179
4180 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594181 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494182 ProxyResolutionService::CreateFixedFromPacResult(
4183 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334184
Jeremy Roman0579ed62017-08-29 15:56:194185 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334186 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194187 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334188 mock_handler->set_allows_default_credentials(true);
4189 auth_handler_factory->AddMockHandler(mock_handler.release(),
4190 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484191 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334192
4193 // Add NetLog just so can verify load timing information gets a NetLog ID.
4194 NetLog net_log;
4195 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094196 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334197
4198 // Should try to establish tunnel.
4199 MockWrite data_writes1[] = {
4200 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174201 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334202 "Proxy-Connection: keep-alive\r\n\r\n"),
4203
4204 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174205 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334206 "Proxy-Connection: keep-alive\r\n"
4207 "Proxy-Authorization: auth_token\r\n\r\n"),
4208 };
4209
4210 // The proxy responds to the connect with a 407, and then hangs up after the
4211 // second request is sent.
4212 MockRead data_reads1[] = {
4213 // No credentials.
4214 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4215 MockRead("Content-Length: 0\r\n"),
4216 MockRead("Proxy-Connection: keep-alive\r\n"),
4217 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4218 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4219 };
4220
4221 // HttpNetworkTransaction sees a reused connection that was closed with
4222 // ERR_CONNECTION_CLOSED, realized it might have been a race, so retries the
4223 // request.
4224 MockWrite data_writes2[] = {
4225 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174226 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334227 "Proxy-Connection: keep-alive\r\n\r\n"),
4228 };
4229
4230 // The proxy, having had more than enough of us, just hangs up.
4231 MockRead data_reads2[] = {
4232 // No credentials.
4233 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4234 };
4235
Ryan Sleevib8d7ea02018-05-07 20:01:014236 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke2a1781d2015-10-07 19:25:334237 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:014238 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke2a1781d2015-10-07 19:25:334239 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4240
bnc87dcefc2017-05-25 12:47:584241 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194242 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334243
4244 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204245 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014246 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334247
4248 const HttpResponseInfo* response = trans->GetResponseInfo();
4249 ASSERT_TRUE(response);
4250 ASSERT_TRUE(response->headers);
4251 EXPECT_TRUE(response->headers->IsKeepAlive());
4252 EXPECT_EQ(407, response->headers->response_code());
4253 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4254 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4255 EXPECT_FALSE(response->auth_challenge);
4256
4257 LoadTimingInfo load_timing_info;
4258 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4259
4260 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014261 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_EMPTY_RESPONSE));
mmenke2a1781d2015-10-07 19:25:334262
4263 trans.reset();
4264 session->CloseAllConnections();
4265}
4266
4267// Test a proxy auth scheme that allows default credentials and a proxy server
4268// that hangs up when credentials are initially sent, and sends a challenge
4269// again they are retried.
bncd16676a2016-07-20 16:23:014270TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334271 AuthAllowsDefaultCredentialsTunnelServerChallengesTwice) {
4272 HttpRequestInfo request;
4273 request.method = "GET";
4274 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104275 request.traffic_annotation =
4276 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334277
4278 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594279 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494280 ProxyResolutionService::CreateFixedFromPacResult(
4281 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334282
Jeremy Roman0579ed62017-08-29 15:56:194283 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334284 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194285 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334286 mock_handler->set_allows_default_credentials(true);
4287 auth_handler_factory->AddMockHandler(mock_handler.release(),
4288 HttpAuth::AUTH_PROXY);
4289 // Add another handler for the second challenge. It supports default
4290 // credentials, but they shouldn't be used, since they were already tried.
Jeremy Roman0579ed62017-08-29 15:56:194291 mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334292 mock_handler->set_allows_default_credentials(true);
4293 auth_handler_factory->AddMockHandler(mock_handler.release(),
4294 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484295 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334296
4297 // Add NetLog just so can verify load timing information gets a NetLog ID.
4298 NetLog net_log;
4299 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094300 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334301
4302 // Should try to establish tunnel.
4303 MockWrite data_writes1[] = {
4304 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174305 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334306 "Proxy-Connection: keep-alive\r\n\r\n"),
4307 };
4308
4309 // The proxy responds to the connect with a 407, using a non-persistent
4310 // connection.
4311 MockRead data_reads1[] = {
4312 // No credentials.
4313 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4314 MockRead("Proxy-Authenticate: Mock\r\n"),
4315 MockRead("Proxy-Connection: close\r\n\r\n"),
4316 };
4317
4318 // Since the first connection was closed, need to establish another once given
4319 // credentials.
4320 MockWrite data_writes2[] = {
4321 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174322 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334323 "Proxy-Connection: keep-alive\r\n"
4324 "Proxy-Authorization: auth_token\r\n\r\n"),
4325 };
4326
4327 MockRead data_reads2[] = {
4328 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4329 MockRead("Proxy-Authenticate: Mock\r\n"),
4330 MockRead("Proxy-Connection: close\r\n\r\n"),
4331 };
4332
Ryan Sleevib8d7ea02018-05-07 20:01:014333 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke2a1781d2015-10-07 19:25:334334 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:014335 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke2a1781d2015-10-07 19:25:334336 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4337 SSLSocketDataProvider ssl(ASYNC, OK);
4338 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4339
bnc87dcefc2017-05-25 12:47:584340 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194341 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334342
4343 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204344 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014345 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334346
4347 const HttpResponseInfo* response = trans->GetResponseInfo();
4348 ASSERT_TRUE(response);
4349 ASSERT_TRUE(response->headers);
4350 EXPECT_EQ(407, response->headers->response_code());
4351 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4352 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4353 EXPECT_FALSE(response->auth_challenge);
4354
4355 LoadTimingInfo load_timing_info;
4356 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4357
4358 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014359 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334360 response = trans->GetResponseInfo();
4361 ASSERT_TRUE(response);
4362 ASSERT_TRUE(response->headers);
4363 EXPECT_EQ(407, response->headers->response_code());
4364 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4365 EXPECT_TRUE(response->auth_challenge);
4366
4367 trans.reset();
4368 session->CloseAllConnections();
4369}
4370
asankae2257db2016-10-11 22:03:164371// A more nuanced test than GenerateAuthToken test which asserts that
4372// ERR_INVALID_AUTH_CREDENTIALS does not cause the auth scheme to be
4373// unnecessarily invalidated, and that if the server co-operates, the
4374// authentication handshake can continue with the same scheme but with a
4375// different identity.
4376TEST_F(HttpNetworkTransactionTest, NonPermanentGenerateAuthTokenError) {
4377 HttpRequestInfo request;
4378 request.method = "GET";
4379 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104380 request.traffic_annotation =
4381 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
asankae2257db2016-10-11 22:03:164382
Jeremy Roman0579ed62017-08-29 15:56:194383 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
asankae2257db2016-10-11 22:03:164384 auth_handler_factory->set_do_init_from_challenge(true);
4385
4386 // First handler. Uses default credentials, but barfs at generate auth token.
Jeremy Roman0579ed62017-08-29 15:56:194387 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164388 mock_handler->set_allows_default_credentials(true);
4389 mock_handler->set_allows_explicit_credentials(true);
4390 mock_handler->set_connection_based(true);
4391 mock_handler->SetGenerateExpectation(true, ERR_INVALID_AUTH_CREDENTIALS);
4392 auth_handler_factory->AddMockHandler(mock_handler.release(),
4393 HttpAuth::AUTH_SERVER);
4394
4395 // Add another handler for the second challenge. It supports default
4396 // credentials, but they shouldn't be used, since they were already tried.
Jeremy Roman0579ed62017-08-29 15:56:194397 mock_handler = std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164398 mock_handler->set_allows_default_credentials(true);
4399 mock_handler->set_allows_explicit_credentials(true);
4400 mock_handler->set_connection_based(true);
4401 auth_handler_factory->AddMockHandler(mock_handler.release(),
4402 HttpAuth::AUTH_SERVER);
4403 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
4404
4405 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4406
4407 MockWrite data_writes1[] = {
4408 MockWrite("GET / HTTP/1.1\r\n"
4409 "Host: www.example.org\r\n"
4410 "Connection: keep-alive\r\n\r\n"),
4411 };
4412
4413 MockRead data_reads1[] = {
4414 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4415 "WWW-Authenticate: Mock\r\n"
4416 "Connection: keep-alive\r\n\r\n"),
4417 };
4418
4419 // Identical to data_writes1[]. The AuthHandler encounters a
4420 // ERR_INVALID_AUTH_CREDENTIALS during the GenerateAuthToken stage, so the
4421 // transaction procceds without an authorization header.
4422 MockWrite data_writes2[] = {
4423 MockWrite("GET / HTTP/1.1\r\n"
4424 "Host: www.example.org\r\n"
4425 "Connection: keep-alive\r\n\r\n"),
4426 };
4427
4428 MockRead data_reads2[] = {
4429 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4430 "WWW-Authenticate: Mock\r\n"
4431 "Connection: keep-alive\r\n\r\n"),
4432 };
4433
4434 MockWrite data_writes3[] = {
4435 MockWrite("GET / HTTP/1.1\r\n"
4436 "Host: www.example.org\r\n"
4437 "Connection: keep-alive\r\n"
4438 "Authorization: auth_token\r\n\r\n"),
4439 };
4440
4441 MockRead data_reads3[] = {
4442 MockRead("HTTP/1.1 200 OK\r\n"
4443 "Content-Length: 5\r\n"
4444 "Content-Type: text/plain\r\n"
4445 "Connection: keep-alive\r\n\r\n"
4446 "Hello"),
4447 };
4448
Ryan Sleevib8d7ea02018-05-07 20:01:014449 StaticSocketDataProvider data1(data_reads1, data_writes1);
asankae2257db2016-10-11 22:03:164450 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4451
Ryan Sleevib8d7ea02018-05-07 20:01:014452 StaticSocketDataProvider data2(data_reads2, data_writes2);
asankae2257db2016-10-11 22:03:164453 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4454
Ryan Sleevib8d7ea02018-05-07 20:01:014455 StaticSocketDataProvider data3(data_reads3, data_writes3);
asankae2257db2016-10-11 22:03:164456 session_deps_.socket_factory->AddSocketDataProvider(&data3);
4457
bnc87dcefc2017-05-25 12:47:584458 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194459 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
asankae2257db2016-10-11 22:03:164460
4461 TestCompletionCallback callback;
4462 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4463 EXPECT_THAT(callback.GetResult(rv), IsOk());
4464
4465 const HttpResponseInfo* response = trans->GetResponseInfo();
4466 ASSERT_TRUE(response);
4467 ASSERT_TRUE(response->headers);
4468 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4469
4470 // The following three tests assert that an authentication challenge was
4471 // received and that the stack is ready to respond to the challenge using
4472 // ambient credentials.
4473 EXPECT_EQ(401, response->headers->response_code());
4474 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4475 EXPECT_FALSE(response->auth_challenge);
4476
4477 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4478 EXPECT_THAT(callback.GetResult(rv), IsOk());
4479 response = trans->GetResponseInfo();
4480 ASSERT_TRUE(response);
4481 ASSERT_TRUE(response->headers);
4482
4483 // The following three tests assert that an authentication challenge was
4484 // received and that the stack needs explicit credentials before it is ready
4485 // to respond to the challenge.
4486 EXPECT_EQ(401, response->headers->response_code());
4487 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4488 EXPECT_TRUE(response->auth_challenge);
4489
4490 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4491 EXPECT_THAT(callback.GetResult(rv), IsOk());
4492 response = trans->GetResponseInfo();
4493 ASSERT_TRUE(response);
4494 ASSERT_TRUE(response->headers);
4495 EXPECT_EQ(200, response->headers->response_code());
4496
4497 trans.reset();
4498 session->CloseAllConnections();
4499}
4500
Matt Menked1eb6d42018-01-17 04:54:064501// Proxy resolver that returns a proxy with the same host and port for different
4502// schemes, based on the path of the URL being requests.
4503class SameProxyWithDifferentSchemesProxyResolver : public ProxyResolver {
4504 public:
4505 SameProxyWithDifferentSchemesProxyResolver() {}
4506 ~SameProxyWithDifferentSchemesProxyResolver() override {}
4507
4508 static std::string ProxyHostPortPairAsString() { return "proxy.test:10000"; }
4509
4510 static HostPortPair ProxyHostPortPair() {
4511 return HostPortPair::FromString(ProxyHostPortPairAsString());
4512 }
4513
4514 // ProxyResolver implementation.
4515 int GetProxyForURL(const GURL& url,
4516 ProxyInfo* results,
Bence Békycc5b88a2018-05-25 20:24:174517 CompletionOnceCallback callback,
Matt Menked1eb6d42018-01-17 04:54:064518 std::unique_ptr<Request>* request,
4519 const NetLogWithSource& /*net_log*/) override {
4520 *results = ProxyInfo();
Ramin Halavati921731ea2018-03-16 08:24:574521 results->set_traffic_annotation(
4522 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
Matt Menked1eb6d42018-01-17 04:54:064523 if (url.path() == "/socks4") {
4524 results->UsePacString("SOCKS " + ProxyHostPortPairAsString());
4525 return OK;
4526 }
4527 if (url.path() == "/socks5") {
4528 results->UsePacString("SOCKS5 " + ProxyHostPortPairAsString());
4529 return OK;
4530 }
4531 if (url.path() == "/http") {
4532 results->UsePacString("PROXY " + ProxyHostPortPairAsString());
4533 return OK;
4534 }
4535 if (url.path() == "/https") {
4536 results->UsePacString("HTTPS " + ProxyHostPortPairAsString());
4537 return OK;
4538 }
4539 NOTREACHED();
4540 return ERR_NOT_IMPLEMENTED;
4541 }
4542
4543 private:
4544 DISALLOW_COPY_AND_ASSIGN(SameProxyWithDifferentSchemesProxyResolver);
4545};
4546
4547class SameProxyWithDifferentSchemesProxyResolverFactory
4548 : public ProxyResolverFactory {
4549 public:
4550 SameProxyWithDifferentSchemesProxyResolverFactory()
4551 : ProxyResolverFactory(false) {}
4552
Lily Houghton99597862018-03-07 16:40:424553 int CreateProxyResolver(const scoped_refptr<PacFileData>& pac_script,
4554 std::unique_ptr<ProxyResolver>* resolver,
Bence Békycc5b88a2018-05-25 20:24:174555 CompletionOnceCallback callback,
Lily Houghton99597862018-03-07 16:40:424556 std::unique_ptr<Request>* request) override {
Matt Menked1eb6d42018-01-17 04:54:064557 *resolver = std::make_unique<SameProxyWithDifferentSchemesProxyResolver>();
4558 return OK;
4559 }
4560
4561 private:
4562 DISALLOW_COPY_AND_ASSIGN(SameProxyWithDifferentSchemesProxyResolverFactory);
4563};
4564
4565// Check that when different proxy schemes are all applied to a proxy at the
4566// same address, the sonnections are not grouped together. i.e., a request to
4567// foo.com using proxy.com as an HTTPS proxy won't use the same socket as a
4568// request to foo.com using proxy.com as an HTTP proxy.
4569TEST_F(HttpNetworkTransactionTest, SameDestinationForDifferentProxyTypes) {
Ramin Halavatica8d5252018-03-12 05:33:494570 session_deps_.proxy_resolution_service =
4571 std::make_unique<ProxyResolutionService>(
4572 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
4573 ProxyConfig::CreateAutoDetect(), TRAFFIC_ANNOTATION_FOR_TESTS)),
4574 std::make_unique<SameProxyWithDifferentSchemesProxyResolverFactory>(),
4575 nullptr);
Matt Menked1eb6d42018-01-17 04:54:064576
4577 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4578
4579 MockWrite socks_writes[] = {
4580 MockWrite(SYNCHRONOUS, kSOCKS4OkRequestLocalHostPort80,
4581 kSOCKS4OkRequestLocalHostPort80Length),
4582 MockWrite(SYNCHRONOUS,
4583 "GET /socks4 HTTP/1.1\r\n"
4584 "Host: test\r\n"
4585 "Connection: keep-alive\r\n\r\n"),
4586 };
4587 MockRead socks_reads[] = {
4588 MockRead(SYNCHRONOUS, kSOCKS4OkReply, kSOCKS4OkReplyLength),
4589 MockRead("HTTP/1.0 200 OK\r\n"
4590 "Connection: keep-alive\r\n"
4591 "Content-Length: 15\r\n\r\n"
4592 "SOCKS4 Response"),
4593 };
Ryan Sleevib8d7ea02018-05-07 20:01:014594 StaticSocketDataProvider socks_data(socks_reads, socks_writes);
Matt Menked1eb6d42018-01-17 04:54:064595 session_deps_.socket_factory->AddSocketDataProvider(&socks_data);
4596
4597 const char kSOCKS5Request[] = {
4598 0x05, // Version
4599 0x01, // Command (CONNECT)
4600 0x00, // Reserved
4601 0x03, // Address type (DOMAINNAME)
4602 0x04, // Length of domain (4)
4603 't', 'e', 's', 't', // Domain string
4604 0x00, 0x50, // 16-bit port (80)
4605 };
4606 MockWrite socks5_writes[] = {
4607 MockWrite(ASYNC, kSOCKS5GreetRequest, kSOCKS5GreetRequestLength),
4608 MockWrite(ASYNC, kSOCKS5Request, arraysize(kSOCKS5Request)),
4609 MockWrite(SYNCHRONOUS,
4610 "GET /socks5 HTTP/1.1\r\n"
4611 "Host: test\r\n"
4612 "Connection: keep-alive\r\n\r\n"),
4613 };
4614 MockRead socks5_reads[] = {
4615 MockRead(ASYNC, kSOCKS5GreetResponse, kSOCKS5GreetResponseLength),
4616 MockRead(ASYNC, kSOCKS5OkResponse, kSOCKS5OkResponseLength),
4617 MockRead("HTTP/1.0 200 OK\r\n"
4618 "Connection: keep-alive\r\n"
4619 "Content-Length: 15\r\n\r\n"
4620 "SOCKS5 Response"),
4621 };
Ryan Sleevib8d7ea02018-05-07 20:01:014622 StaticSocketDataProvider socks5_data(socks5_reads, socks5_writes);
Matt Menked1eb6d42018-01-17 04:54:064623 session_deps_.socket_factory->AddSocketDataProvider(&socks5_data);
4624
4625 MockWrite http_writes[] = {
4626 MockWrite(SYNCHRONOUS,
4627 "GET http://test/http HTTP/1.1\r\n"
4628 "Host: test\r\n"
4629 "Proxy-Connection: keep-alive\r\n\r\n"),
4630 };
4631 MockRead http_reads[] = {
4632 MockRead("HTTP/1.1 200 OK\r\n"
4633 "Proxy-Connection: keep-alive\r\n"
4634 "Content-Length: 13\r\n\r\n"
4635 "HTTP Response"),
4636 };
Ryan Sleevib8d7ea02018-05-07 20:01:014637 StaticSocketDataProvider http_data(http_reads, http_writes);
Matt Menked1eb6d42018-01-17 04:54:064638 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
4639
4640 MockWrite https_writes[] = {
4641 MockWrite(SYNCHRONOUS,
4642 "GET http://test/https HTTP/1.1\r\n"
4643 "Host: test\r\n"
4644 "Proxy-Connection: keep-alive\r\n\r\n"),
4645 };
4646 MockRead https_reads[] = {
4647 MockRead("HTTP/1.1 200 OK\r\n"
4648 "Proxy-Connection: keep-alive\r\n"
4649 "Content-Length: 14\r\n\r\n"
4650 "HTTPS Response"),
4651 };
Ryan Sleevib8d7ea02018-05-07 20:01:014652 StaticSocketDataProvider https_data(https_reads, https_writes);
Matt Menked1eb6d42018-01-17 04:54:064653 session_deps_.socket_factory->AddSocketDataProvider(&https_data);
4654 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
4655 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4656
4657 struct TestCase {
4658 GURL url;
4659 std::string expected_response;
4660 // How many idle sockets there should be in the SOCKS proxy socket pool
4661 // after the test.
4662 int expected_idle_socks_sockets;
4663 // How many idle sockets there should be in the HTTP proxy socket pool after
4664 // the test.
4665 int expected_idle_http_sockets;
4666 } const kTestCases[] = {
4667 {GURL("http://test/socks4"), "SOCKS4 Response", 1, 0},
4668 {GURL("http://test/socks5"), "SOCKS5 Response", 2, 0},
4669 {GURL("http://test/http"), "HTTP Response", 2, 1},
4670 {GURL("http://test/https"), "HTTPS Response", 2, 2},
4671 };
4672
4673 for (const auto& test_case : kTestCases) {
4674 HttpRequestInfo request;
4675 request.method = "GET";
4676 request.url = test_case.url;
Ramin Halavatib5e433e62018-02-07 07:41:104677 request.traffic_annotation =
4678 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Matt Menked1eb6d42018-01-17 04:54:064679 std::unique_ptr<HttpNetworkTransaction> trans =
4680 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
4681 session.get());
4682 TestCompletionCallback callback;
4683 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4684 EXPECT_THAT(callback.GetResult(rv), IsOk());
4685
4686 const HttpResponseInfo* response = trans->GetResponseInfo();
4687 ASSERT_TRUE(response);
4688 ASSERT_TRUE(response->headers);
4689 EXPECT_EQ(200, response->headers->response_code());
4690 std::string response_data;
4691 EXPECT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
4692 EXPECT_EQ(test_case.expected_response, response_data);
4693
4694 // Return the socket to the socket pool, so can make sure it's not used for
4695 // the next requests.
4696 trans.reset();
4697 base::RunLoop().RunUntilIdle();
4698
4699 // Check the number of idle sockets in the pool, to make sure that used
4700 // sockets are indeed being returned to the socket pool. If each request
4701 // doesn't return an idle socket to the pool, the test would incorrectly
4702 // pass.
4703 EXPECT_EQ(
4704 test_case.expected_idle_socks_sockets,
4705 session
4706 ->GetSocketPoolForSOCKSProxy(
4707 HttpNetworkSession::NORMAL_SOCKET_POOL,
4708 SameProxyWithDifferentSchemesProxyResolver::ProxyHostPortPair())
4709 ->IdleSocketCount());
4710 EXPECT_EQ(
4711 test_case.expected_idle_http_sockets,
4712 session
4713 ->GetSocketPoolForHTTPProxy(
4714 HttpNetworkSession::NORMAL_SOCKET_POOL,
4715 SameProxyWithDifferentSchemesProxyResolver::ProxyHostPortPair())
4716 ->IdleSocketCount());
4717 }
4718}
4719
[email protected]029c83b62013-01-24 05:28:204720// Test the load timing for HTTPS requests with an HTTP proxy.
bncd16676a2016-07-20 16:23:014721TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:204722 HttpRequestInfo request1;
4723 request1.method = "GET";
bncce36dca22015-04-21 22:11:234724 request1.url = GURL("https://www.example.org/1");
Ramin Halavatib5e433e62018-02-07 07:41:104725 request1.traffic_annotation =
4726 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:204727
4728 HttpRequestInfo request2;
4729 request2.method = "GET";
bncce36dca22015-04-21 22:11:234730 request2.url = GURL("https://www.example.org/2");
Ramin Halavatib5e433e62018-02-07 07:41:104731 request2.traffic_annotation =
4732 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:204733
4734 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:494735 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
4736 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:514737 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074738 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094739 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:204740
4741 // Since we have proxy, should try to establish tunnel.
4742 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174743 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4744 "Host: www.example.org:443\r\n"
4745 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204746
rsleevidb16bb02015-11-12 23:47:174747 MockWrite("GET /1 HTTP/1.1\r\n"
4748 "Host: www.example.org\r\n"
4749 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204750
rsleevidb16bb02015-11-12 23:47:174751 MockWrite("GET /2 HTTP/1.1\r\n"
4752 "Host: www.example.org\r\n"
4753 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204754 };
4755
4756 // The proxy responds to the connect with a 407, using a persistent
4757 // connection.
4758 MockRead data_reads1[] = {
4759 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4760
4761 MockRead("HTTP/1.1 200 OK\r\n"),
4762 MockRead("Content-Length: 1\r\n\r\n"),
4763 MockRead(SYNCHRONOUS, "1"),
4764
4765 MockRead("HTTP/1.1 200 OK\r\n"),
4766 MockRead("Content-Length: 2\r\n\r\n"),
4767 MockRead(SYNCHRONOUS, "22"),
4768 };
4769
Ryan Sleevib8d7ea02018-05-07 20:01:014770 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:074771 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:204772 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074773 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:204774
4775 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:584776 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:194777 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204778
4779 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014780 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204781
4782 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014783 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204784
4785 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:524786 ASSERT_TRUE(response1);
tbansal2ecbbc72016-10-06 17:15:474787 EXPECT_TRUE(response1->proxy_server.is_http());
wezca1070932016-05-26 20:30:524788 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:204789 EXPECT_EQ(1, response1->headers->GetContentLength());
4790
4791 LoadTimingInfo load_timing_info1;
4792 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4793 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
4794
4795 trans1.reset();
4796
4797 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:584798 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:194799 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204800
4801 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014802 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204803
4804 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:014805 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204806
4807 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:524808 ASSERT_TRUE(response2);
tbansal2ecbbc72016-10-06 17:15:474809 EXPECT_TRUE(response2->proxy_server.is_http());
wezca1070932016-05-26 20:30:524810 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:204811 EXPECT_EQ(2, response2->headers->GetContentLength());
4812
4813 LoadTimingInfo load_timing_info2;
4814 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4815 TestLoadTimingReused(load_timing_info2);
4816
4817 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
4818
4819 trans2.reset();
4820 session->CloseAllConnections();
4821}
4822
4823// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
bncd16676a2016-07-20 16:23:014824TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:204825 HttpRequestInfo request1;
4826 request1.method = "GET";
bncce36dca22015-04-21 22:11:234827 request1.url = GURL("https://www.example.org/1");
Ramin Halavatib5e433e62018-02-07 07:41:104828 request1.traffic_annotation =
4829 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:204830
4831 HttpRequestInfo request2;
4832 request2.method = "GET";
bncce36dca22015-04-21 22:11:234833 request2.url = GURL("https://www.example.org/2");
Ramin Halavatib5e433e62018-02-07 07:41:104834 request2.traffic_annotation =
4835 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:204836
4837 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594838 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494839 ProxyResolutionService::CreateFixedFromPacResult(
4840 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:514841 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074842 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094843 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:204844
4845 // Since we have proxy, should try to establish tunnel.
4846 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174847 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4848 "Host: www.example.org:443\r\n"
4849 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204850
rsleevidb16bb02015-11-12 23:47:174851 MockWrite("GET /1 HTTP/1.1\r\n"
4852 "Host: www.example.org\r\n"
4853 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204854
rsleevidb16bb02015-11-12 23:47:174855 MockWrite("GET /2 HTTP/1.1\r\n"
4856 "Host: www.example.org\r\n"
4857 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204858 };
4859
4860 // The proxy responds to the connect with a 407, using a persistent
4861 // connection.
4862 MockRead data_reads1[] = {
4863 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4864
4865 MockRead("HTTP/1.1 200 OK\r\n"),
4866 MockRead("Content-Length: 1\r\n\r\n"),
4867 MockRead(SYNCHRONOUS, "1"),
4868
4869 MockRead("HTTP/1.1 200 OK\r\n"),
4870 MockRead("Content-Length: 2\r\n\r\n"),
4871 MockRead(SYNCHRONOUS, "22"),
4872 };
4873
Ryan Sleevib8d7ea02018-05-07 20:01:014874 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:074875 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:204876 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074877 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:204878
4879 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:584880 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:194881 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204882
4883 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014884 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204885
4886 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014887 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204888
4889 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:524890 ASSERT_TRUE(response1);
4891 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:204892 EXPECT_EQ(1, response1->headers->GetContentLength());
4893
4894 LoadTimingInfo load_timing_info1;
4895 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4896 TestLoadTimingNotReusedWithPac(load_timing_info1,
4897 CONNECT_TIMING_HAS_SSL_TIMES);
4898
4899 trans1.reset();
4900
4901 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:584902 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:194903 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204904
4905 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014906 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204907
4908 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:014909 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204910
4911 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:524912 ASSERT_TRUE(response2);
4913 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:204914 EXPECT_EQ(2, response2->headers->GetContentLength());
4915
4916 LoadTimingInfo load_timing_info2;
4917 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4918 TestLoadTimingReusedWithPac(load_timing_info2);
4919
4920 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
4921
4922 trans2.reset();
4923 session->CloseAllConnections();
4924}
4925
[email protected]2df19bb2010-08-25 20:13:464926// Test a simple get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:014927TEST_F(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:274928 HttpRequestInfo request;
4929 request.method = "GET";
bncce36dca22015-04-21 22:11:234930 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104931 request.traffic_annotation =
4932 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:274933
[email protected]2df19bb2010-08-25 20:13:464934 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:494935 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
4936 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:514937 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074938 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094939 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:464940
[email protected]2df19bb2010-08-25 20:13:464941 // Since we have proxy, should use full url
4942 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:234943 MockWrite(
4944 "GET http://www.example.org/ HTTP/1.1\r\n"
4945 "Host: www.example.org\r\n"
4946 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:464947 };
4948
4949 MockRead data_reads1[] = {
4950 MockRead("HTTP/1.1 200 OK\r\n"),
4951 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4952 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064953 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:464954 };
4955
Ryan Sleevib8d7ea02018-05-07 20:01:014956 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:074957 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:064958 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074959 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:464960
[email protected]49639fa2011-12-20 23:22:414961 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:464962
bnc691fda62016-08-12 00:43:164963 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:504964
bnc691fda62016-08-12 00:43:164965 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014966 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:464967
4968 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014969 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:464970
[email protected]58e32bb2013-01-21 18:23:254971 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:164972 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:254973 TestLoadTimingNotReused(load_timing_info,
4974 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4975
bnc691fda62016-08-12 00:43:164976 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:524977 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:464978
tbansal2ecbbc72016-10-06 17:15:474979 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:464980 EXPECT_TRUE(response->headers->IsKeepAlive());
4981 EXPECT_EQ(200, response->headers->response_code());
4982 EXPECT_EQ(100, response->headers->GetContentLength());
4983 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4984
4985 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524986 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:464987}
4988
[email protected]7642b5ae2010-09-01 20:55:174989// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:014990TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:274991 HttpRequestInfo request;
4992 request.method = "GET";
bncce36dca22015-04-21 22:11:234993 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104994 request.traffic_annotation =
4995 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:274996
[email protected]7642b5ae2010-09-01 20:55:174997 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:494998 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
4999 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515000 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075001 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095002 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:175003
bncce36dca22015-04-21 22:11:235004 // fetch http://www.example.org/ via SPDY
Ryan Hamilton0239aac2018-05-19 00:03:135005 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:455006 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415007 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]7642b5ae2010-09-01 20:55:175008
Ryan Hamilton0239aac2018-05-19 00:03:135009 spdy::SpdySerializedFrame resp(
5010 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
5011 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:175012 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415013 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]7642b5ae2010-09-01 20:55:175014 };
5015
Ryan Sleevib8d7ea02018-05-07 20:01:015016 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075017 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:175018
[email protected]8ddf8322012-02-23 18:08:065019 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365020 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075021 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:175022
[email protected]49639fa2011-12-20 23:22:415023 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:175024
bnc691fda62016-08-12 00:43:165025 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505026
bnc691fda62016-08-12 00:43:165027 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015028 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7642b5ae2010-09-01 20:55:175029
5030 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015031 EXPECT_THAT(rv, IsOk());
[email protected]7642b5ae2010-09-01 20:55:175032
[email protected]58e32bb2013-01-21 18:23:255033 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165034 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255035 TestLoadTimingNotReused(load_timing_info,
5036 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5037
bnc691fda62016-08-12 00:43:165038 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525039 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:475040 EXPECT_TRUE(response->proxy_server.is_https());
wezca1070932016-05-26 20:30:525041 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025042 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]7642b5ae2010-09-01 20:55:175043
5044 std::string response_data;
bnc691fda62016-08-12 00:43:165045 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235046 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:175047}
5048
[email protected]1c173852014-06-19 12:51:505049// Verifies that a session which races and wins against the owning transaction
5050// (completing prior to host resolution), doesn't fail the transaction.
5051// Regression test for crbug.com/334413.
bncd16676a2016-07-20 16:23:015052TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
[email protected]1c173852014-06-19 12:51:505053 HttpRequestInfo request;
5054 request.method = "GET";
bncce36dca22015-04-21 22:11:235055 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105056 request.traffic_annotation =
5057 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c173852014-06-19 12:51:505058
5059 // Configure SPDY proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495060 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5061 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515062 BoundTestNetLog log;
[email protected]1c173852014-06-19 12:51:505063 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095064 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1c173852014-06-19 12:51:505065
bncce36dca22015-04-21 22:11:235066 // Fetch http://www.example.org/ through the SPDY proxy.
Ryan Hamilton0239aac2018-05-19 00:03:135067 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:455068 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415069 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]1c173852014-06-19 12:51:505070
Ryan Hamilton0239aac2018-05-19 00:03:135071 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
5072 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]1c173852014-06-19 12:51:505073 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415074 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]1c173852014-06-19 12:51:505075 };
5076
Ryan Sleevib8d7ea02018-05-07 20:01:015077 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]1c173852014-06-19 12:51:505078 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
5079
5080 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365081 ssl.next_proto = kProtoHTTP2;
[email protected]1c173852014-06-19 12:51:505082 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5083
5084 TestCompletionCallback callback1;
5085
bnc691fda62016-08-12 00:43:165086 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1c173852014-06-19 12:51:505087
5088 // Stall the hostname resolution begun by the transaction.
5089 session_deps_.host_resolver->set_synchronous_mode(false);
5090 session_deps_.host_resolver->set_ondemand_mode(true);
5091
bnc691fda62016-08-12 00:43:165092 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015093 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c173852014-06-19 12:51:505094
5095 // Race a session to the proxy, which completes first.
5096 session_deps_.host_resolver->set_ondemand_mode(false);
Paul Jensena457017a2018-01-19 23:52:045097 SpdySessionKey key(HostPortPair("proxy", 70), ProxyServer::Direct(),
5098 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]1c173852014-06-19 12:51:505099 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:525100 CreateSpdySession(session.get(), key, log.bound());
[email protected]1c173852014-06-19 12:51:505101
5102 // Unstall the resolution begun by the transaction.
5103 session_deps_.host_resolver->set_ondemand_mode(true);
5104 session_deps_.host_resolver->ResolveAllPending();
5105
5106 EXPECT_FALSE(callback1.have_result());
5107 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015108 EXPECT_THAT(rv, IsOk());
[email protected]1c173852014-06-19 12:51:505109
bnc691fda62016-08-12 00:43:165110 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525111 ASSERT_TRUE(response);
5112 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025113 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]1c173852014-06-19 12:51:505114
5115 std::string response_data;
bnc691fda62016-08-12 00:43:165116 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]1c173852014-06-19 12:51:505117 EXPECT_EQ(kUploadData, response_data);
5118}
5119
[email protected]dc7bd1c52010-11-12 00:01:135120// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015121TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:275122 HttpRequestInfo request;
5123 request.method = "GET";
bncce36dca22015-04-21 22:11:235124 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105125 request.traffic_annotation =
5126 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275127
[email protected]79cb5c12011-09-12 13:12:045128 // Configure against https proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495129 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5130 "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515131 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075132 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095133 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:135134
[email protected]dc7bd1c52010-11-12 00:01:135135 // The first request will be a bare GET, the second request will be a
5136 // GET with a Proxy-Authorization header.
bncb26024382016-06-29 02:39:455137 spdy_util_.set_default_url(request.url);
Ryan Hamilton0239aac2018-05-19 00:03:135138 spdy::SpdySerializedFrame req_get(
Bence Béky27ad0a12018-02-08 00:35:485139 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:385140 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]dc7bd1c52010-11-12 00:01:135141 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:465142 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:135143 };
Ryan Hamilton0239aac2018-05-19 00:03:135144 spdy::SpdySerializedFrame req_get_authorization(spdy_util_.ConstructSpdyGet(
bncdf80d44fd2016-07-15 20:27:415145 kExtraAuthorizationHeaders, arraysize(kExtraAuthorizationHeaders) / 2, 3,
Bence Béky27ad0a12018-02-08 00:35:485146 LOWEST));
[email protected]dc7bd1c52010-11-12 00:01:135147 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415148 CreateMockWrite(req_get, 0), CreateMockWrite(req_get_authorization, 3),
[email protected]dc7bd1c52010-11-12 00:01:135149 };
5150
5151 // The first response is a 407 proxy authentication challenge, and the second
5152 // response will be a 200 response since the second request includes a valid
5153 // Authorization header.
5154 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:465155 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:135156 };
Ryan Hamilton0239aac2018-05-19 00:03:135157 spdy::SpdySerializedFrame resp_authentication(
5158 spdy_util_.ConstructSpdyReplyError(
5159 "407", kExtraAuthenticationHeaders,
5160 arraysize(kExtraAuthenticationHeaders) / 2, 1));
5161 spdy::SpdySerializedFrame body_authentication(
bncdf80d44fd2016-07-15 20:27:415162 spdy_util_.ConstructSpdyDataFrame(1, true));
Ryan Hamilton0239aac2018-05-19 00:03:135163 spdy::SpdySerializedFrame resp_data(
5164 spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
5165 spdy::SpdySerializedFrame body_data(
5166 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:135167 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415168 CreateMockRead(resp_authentication, 1),
bnceb9aa7112017-01-05 01:03:465169 CreateMockRead(body_authentication, 2, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415170 CreateMockRead(resp_data, 4),
5171 CreateMockRead(body_data, 5),
rch8e6c6c42015-05-01 14:05:135172 MockRead(ASYNC, 0, 6),
[email protected]dc7bd1c52010-11-12 00:01:135173 };
5174
Ryan Sleevib8d7ea02018-05-07 20:01:015175 SequencedSocketData data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075176 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:135177
[email protected]8ddf8322012-02-23 18:08:065178 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365179 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075180 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:135181
[email protected]49639fa2011-12-20 23:22:415182 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:135183
bnc691fda62016-08-12 00:43:165184 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]dc7bd1c52010-11-12 00:01:135185
bnc691fda62016-08-12 00:43:165186 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015187 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:135188
5189 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015190 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:135191
bnc691fda62016-08-12 00:43:165192 const HttpResponseInfo* const response = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:135193
wezca1070932016-05-26 20:30:525194 ASSERT_TRUE(response);
5195 ASSERT_TRUE(response->headers);
[email protected]dc7bd1c52010-11-12 00:01:135196 EXPECT_EQ(407, response->headers->response_code());
5197 EXPECT_TRUE(response->was_fetched_via_spdy);
asanka098c0092016-06-16 20:18:435198 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:135199
[email protected]49639fa2011-12-20 23:22:415200 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:135201
bnc691fda62016-08-12 00:43:165202 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015203 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:135204
5205 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015206 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:135207
bnc691fda62016-08-12 00:43:165208 const HttpResponseInfo* const response_restart = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:135209
wezca1070932016-05-26 20:30:525210 ASSERT_TRUE(response_restart);
5211 ASSERT_TRUE(response_restart->headers);
[email protected]dc7bd1c52010-11-12 00:01:135212 EXPECT_EQ(200, response_restart->headers->response_code());
5213 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525214 EXPECT_FALSE(response_restart->auth_challenge);
[email protected]dc7bd1c52010-11-12 00:01:135215}
5216
[email protected]d9da5fe2010-10-13 22:37:165217// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
bncd16676a2016-07-20 16:23:015218TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:275219 HttpRequestInfo request;
5220 request.method = "GET";
bncce36dca22015-04-21 22:11:235221 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105222 request.traffic_annotation =
5223 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275224
[email protected]d9da5fe2010-10-13 22:37:165225 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495226 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5227 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515228 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075229 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095230 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165231
bnc691fda62016-08-12 00:43:165232 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165233
bncce36dca22015-04-21 22:11:235234 // CONNECT to www.example.org:443 via SPDY
Ryan Hamilton0239aac2018-05-19 00:03:135235 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235236 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
5237 // fetch https://www.example.org/ via HTTP
[email protected]d9da5fe2010-10-13 22:37:165238
bncce36dca22015-04-21 22:11:235239 const char get[] =
5240 "GET / HTTP/1.1\r\n"
5241 "Host: www.example.org\r\n"
5242 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:135243 spdy::SpdySerializedFrame wrapped_get(
Bence Békyd74f4382018-02-20 18:26:195244 spdy_util_.ConstructSpdyDataFrame(1, get, false));
Ryan Hamilton0239aac2018-05-19 00:03:135245 spdy::SpdySerializedFrame conn_resp(
5246 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:165247 const char resp[] = "HTTP/1.1 200 OK\r\n"
5248 "Content-Length: 10\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:135249 spdy::SpdySerializedFrame wrapped_get_resp(
Bence Békyd74f4382018-02-20 18:26:195250 spdy_util_.ConstructSpdyDataFrame(1, resp, false));
Ryan Hamilton0239aac2018-05-19 00:03:135251 spdy::SpdySerializedFrame wrapped_body(
Bence Békyd74f4382018-02-20 18:26:195252 spdy_util_.ConstructSpdyDataFrame(1, "1234567890", false));
Ryan Hamilton0239aac2018-05-19 00:03:135253 spdy::SpdySerializedFrame window_update(
bncdf80d44fd2016-07-15 20:27:415254 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
[email protected]8d2f7012012-02-16 00:08:045255
5256 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415257 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
5258 CreateMockWrite(window_update, 6),
[email protected]8d2f7012012-02-16 00:08:045259 };
5260
[email protected]d9da5fe2010-10-13 22:37:165261 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415262 CreateMockRead(conn_resp, 1, ASYNC),
5263 CreateMockRead(wrapped_get_resp, 3, ASYNC),
5264 CreateMockRead(wrapped_body, 4, ASYNC),
5265 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:135266 MockRead(ASYNC, 0, 7),
[email protected]d9da5fe2010-10-13 22:37:165267 };
5268
Ryan Sleevib8d7ea02018-05-07 20:01:015269 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075270 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165271
[email protected]8ddf8322012-02-23 18:08:065272 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365273 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075274 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065275 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075276 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165277
[email protected]49639fa2011-12-20 23:22:415278 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165279
bnc691fda62016-08-12 00:43:165280 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015281 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165282
5283 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015284 ASSERT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:165285
[email protected]58e32bb2013-01-21 18:23:255286 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165287 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255288 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5289
bnc691fda62016-08-12 00:43:165290 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525291 ASSERT_TRUE(response);
5292 ASSERT_TRUE(response->headers);
[email protected]d9da5fe2010-10-13 22:37:165293 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5294
5295 std::string response_data;
bnc691fda62016-08-12 00:43:165296 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]d9da5fe2010-10-13 22:37:165297 EXPECT_EQ("1234567890", response_data);
5298}
5299
5300// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
bncd16676a2016-07-20 16:23:015301TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
5302 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:385303
[email protected]cb9bf6ca2011-01-28 13:15:275304 HttpRequestInfo request;
5305 request.method = "GET";
bncce36dca22015-04-21 22:11:235306 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105307 request.traffic_annotation =
5308 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275309
[email protected]d9da5fe2010-10-13 22:37:165310 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495311 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5312 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515313 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075314 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095315 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165316
bnc691fda62016-08-12 00:43:165317 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165318
bncce36dca22015-04-21 22:11:235319 // CONNECT to www.example.org:443 via SPDY
Ryan Hamilton0239aac2018-05-19 00:03:135320 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235321 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
5322 // fetch https://www.example.org/ via SPDY
5323 const char kMyUrl[] = "https://www.example.org/";
Ryan Hamilton0239aac2018-05-19 00:03:135324 spdy::SpdySerializedFrame get(
bnc38dcd392016-02-09 23:19:495325 spdy_util_wrapped.ConstructSpdyGet(kMyUrl, 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:135326 spdy::SpdySerializedFrame wrapped_get(
5327 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
5328 spdy::SpdySerializedFrame conn_resp(
5329 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
5330 spdy::SpdySerializedFrame get_resp(
bnc42331402016-07-25 13:36:155331 spdy_util_wrapped.ConstructSpdyGetReply(NULL, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135332 spdy::SpdySerializedFrame wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:025333 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135334 spdy::SpdySerializedFrame body(
5335 spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
5336 spdy::SpdySerializedFrame wrapped_body(
[email protected]23e482282013-06-14 16:08:025337 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135338 spdy::SpdySerializedFrame window_update_get_resp(
bncdf80d44fd2016-07-15 20:27:415339 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
Ryan Hamilton0239aac2018-05-19 00:03:135340 spdy::SpdySerializedFrame window_update_body(
bncdf80d44fd2016-07-15 20:27:415341 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
[email protected]8d2f7012012-02-16 00:08:045342
5343 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415344 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
5345 CreateMockWrite(window_update_get_resp, 6),
5346 CreateMockWrite(window_update_body, 7),
[email protected]8d2f7012012-02-16 00:08:045347 };
5348
[email protected]d9da5fe2010-10-13 22:37:165349 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415350 CreateMockRead(conn_resp, 1, ASYNC),
rch32320842015-05-16 15:57:095351 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:415352 CreateMockRead(wrapped_get_resp, 4, ASYNC),
5353 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:135354 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:165355 };
5356
Ryan Sleevib8d7ea02018-05-07 20:01:015357 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075358 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165359
[email protected]8ddf8322012-02-23 18:08:065360 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365361 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075362 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065363 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365364 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075365 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165366
[email protected]49639fa2011-12-20 23:22:415367 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165368
bnc691fda62016-08-12 00:43:165369 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015370 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165371
rch32320842015-05-16 15:57:095372 // Allow the SpdyProxyClientSocket's write callback to complete.
fdoray92e35a72016-06-10 15:54:555373 base::RunLoop().RunUntilIdle();
rch32320842015-05-16 15:57:095374 // Now allow the read of the response to complete.
mmenkee24011922015-12-17 22:12:595375 spdy_data.Resume();
[email protected]d9da5fe2010-10-13 22:37:165376 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015377 EXPECT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:165378
[email protected]58e32bb2013-01-21 18:23:255379 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165380 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255381 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5382
bnc691fda62016-08-12 00:43:165383 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525384 ASSERT_TRUE(response);
5385 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025386 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d9da5fe2010-10-13 22:37:165387
5388 std::string response_data;
bnc691fda62016-08-12 00:43:165389 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235390 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:165391}
5392
5393// Test a SPDY CONNECT failure through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015394TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:275395 HttpRequestInfo request;
5396 request.method = "GET";
bncce36dca22015-04-21 22:11:235397 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105398 request.traffic_annotation =
5399 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275400
[email protected]d9da5fe2010-10-13 22:37:165401 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495402 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5403 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515404 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075405 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095406 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165407
bnc691fda62016-08-12 00:43:165408 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165409
bncce36dca22015-04-21 22:11:235410 // CONNECT to www.example.org:443 via SPDY
Ryan Hamilton0239aac2018-05-19 00:03:135411 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235412 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:135413 spdy::SpdySerializedFrame get(
5414 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:165415
5416 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415417 CreateMockWrite(connect, 0), CreateMockWrite(get, 2),
[email protected]d9da5fe2010-10-13 22:37:165418 };
5419
Ryan Hamilton0239aac2018-05-19 00:03:135420 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(1));
5421 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:165422 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415423 CreateMockRead(resp, 1, ASYNC), MockRead(ASYNC, 0, 3),
[email protected]d9da5fe2010-10-13 22:37:165424 };
5425
Ryan Sleevib8d7ea02018-05-07 20:01:015426 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075427 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165428
[email protected]8ddf8322012-02-23 18:08:065429 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365430 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075431 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065432 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365433 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075434 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165435
[email protected]49639fa2011-12-20 23:22:415436 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165437
bnc691fda62016-08-12 00:43:165438 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015439 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165440
5441 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015442 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]d9da5fe2010-10-13 22:37:165443
ttuttle960fcbf2016-04-19 13:26:325444 // TODO(juliatuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:165445}
5446
[email protected]f6c63db52013-02-02 00:35:225447// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
5448// HTTPS Proxy to different servers.
bncd16676a2016-07-20 16:23:015449TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:225450 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
5451 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495452 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5453 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515454 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075455 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095456 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505457 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225458
5459 HttpRequestInfo request1;
5460 request1.method = "GET";
bncce36dca22015-04-21 22:11:235461 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225462 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:105463 request1.traffic_annotation =
5464 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225465
5466 HttpRequestInfo request2;
5467 request2.method = "GET";
bncce36dca22015-04-21 22:11:235468 request2.url = GURL("https://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:225469 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:105470 request2.traffic_annotation =
5471 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225472
bncce36dca22015-04-21 22:11:235473 // CONNECT to www.example.org:443 via SPDY.
Ryan Hamilton0239aac2018-05-19 00:03:135474 spdy::SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235475 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:135476 spdy::SpdySerializedFrame conn_resp1(
5477 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:225478
bncce36dca22015-04-21 22:11:235479 // Fetch https://www.example.org/ via HTTP.
5480 const char get1[] =
5481 "GET / HTTP/1.1\r\n"
5482 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225483 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:135484 spdy::SpdySerializedFrame wrapped_get1(
Bence Békyd74f4382018-02-20 18:26:195485 spdy_util_.ConstructSpdyDataFrame(1, get1, false));
[email protected]f6c63db52013-02-02 00:35:225486 const char resp1[] = "HTTP/1.1 200 OK\r\n"
5487 "Content-Length: 1\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:135488 spdy::SpdySerializedFrame wrapped_get_resp1(
Bence Békyd74f4382018-02-20 18:26:195489 spdy_util_.ConstructSpdyDataFrame(1, resp1, false));
Ryan Hamilton0239aac2018-05-19 00:03:135490 spdy::SpdySerializedFrame wrapped_body1(
Bence Békyd74f4382018-02-20 18:26:195491 spdy_util_.ConstructSpdyDataFrame(1, "1", false));
Ryan Hamilton0239aac2018-05-19 00:03:135492 spdy::SpdySerializedFrame window_update(
bncdf80d44fd2016-07-15 20:27:415493 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:225494
bncce36dca22015-04-21 22:11:235495 // CONNECT to mail.example.org:443 via SPDY.
Ryan Hamilton0239aac2018-05-19 00:03:135496 spdy::SpdyHeaderBlock connect2_block;
5497 connect2_block[spdy::kHttp2MethodHeader] = "CONNECT";
5498 connect2_block[spdy::kHttp2AuthorityHeader] = "mail.example.org:443";
5499 spdy::SpdySerializedFrame connect2(spdy_util_.ConstructSpdyHeaders(
bnc42331402016-07-25 13:36:155500 3, std::move(connect2_block), LOWEST, false));
[email protected]601e03f12014-04-06 16:26:395501
Ryan Hamilton0239aac2018-05-19 00:03:135502 spdy::SpdySerializedFrame conn_resp2(
5503 spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:225504
bncce36dca22015-04-21 22:11:235505 // Fetch https://mail.example.org/ via HTTP.
5506 const char get2[] =
5507 "GET / HTTP/1.1\r\n"
5508 "Host: mail.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225509 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:135510 spdy::SpdySerializedFrame wrapped_get2(
Bence Békyd74f4382018-02-20 18:26:195511 spdy_util_.ConstructSpdyDataFrame(3, get2, false));
[email protected]f6c63db52013-02-02 00:35:225512 const char resp2[] = "HTTP/1.1 200 OK\r\n"
5513 "Content-Length: 2\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:135514 spdy::SpdySerializedFrame wrapped_get_resp2(
Bence Békyd74f4382018-02-20 18:26:195515 spdy_util_.ConstructSpdyDataFrame(3, resp2, false));
Ryan Hamilton0239aac2018-05-19 00:03:135516 spdy::SpdySerializedFrame wrapped_body2(
Bence Békyd74f4382018-02-20 18:26:195517 spdy_util_.ConstructSpdyDataFrame(3, "22", false));
[email protected]f6c63db52013-02-02 00:35:225518
5519 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415520 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
5521 CreateMockWrite(connect2, 5), CreateMockWrite(wrapped_get2, 7),
[email protected]f6c63db52013-02-02 00:35:225522 };
5523
5524 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415525 CreateMockRead(conn_resp1, 1, ASYNC),
5526 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
5527 CreateMockRead(wrapped_body1, 4, ASYNC),
5528 CreateMockRead(conn_resp2, 6, ASYNC),
5529 CreateMockRead(wrapped_get_resp2, 8, ASYNC),
5530 CreateMockRead(wrapped_body2, 9, ASYNC),
5531 MockRead(ASYNC, 0, 10),
[email protected]f6c63db52013-02-02 00:35:225532 };
5533
Ryan Sleevib8d7ea02018-05-07 20:01:015534 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
mmenke11eb5152015-06-09 14:50:505535 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225536
5537 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365538 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505539 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225540 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505541 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:225542 SSLSocketDataProvider ssl3(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505543 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:225544
5545 TestCompletionCallback callback;
5546
bnc691fda62016-08-12 00:43:165547 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205548 int rv = trans.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015549 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225550
5551 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165552 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]f6c63db52013-02-02 00:35:225553 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5554
bnc691fda62016-08-12 00:43:165555 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525556 ASSERT_TRUE(response);
5557 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:225558 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5559
5560 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295561 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
bnc691fda62016-08-12 00:43:165562 rv = trans.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505563 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225564
bnc691fda62016-08-12 00:43:165565 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205566 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015567 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225568
5569 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:165570 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:225571 // Even though the SPDY connection is reused, a new tunnelled connection has
5572 // to be created, so the socket's load timing looks like a fresh connection.
5573 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
5574
5575 // The requests should have different IDs, since they each are using their own
5576 // separate stream.
5577 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5578
bnc691fda62016-08-12 00:43:165579 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505580 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225581}
5582
5583// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
5584// HTTPS Proxy to the same server.
bncd16676a2016-07-20 16:23:015585TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:225586 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
5587 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495588 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5589 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515590 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075591 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095592 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505593 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225594
5595 HttpRequestInfo request1;
5596 request1.method = "GET";
bncce36dca22015-04-21 22:11:235597 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225598 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:105599 request1.traffic_annotation =
5600 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225601
5602 HttpRequestInfo request2;
5603 request2.method = "GET";
bncce36dca22015-04-21 22:11:235604 request2.url = GURL("https://www.example.org/2");
[email protected]f6c63db52013-02-02 00:35:225605 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:105606 request2.traffic_annotation =
5607 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225608
bncce36dca22015-04-21 22:11:235609 // CONNECT to www.example.org:443 via SPDY.
Ryan Hamilton0239aac2018-05-19 00:03:135610 spdy::SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235611 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:135612 spdy::SpdySerializedFrame conn_resp1(
5613 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:225614
bncce36dca22015-04-21 22:11:235615 // Fetch https://www.example.org/ via HTTP.
5616 const char get1[] =
5617 "GET / HTTP/1.1\r\n"
5618 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225619 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:135620 spdy::SpdySerializedFrame wrapped_get1(
Bence Békyd74f4382018-02-20 18:26:195621 spdy_util_.ConstructSpdyDataFrame(1, get1, false));
[email protected]f6c63db52013-02-02 00:35:225622 const char resp1[] = "HTTP/1.1 200 OK\r\n"
5623 "Content-Length: 1\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:135624 spdy::SpdySerializedFrame wrapped_get_resp1(
Bence Békyd74f4382018-02-20 18:26:195625 spdy_util_.ConstructSpdyDataFrame(1, resp1, false));
Ryan Hamilton0239aac2018-05-19 00:03:135626 spdy::SpdySerializedFrame wrapped_body1(
Bence Békyd74f4382018-02-20 18:26:195627 spdy_util_.ConstructSpdyDataFrame(1, "1", false));
Ryan Hamilton0239aac2018-05-19 00:03:135628 spdy::SpdySerializedFrame window_update(
bncdf80d44fd2016-07-15 20:27:415629 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:225630
bncce36dca22015-04-21 22:11:235631 // Fetch https://www.example.org/2 via HTTP.
5632 const char get2[] =
5633 "GET /2 HTTP/1.1\r\n"
5634 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225635 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:135636 spdy::SpdySerializedFrame wrapped_get2(
Bence Békyd74f4382018-02-20 18:26:195637 spdy_util_.ConstructSpdyDataFrame(1, get2, false));
[email protected]f6c63db52013-02-02 00:35:225638 const char resp2[] = "HTTP/1.1 200 OK\r\n"
5639 "Content-Length: 2\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:135640 spdy::SpdySerializedFrame wrapped_get_resp2(
Bence Békyd74f4382018-02-20 18:26:195641 spdy_util_.ConstructSpdyDataFrame(1, resp2, false));
Ryan Hamilton0239aac2018-05-19 00:03:135642 spdy::SpdySerializedFrame wrapped_body2(
Bence Békyd74f4382018-02-20 18:26:195643 spdy_util_.ConstructSpdyDataFrame(1, "22", false));
[email protected]f6c63db52013-02-02 00:35:225644
5645 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415646 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
5647 CreateMockWrite(wrapped_get2, 5),
[email protected]f6c63db52013-02-02 00:35:225648 };
5649
5650 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415651 CreateMockRead(conn_resp1, 1, ASYNC),
5652 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
bnceb9aa7112017-01-05 01:03:465653 CreateMockRead(wrapped_body1, 4, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415654 CreateMockRead(wrapped_get_resp2, 6, ASYNC),
bnceb9aa7112017-01-05 01:03:465655 CreateMockRead(wrapped_body2, 7, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415656 MockRead(ASYNC, 0, 8),
[email protected]f6c63db52013-02-02 00:35:225657 };
5658
Ryan Sleevib8d7ea02018-05-07 20:01:015659 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
mmenke11eb5152015-06-09 14:50:505660 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225661
5662 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365663 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505664 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225665 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505666 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:225667
5668 TestCompletionCallback callback;
5669
bnc87dcefc2017-05-25 12:47:585670 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:195671 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205672 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015673 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:225674
5675 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:015676 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:225677
5678 LoadTimingInfo load_timing_info;
5679 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5680 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5681
5682 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525683 ASSERT_TRUE(response);
5684 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:225685 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5686
5687 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295688 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]90499482013-06-01 00:39:505689 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:225690 trans.reset();
5691
bnc87dcefc2017-05-25 12:47:585692 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:195693 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205694 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015695 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:225696
[email protected]f6c63db52013-02-02 00:35:225697 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:015698 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:225699
5700 LoadTimingInfo load_timing_info2;
5701 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5702 TestLoadTimingReused(load_timing_info2);
5703
5704 // The requests should have the same ID.
5705 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5706
[email protected]90499482013-06-01 00:39:505707 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:225708}
5709
5710// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
5711// Proxy to different servers.
bncd16676a2016-07-20 16:23:015712TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) {
[email protected]f6c63db52013-02-02 00:35:225713 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495714 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5715 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515716 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075717 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095718 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505719 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225720
5721 HttpRequestInfo request1;
5722 request1.method = "GET";
bncce36dca22015-04-21 22:11:235723 request1.url = GURL("http://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225724 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:105725 request1.traffic_annotation =
5726 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225727
5728 HttpRequestInfo request2;
5729 request2.method = "GET";
bncce36dca22015-04-21 22:11:235730 request2.url = GURL("http://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:225731 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:105732 request2.traffic_annotation =
5733 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225734
bncce36dca22015-04-21 22:11:235735 // http://www.example.org/
Ryan Hamilton0239aac2018-05-19 00:03:135736 spdy::SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:235737 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
Ryan Hamilton0239aac2018-05-19 00:03:135738 spdy::SpdySerializedFrame get1(
bnc42331402016-07-25 13:36:155739 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
Ryan Hamilton0239aac2018-05-19 00:03:135740 spdy::SpdySerializedFrame get_resp1(
5741 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
5742 spdy::SpdySerializedFrame body1(
5743 spdy_util_.ConstructSpdyDataFrame(1, "1", true));
rdsmithebb50aa2015-11-12 03:44:385744 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]f6c63db52013-02-02 00:35:225745
bncce36dca22015-04-21 22:11:235746 // http://mail.example.org/
Ryan Hamilton0239aac2018-05-19 00:03:135747 spdy::SpdyHeaderBlock headers2(
bncce36dca22015-04-21 22:11:235748 spdy_util_.ConstructGetHeaderBlockForProxy("http://mail.example.org/"));
Ryan Hamilton0239aac2018-05-19 00:03:135749 spdy::SpdySerializedFrame get2(
bnc42331402016-07-25 13:36:155750 spdy_util_.ConstructSpdyHeaders(3, std::move(headers2), LOWEST, true));
Ryan Hamilton0239aac2018-05-19 00:03:135751 spdy::SpdySerializedFrame get_resp2(
5752 spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
5753 spdy::SpdySerializedFrame body2(
5754 spdy_util_.ConstructSpdyDataFrame(3, "22", true));
[email protected]f6c63db52013-02-02 00:35:225755
5756 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415757 CreateMockWrite(get1, 0), CreateMockWrite(get2, 3),
[email protected]f6c63db52013-02-02 00:35:225758 };
5759
5760 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415761 CreateMockRead(get_resp1, 1, ASYNC),
5762 CreateMockRead(body1, 2, ASYNC),
5763 CreateMockRead(get_resp2, 4, ASYNC),
5764 CreateMockRead(body2, 5, ASYNC),
5765 MockRead(ASYNC, 0, 6),
[email protected]f6c63db52013-02-02 00:35:225766 };
5767
Ryan Sleevib8d7ea02018-05-07 20:01:015768 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
mmenke11eb5152015-06-09 14:50:505769 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225770
5771 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365772 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505773 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225774
5775 TestCompletionCallback callback;
5776
bnc87dcefc2017-05-25 12:47:585777 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:195778 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205779 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015780 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225781
5782 LoadTimingInfo load_timing_info;
5783 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5784 TestLoadTimingNotReused(load_timing_info,
5785 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5786
5787 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525788 ASSERT_TRUE(response);
5789 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025790 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]f6c63db52013-02-02 00:35:225791
5792 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295793 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
mmenke11eb5152015-06-09 14:50:505794 rv = trans->Read(buf.get(), 256, callback.callback());
5795 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225796 // Delete the first request, so the second one can reuse the socket.
5797 trans.reset();
5798
bnc691fda62016-08-12 00:43:165799 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205800 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015801 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225802
5803 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:165804 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:225805 TestLoadTimingReused(load_timing_info2);
5806
5807 // The requests should have the same ID.
5808 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5809
bnc691fda62016-08-12 00:43:165810 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505811 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225812}
5813
[email protected]2df19bb2010-08-25 20:13:465814// Test the challenge-response-retry sequence through an HTTPS Proxy
bncd16676a2016-07-20 16:23:015815TEST_F(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:465816 HttpRequestInfo request;
5817 request.method = "GET";
bncce36dca22015-04-21 22:11:235818 request.url = GURL("http://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:465819 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:295820 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:105821 request.traffic_annotation =
5822 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:465823
[email protected]79cb5c12011-09-12 13:12:045824 // Configure against https proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495825 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5826 "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515827 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075828 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095829 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275830
[email protected]2df19bb2010-08-25 20:13:465831 // Since we have proxy, should use full url
5832 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:165833 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
5834 "Host: www.example.org\r\n"
5835 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465836
bnc691fda62016-08-12 00:43:165837 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:235838 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:165839 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
5840 "Host: www.example.org\r\n"
5841 "Proxy-Connection: keep-alive\r\n"
5842 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465843 };
5844
5845 // The proxy responds to the GET with a 407, using a persistent
5846 // connection.
5847 MockRead data_reads1[] = {
5848 // No credentials.
5849 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
5850 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5851 MockRead("Proxy-Connection: keep-alive\r\n"),
5852 MockRead("Content-Length: 0\r\n\r\n"),
5853
5854 MockRead("HTTP/1.1 200 OK\r\n"),
5855 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5856 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065857 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:465858 };
5859
Ryan Sleevib8d7ea02018-05-07 20:01:015860 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:075861 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:065862 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075863 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:465864
[email protected]49639fa2011-12-20 23:22:415865 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:465866
bnc691fda62016-08-12 00:43:165867 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505868
bnc691fda62016-08-12 00:43:165869 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015870 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465871
5872 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015873 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465874
[email protected]58e32bb2013-01-21 18:23:255875 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165876 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255877 TestLoadTimingNotReused(load_timing_info,
5878 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5879
bnc691fda62016-08-12 00:43:165880 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525881 ASSERT_TRUE(response);
5882 ASSERT_TRUE(response->headers);
[email protected]2df19bb2010-08-25 20:13:465883 EXPECT_EQ(407, response->headers->response_code());
5884 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
asanka098c0092016-06-16 20:18:435885 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:465886
[email protected]49639fa2011-12-20 23:22:415887 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:465888
bnc691fda62016-08-12 00:43:165889 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015890 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465891
5892 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015893 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465894
[email protected]58e32bb2013-01-21 18:23:255895 load_timing_info = LoadTimingInfo();
bnc691fda62016-08-12 00:43:165896 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255897 // Retrying with HTTP AUTH is considered to be reusing a socket.
5898 TestLoadTimingReused(load_timing_info);
5899
bnc691fda62016-08-12 00:43:165900 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525901 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:465902
5903 EXPECT_TRUE(response->headers->IsKeepAlive());
5904 EXPECT_EQ(200, response->headers->response_code());
5905 EXPECT_EQ(100, response->headers->GetContentLength());
5906 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5907
5908 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525909 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:465910}
5911
[email protected]23e482282013-06-14 16:08:025912void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:085913 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:425914 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:085915 request.method = "GET";
bncce36dca22015-04-21 22:11:235916 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105917 request.traffic_annotation =
5918 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]c744cf22009-02-27 07:28:085919
[email protected]cb9bf6ca2011-01-28 13:15:275920 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495921 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5922 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:095923 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275924
[email protected]c744cf22009-02-27 07:28:085925 // Since we have proxy, should try to establish tunnel.
5926 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:175927 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5928 "Host: www.example.org:443\r\n"
5929 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:085930 };
5931
5932 MockRead data_reads[] = {
mmenked39192ee2015-12-09 00:57:235933 status, MockRead("Content-Length: 10\r\n\r\n"),
5934 // No response body because the test stops reading here.
5935 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]c744cf22009-02-27 07:28:085936 };
5937
Ryan Sleevib8d7ea02018-05-07 20:01:015938 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:075939 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:085940
[email protected]49639fa2011-12-20 23:22:415941 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:085942
bnc691fda62016-08-12 00:43:165943 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505944
tfarina42834112016-09-22 13:38:205945 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015946 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]c744cf22009-02-27 07:28:085947
5948 rv = callback.WaitForResult();
5949 EXPECT_EQ(expected_status, rv);
5950}
5951
[email protected]23e482282013-06-14 16:08:025952void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:235953 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:085954 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:425955 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:085956}
5957
bncd16676a2016-07-20 16:23:015958TEST_F(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:085959 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
5960}
5961
bncd16676a2016-07-20 16:23:015962TEST_F(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:085963 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
5964}
5965
bncd16676a2016-07-20 16:23:015966TEST_F(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:085967 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
5968}
5969
bncd16676a2016-07-20 16:23:015970TEST_F(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:085971 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
5972}
5973
bncd16676a2016-07-20 16:23:015974TEST_F(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:085975 ConnectStatusHelper(
5976 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
5977}
5978
bncd16676a2016-07-20 16:23:015979TEST_F(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:085980 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
5981}
5982
bncd16676a2016-07-20 16:23:015983TEST_F(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:085984 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
5985}
5986
bncd16676a2016-07-20 16:23:015987TEST_F(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:085988 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
5989}
5990
bncd16676a2016-07-20 16:23:015991TEST_F(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:085992 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
5993}
5994
bncd16676a2016-07-20 16:23:015995TEST_F(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:085996 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
5997}
5998
bncd16676a2016-07-20 16:23:015999TEST_F(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:086000 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
6001}
6002
bncd16676a2016-07-20 16:23:016003TEST_F(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:086004 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
6005}
6006
bncd16676a2016-07-20 16:23:016007TEST_F(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:086008 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
6009}
6010
bncd16676a2016-07-20 16:23:016011TEST_F(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:086012 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
6013}
6014
bncd16676a2016-07-20 16:23:016015TEST_F(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:086016 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
6017}
6018
bncd16676a2016-07-20 16:23:016019TEST_F(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:086020 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
6021}
6022
bncd16676a2016-07-20 16:23:016023TEST_F(HttpNetworkTransactionTest, ConnectStatus308) {
[email protected]0a17aab32014-04-24 03:32:376024 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
6025}
6026
bncd16676a2016-07-20 16:23:016027TEST_F(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:086028 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
6029}
6030
bncd16676a2016-07-20 16:23:016031TEST_F(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:086032 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
6033}
6034
bncd16676a2016-07-20 16:23:016035TEST_F(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:086036 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
6037}
6038
bncd16676a2016-07-20 16:23:016039TEST_F(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:086040 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
6041}
6042
bncd16676a2016-07-20 16:23:016043TEST_F(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:086044 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
6045}
6046
bncd16676a2016-07-20 16:23:016047TEST_F(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:086048 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
6049}
6050
bncd16676a2016-07-20 16:23:016051TEST_F(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:086052 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
6053}
6054
bncd16676a2016-07-20 16:23:016055TEST_F(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:086056 ConnectStatusHelperWithExpectedStatus(
6057 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:546058 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:086059}
6060
bncd16676a2016-07-20 16:23:016061TEST_F(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:086062 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
6063}
6064
bncd16676a2016-07-20 16:23:016065TEST_F(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:086066 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
6067}
6068
bncd16676a2016-07-20 16:23:016069TEST_F(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:086070 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
6071}
6072
bncd16676a2016-07-20 16:23:016073TEST_F(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:086074 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
6075}
6076
bncd16676a2016-07-20 16:23:016077TEST_F(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:086078 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
6079}
6080
bncd16676a2016-07-20 16:23:016081TEST_F(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:086082 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
6083}
6084
bncd16676a2016-07-20 16:23:016085TEST_F(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:086086 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
6087}
6088
bncd16676a2016-07-20 16:23:016089TEST_F(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:086090 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
6091}
6092
bncd16676a2016-07-20 16:23:016093TEST_F(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:086094 ConnectStatusHelper(
6095 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
6096}
6097
bncd16676a2016-07-20 16:23:016098TEST_F(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:086099 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
6100}
6101
bncd16676a2016-07-20 16:23:016102TEST_F(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:086103 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
6104}
6105
bncd16676a2016-07-20 16:23:016106TEST_F(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:086107 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
6108}
6109
bncd16676a2016-07-20 16:23:016110TEST_F(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:086111 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
6112}
6113
bncd16676a2016-07-20 16:23:016114TEST_F(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:086115 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
6116}
6117
bncd16676a2016-07-20 16:23:016118TEST_F(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:086119 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
6120}
6121
bncd16676a2016-07-20 16:23:016122TEST_F(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:086123 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
6124}
6125
[email protected]038e9a32008-10-08 22:40:166126// Test the flow when both the proxy server AND origin server require
6127// authentication. Again, this uses basic auth for both since that is
6128// the simplest to mock.
bncd16676a2016-07-20 16:23:016129TEST_F(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:276130 HttpRequestInfo request;
6131 request.method = "GET";
bncce36dca22015-04-21 22:11:236132 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:106133 request.traffic_annotation =
6134 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:276135
[email protected]038e9a32008-10-08 22:40:166136 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496137 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6138 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:096139 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:076140
bnc691fda62016-08-12 00:43:166141 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]038e9a32008-10-08 22:40:166142
[email protected]f9ee6b52008-11-08 06:46:236143 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236144 MockWrite(
6145 "GET http://www.example.org/ HTTP/1.1\r\n"
6146 "Host: www.example.org\r\n"
6147 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236148 };
6149
[email protected]038e9a32008-10-08 22:40:166150 MockRead data_reads1[] = {
6151 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
6152 // Give a couple authenticate options (only the middle one is actually
6153 // supported).
[email protected]22927ad2009-09-21 19:56:196154 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:166155 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6156 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
6157 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6158 // Large content-length -- won't matter, as connection will be reset.
6159 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066160 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:166161 };
6162
bnc691fda62016-08-12 00:43:166163 // After calling trans.RestartWithAuth() the first time, this is the
[email protected]038e9a32008-10-08 22:40:166164 // request we should be issuing -- the final header line contains the
6165 // proxy's credentials.
6166 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236167 MockWrite(
6168 "GET http://www.example.org/ HTTP/1.1\r\n"
6169 "Host: www.example.org\r\n"
6170 "Proxy-Connection: keep-alive\r\n"
6171 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:166172 };
6173
6174 // Now the proxy server lets the request pass through to origin server.
6175 // The origin server responds with a 401.
6176 MockRead data_reads2[] = {
6177 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6178 // Note: We are using the same realm-name as the proxy server. This is
6179 // completely valid, as realms are unique across hosts.
6180 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6181 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6182 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066183 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:166184 };
6185
bnc691fda62016-08-12 00:43:166186 // After calling trans.RestartWithAuth() the second time, we should send
[email protected]038e9a32008-10-08 22:40:166187 // the credentials for both the proxy and origin server.
6188 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236189 MockWrite(
6190 "GET http://www.example.org/ HTTP/1.1\r\n"
6191 "Host: www.example.org\r\n"
6192 "Proxy-Connection: keep-alive\r\n"
6193 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
6194 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:166195 };
6196
6197 // Lastly we get the desired content.
6198 MockRead data_reads3[] = {
6199 MockRead("HTTP/1.0 200 OK\r\n"),
6200 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6201 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066202 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:166203 };
6204
Ryan Sleevib8d7ea02018-05-07 20:01:016205 StaticSocketDataProvider data1(data_reads1, data_writes1);
6206 StaticSocketDataProvider data2(data_reads2, data_writes2);
6207 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]bb88e1d32013-05-03 23:11:076208 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6209 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6210 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:166211
[email protected]49639fa2011-12-20 23:22:416212 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:166213
tfarina42834112016-09-22 13:38:206214 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016215 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:166216
6217 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016218 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:166219
bnc691fda62016-08-12 00:43:166220 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526221 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046222 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:166223
[email protected]49639fa2011-12-20 23:22:416224 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:166225
bnc691fda62016-08-12 00:43:166226 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:016227 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:166228
6229 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016230 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:166231
bnc691fda62016-08-12 00:43:166232 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526233 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046234 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:166235
[email protected]49639fa2011-12-20 23:22:416236 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:166237
bnc691fda62016-08-12 00:43:166238 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
6239 callback3.callback());
robpercival214763f2016-07-01 23:27:016240 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:166241
6242 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016243 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:166244
bnc691fda62016-08-12 00:43:166245 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526246 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:166247 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:166248}
[email protected]4ddaf2502008-10-23 18:26:196249
[email protected]ea9dc9a2009-09-05 00:43:326250// For the NTLM implementation using SSPI, we skip the NTLM tests since we
6251// can't hook into its internals to cause it to generate predictable NTLM
6252// authorization headers.
6253#if defined(NTLM_PORTABLE)
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376254// The NTLM authentication unit tests are based on known test data from the
6255// [MS-NLMP] Specification [1]. These tests are primarily of the authentication
6256// flow rather than the implementation of the NTLM protocol. See net/ntlm
6257// for the implementation and testing of the protocol.
6258//
6259// [1] https://msdn.microsoft.com/en-us/library/cc236621.aspx
[email protected]385a4672009-03-11 22:21:296260
6261// Enter the correct password and authenticate successfully.
Zentaro Kavanagh1890a3d2018-01-29 19:52:556262TEST_F(HttpNetworkTransactionTest, NTLMAuthV2) {
[email protected]1c773ea12009-04-28 19:58:426263 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:246264 request.method = "GET";
Zentaro Kavanagh1890a3d2018-01-29 19:52:556265 request.url = GURL("https://server/kids/login.aspx");
Ramin Halavatib5e433e62018-02-07 07:41:106266 request.traffic_annotation =
6267 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2217aa22013-10-11 03:03:546268
6269 // Ensure load is not disrupted by flags which suppress behaviour specific
6270 // to other auth schemes.
6271 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:246272
Zentaro Kavanagh6ccee512017-09-28 18:34:096273 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
6274 MockGetMSTime, MockGenerateRandom, MockGetHostName);
danakj1fd259a02016-04-16 03:17:096275 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276276
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376277 // Generate the NTLM messages based on known test data.
6278 std::string negotiate_msg;
6279 std::string challenge_msg;
6280 std::string authenticate_msg;
6281 base::Base64Encode(
6282 base::StringPiece(
6283 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
6284 arraysize(ntlm::test::kExpectedNegotiateMsg)),
6285 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:556286 base::Base64Encode(
6287 base::StringPiece(
6288 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
6289 arraysize(ntlm::test::kChallengeMsgFromSpecV2)),
6290 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376291 base::Base64Encode(
6292 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:096293 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:556294 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
6295 arraysize(
6296 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376297 &authenticate_msg);
6298
[email protected]3f918782009-02-28 01:29:246299 MockWrite data_writes1[] = {
Zentaro Kavanagh1890a3d2018-01-29 19:52:556300 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6301 "Host: server\r\n"
6302 "Connection: keep-alive\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246303 };
6304
6305 MockRead data_reads1[] = {
6306 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:046307 // Negotiate and NTLM are often requested together. However, we only want
6308 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
6309 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:246310 MockRead("WWW-Authenticate: NTLM\r\n"),
6311 MockRead("Connection: close\r\n"),
6312 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366313 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246314 // Missing content -- won't matter, as connection will be reset.
[email protected]3f918782009-02-28 01:29:246315 };
6316
6317 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:166318 // After restarting with a null identity, this is the
6319 // request we should be issuing -- the final header line contains a Type
6320 // 1 message.
6321 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556322 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166323 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376324 "Authorization: NTLM "),
6325 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246326
bnc691fda62016-08-12 00:43:166327 // After calling trans.RestartWithAuth(), we should send a Type 3 message
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376328 // (using correct credentials). The second request continues on the
6329 // same connection.
bnc691fda62016-08-12 00:43:166330 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556331 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166332 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376333 "Authorization: NTLM "),
6334 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246335 };
6336
6337 MockRead data_reads2[] = {
Bence Béky1e4ef192017-09-18 19:58:026338 // The origin server responds with a Type 2 message.
6339 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376340 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6341 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky1e4ef192017-09-18 19:58:026342 MockRead("Content-Type: text/html\r\n\r\n"),
6343 MockRead("You are not authorized to view this page\r\n"),
[email protected]3f918782009-02-28 01:29:246344
Bence Béky1e4ef192017-09-18 19:58:026345 // Lastly we get the desired content.
6346 MockRead("HTTP/1.1 200 OK\r\n"),
6347 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
6348 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
[email protected]3f918782009-02-28 01:29:246349 };
6350
Ryan Sleevib8d7ea02018-05-07 20:01:016351 StaticSocketDataProvider data1(data_reads1, data_writes1);
6352 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:076353 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6354 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:246355
Bence Béky83eb3512017-09-05 12:56:096356 SSLSocketDataProvider ssl1(ASYNC, OK);
6357 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
6358 SSLSocketDataProvider ssl2(ASYNC, OK);
6359 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6360
[email protected]49639fa2011-12-20 23:22:416361 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:246362
bnc691fda62016-08-12 00:43:166363 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506364
tfarina42834112016-09-22 13:38:206365 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016366 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:246367
6368 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016369 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:246370
bnc691fda62016-08-12 00:43:166371 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:226372
bnc691fda62016-08-12 00:43:166373 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526374 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046375 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:246376
[email protected]49639fa2011-12-20 23:22:416377 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:256378
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376379 rv = trans.RestartWithAuth(
6380 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
6381 callback2.callback());
robpercival214763f2016-07-01 23:27:016382 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256383
6384 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016385 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:256386
bnc691fda62016-08-12 00:43:166387 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:256388
bnc691fda62016-08-12 00:43:166389 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526390 ASSERT_TRUE(response);
6391 EXPECT_FALSE(response->auth_challenge);
[email protected]10af5fe72011-01-31 16:17:256392
[email protected]49639fa2011-12-20 23:22:416393 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:246394
bnc691fda62016-08-12 00:43:166395 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:016396 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:246397
[email protected]0757e7702009-03-27 04:00:226398 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016399 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:246400
bnc691fda62016-08-12 00:43:166401 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526402 ASSERT_TRUE(response);
6403 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:026404 EXPECT_EQ(14, response->headers->GetContentLength());
6405
6406 std::string response_data;
6407 rv = ReadTransaction(&trans, &response_data);
6408 EXPECT_THAT(rv, IsOk());
6409 EXPECT_EQ("Please Login\r\n", response_data);
6410
6411 EXPECT_TRUE(data1.AllReadDataConsumed());
6412 EXPECT_TRUE(data1.AllWriteDataConsumed());
6413 EXPECT_TRUE(data2.AllReadDataConsumed());
6414 EXPECT_TRUE(data2.AllWriteDataConsumed());
[email protected]3f918782009-02-28 01:29:246415}
6416
[email protected]385a4672009-03-11 22:21:296417// Enter a wrong password, and then the correct one.
Zentaro Kavanagh1890a3d2018-01-29 19:52:556418TEST_F(HttpNetworkTransactionTest, NTLMAuthV2WrongThenRightPassword) {
[email protected]1c773ea12009-04-28 19:58:426419 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:296420 request.method = "GET";
Zentaro Kavanagh1890a3d2018-01-29 19:52:556421 request.url = GURL("https://server/kids/login.aspx");
Ramin Halavatib5e433e62018-02-07 07:41:106422 request.traffic_annotation =
6423 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]385a4672009-03-11 22:21:296424
Zentaro Kavanagh6ccee512017-09-28 18:34:096425 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
6426 MockGetMSTime, MockGenerateRandom, MockGetHostName);
danakj1fd259a02016-04-16 03:17:096427 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276428
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376429 // Generate the NTLM messages based on known test data.
6430 std::string negotiate_msg;
6431 std::string challenge_msg;
6432 std::string authenticate_msg;
6433 base::Base64Encode(
6434 base::StringPiece(
6435 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
6436 arraysize(ntlm::test::kExpectedNegotiateMsg)),
6437 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:556438 base::Base64Encode(
6439 base::StringPiece(
6440 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
6441 arraysize(ntlm::test::kChallengeMsgFromSpecV2)),
6442 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376443 base::Base64Encode(
6444 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:096445 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:556446 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
6447 arraysize(
6448 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376449 &authenticate_msg);
6450
6451 // The authenticate message when |kWrongPassword| is sent.
6452 std::string wrong_password_authenticate_msg(
Zentaro Kavanagh1890a3d2018-01-29 19:52:556453 "TlRMTVNTUAADAAAAGAAYAFgAAACKAIoAcAAAAAwADAD6AAAACAAIAAYBAAAQABAADgEAAAAA"
6454 "AABYAAAAA4IIAAAAAAAAAAAAAPknEYqtJQtusopDRSfYzAAAAAAAAAAAAAAAAAAAAAAAAAAA"
6455 "AAAAAOtVz38osnFdRRggUQHUJ3EBAQAAAAAAAIALyP0A1NIBqqqqqqqqqqoAAAAAAgAMAEQA"
6456 "bwBtAGEAaQBuAAEADABTAGUAcgB2AGUAcgAGAAQAAgAAAAoAEAAAAAAAAAAAAAAAAAAAAAAA"
6457 "CQAWAEgAVABUAFAALwBzAGUAcgB2AGUAcgAAAAAAAAAAAEQAbwBtAGEAaQBuAFUAcwBlAHIA"
6458 "QwBPAE0AUABVAFQARQBSAA==");
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376459
Zentaro Kavanagh1890a3d2018-01-29 19:52:556460 // Sanity check that it's the same length as the correct authenticate message
6461 // and that it's different.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376462 ASSERT_EQ(authenticate_msg.length(),
6463 wrong_password_authenticate_msg.length());
Zentaro Kavanagh1890a3d2018-01-29 19:52:556464 ASSERT_NE(authenticate_msg, wrong_password_authenticate_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376465
[email protected]385a4672009-03-11 22:21:296466 MockWrite data_writes1[] = {
Zentaro Kavanagh1890a3d2018-01-29 19:52:556467 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6468 "Host: server\r\n"
6469 "Connection: keep-alive\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296470 };
6471
6472 MockRead data_reads1[] = {
6473 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:046474 // Negotiate and NTLM are often requested together. However, we only want
6475 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
6476 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:296477 MockRead("WWW-Authenticate: NTLM\r\n"),
6478 MockRead("Connection: close\r\n"),
6479 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366480 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296481 // Missing content -- won't matter, as connection will be reset.
[email protected]385a4672009-03-11 22:21:296482 };
6483
6484 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:166485 // After restarting with a null identity, this is the
6486 // request we should be issuing -- the final header line contains a Type
6487 // 1 message.
6488 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556489 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166490 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376491 "Authorization: NTLM "),
6492 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296493
bnc691fda62016-08-12 00:43:166494 // After calling trans.RestartWithAuth(), we should send a Type 3 message
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376495 // (using incorrect credentials). The second request continues on the
6496 // same connection.
bnc691fda62016-08-12 00:43:166497 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556498 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166499 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376500 "Authorization: NTLM "),
6501 MockWrite(wrong_password_authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296502 };
6503
6504 MockRead data_reads2[] = {
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376505 // The origin server responds with a Type 2 message.
6506 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6507 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6508 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
6509 MockRead("Content-Type: text/html\r\n\r\n"),
6510 MockRead("You are not authorized to view this page\r\n"),
[email protected]385a4672009-03-11 22:21:296511
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376512 // Wrong password.
6513 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6514 MockRead("WWW-Authenticate: NTLM\r\n"), MockRead("Connection: close\r\n"),
6515 MockRead("Content-Length: 42\r\n"),
6516 MockRead("Content-Type: text/html\r\n\r\n"),
6517 // Missing content -- won't matter, as connection will be reset.
[email protected]385a4672009-03-11 22:21:296518 };
6519
6520 MockWrite data_writes3[] = {
bnc691fda62016-08-12 00:43:166521 // After restarting with a null identity, this is the
6522 // request we should be issuing -- the final header line contains a Type
6523 // 1 message.
6524 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556525 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166526 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376527 "Authorization: NTLM "),
6528 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296529
bnc691fda62016-08-12 00:43:166530 // After calling trans.RestartWithAuth(), we should send a Type 3 message
6531 // (the credentials for the origin server). The second request continues
6532 // on the same connection.
6533 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556534 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166535 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376536 "Authorization: NTLM "),
6537 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296538 };
6539
6540 MockRead data_reads3[] = {
Bence Béky1e4ef192017-09-18 19:58:026541 // The origin server responds with a Type 2 message.
6542 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376543 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6544 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky1e4ef192017-09-18 19:58:026545 MockRead("Content-Type: text/html\r\n\r\n"),
6546 MockRead("You are not authorized to view this page\r\n"),
[email protected]385a4672009-03-11 22:21:296547
Bence Béky1e4ef192017-09-18 19:58:026548 // Lastly we get the desired content.
6549 MockRead("HTTP/1.1 200 OK\r\n"),
6550 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
6551 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
[email protected]385a4672009-03-11 22:21:296552 };
6553
Ryan Sleevib8d7ea02018-05-07 20:01:016554 StaticSocketDataProvider data1(data_reads1, data_writes1);
6555 StaticSocketDataProvider data2(data_reads2, data_writes2);
6556 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]bb88e1d32013-05-03 23:11:076557 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6558 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6559 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:296560
Bence Béky83eb3512017-09-05 12:56:096561 SSLSocketDataProvider ssl1(ASYNC, OK);
6562 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
6563 SSLSocketDataProvider ssl2(ASYNC, OK);
6564 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6565 SSLSocketDataProvider ssl3(ASYNC, OK);
6566 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
6567
[email protected]49639fa2011-12-20 23:22:416568 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:296569
bnc691fda62016-08-12 00:43:166570 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506571
tfarina42834112016-09-22 13:38:206572 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016573 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:296574
6575 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016576 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:296577
bnc691fda62016-08-12 00:43:166578 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:296579
bnc691fda62016-08-12 00:43:166580 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526581 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046582 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:296583
[email protected]49639fa2011-12-20 23:22:416584 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:296585
[email protected]0757e7702009-03-27 04:00:226586 // Enter the wrong password.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376587 rv = trans.RestartWithAuth(
6588 AuthCredentials(ntlm::test::kDomainUserCombined, kWrongPassword),
6589 callback2.callback());
robpercival214763f2016-07-01 23:27:016590 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:296591
[email protected]10af5fe72011-01-31 16:17:256592 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016593 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:296594
bnc691fda62016-08-12 00:43:166595 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:416596 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:166597 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:016598 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256599 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016600 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166601 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:226602
bnc691fda62016-08-12 00:43:166603 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526604 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046605 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:226606
[email protected]49639fa2011-12-20 23:22:416607 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:226608
6609 // Now enter the right password.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376610 rv = trans.RestartWithAuth(
6611 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
6612 callback4.callback());
robpercival214763f2016-07-01 23:27:016613 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256614
6615 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:016616 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:256617
bnc691fda62016-08-12 00:43:166618 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:256619
[email protected]49639fa2011-12-20 23:22:416620 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:256621
6622 // One more roundtrip
bnc691fda62016-08-12 00:43:166623 rv = trans.RestartWithAuth(AuthCredentials(), callback5.callback());
robpercival214763f2016-07-01 23:27:016624 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:226625
6626 rv = callback5.WaitForResult();
robpercival214763f2016-07-01 23:27:016627 EXPECT_THAT(rv, IsOk());
[email protected]0757e7702009-03-27 04:00:226628
bnc691fda62016-08-12 00:43:166629 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526630 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:026631 EXPECT_EQ(14, response->headers->GetContentLength());
6632
6633 std::string response_data;
6634 rv = ReadTransaction(&trans, &response_data);
6635 EXPECT_THAT(rv, IsOk());
6636 EXPECT_EQ("Please Login\r\n", response_data);
6637
6638 EXPECT_TRUE(data1.AllReadDataConsumed());
6639 EXPECT_TRUE(data1.AllWriteDataConsumed());
6640 EXPECT_TRUE(data2.AllReadDataConsumed());
6641 EXPECT_TRUE(data2.AllWriteDataConsumed());
6642 EXPECT_TRUE(data3.AllReadDataConsumed());
6643 EXPECT_TRUE(data3.AllWriteDataConsumed());
[email protected]385a4672009-03-11 22:21:296644}
Bence Béky83eb3512017-09-05 12:56:096645
Bence Béky3238f2e12017-09-22 22:44:496646// Server requests NTLM authentication, which is not supported over HTTP/2.
6647// Subsequent request with authorization header should be sent over HTTP/1.1.
Bence Béky83eb3512017-09-05 12:56:096648TEST_F(HttpNetworkTransactionTest, NTLMOverHttp2) {
Zentaro Kavanagh6ccee512017-09-28 18:34:096649 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
6650 MockGetMSTime, MockGenerateRandom, MockGetHostName);
Bence Béky83eb3512017-09-05 12:56:096651
Zentaro Kavanagh1890a3d2018-01-29 19:52:556652 const char* kUrl = "https://server/kids/login.aspx";
Bence Béky83eb3512017-09-05 12:56:096653
6654 HttpRequestInfo request;
6655 request.method = "GET";
6656 request.url = GURL(kUrl);
Ramin Halavatib5e433e62018-02-07 07:41:106657 request.traffic_annotation =
6658 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Béky83eb3512017-09-05 12:56:096659
6660 // First request without credentials.
Ryan Hamilton0239aac2018-05-19 00:03:136661 spdy::SpdyHeaderBlock request_headers0(
6662 spdy_util_.ConstructGetHeaderBlock(kUrl));
6663 spdy::SpdySerializedFrame request0(spdy_util_.ConstructSpdyHeaders(
Bence Béky83eb3512017-09-05 12:56:096664 1, std::move(request_headers0), LOWEST, true));
6665
Ryan Hamilton0239aac2018-05-19 00:03:136666 spdy::SpdyHeaderBlock response_headers0;
6667 response_headers0[spdy::kHttp2StatusHeader] = "401";
Bence Béky83eb3512017-09-05 12:56:096668 response_headers0["www-authenticate"] = "NTLM";
Ryan Hamilton0239aac2018-05-19 00:03:136669 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyResponseHeaders(
Bence Béky83eb3512017-09-05 12:56:096670 1, std::move(response_headers0), true));
6671
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376672 // Stream 1 is closed.
6673 spdy_util_.UpdateWithStreamDestruction(1);
6674
6675 // Generate the NTLM messages based on known test data.
6676 std::string negotiate_msg;
6677 std::string challenge_msg;
6678 std::string authenticate_msg;
6679 base::Base64Encode(
6680 base::StringPiece(
6681 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
6682 arraysize(ntlm::test::kExpectedNegotiateMsg)),
6683 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:556684 base::Base64Encode(
6685 base::StringPiece(
6686 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
6687 arraysize(ntlm::test::kChallengeMsgFromSpecV2)),
6688 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376689 base::Base64Encode(
6690 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:096691 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:556692 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
6693 arraysize(
6694 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376695 &authenticate_msg);
6696
6697 // Retry with authorization header.
Ryan Hamilton0239aac2018-05-19 00:03:136698 spdy::SpdyHeaderBlock request_headers1(
6699 spdy_util_.ConstructGetHeaderBlock(kUrl));
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376700 request_headers1["authorization"] = std::string("NTLM ") + negotiate_msg;
Ryan Hamilton0239aac2018-05-19 00:03:136701 spdy::SpdySerializedFrame request1(spdy_util_.ConstructSpdyHeaders(
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376702 3, std::move(request_headers1), LOWEST, true));
6703
Ryan Hamilton0239aac2018-05-19 00:03:136704 spdy::SpdySerializedFrame rst(
6705 spdy_util_.ConstructSpdyRstStream(3, spdy::ERROR_CODE_HTTP_1_1_REQUIRED));
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376706
Bence Béky3238f2e12017-09-22 22:44:496707 MockWrite writes0[] = {CreateMockWrite(request0, 0)};
6708 MockRead reads0[] = {CreateMockRead(resp, 1), MockRead(ASYNC, 0, 2)};
Bence Béky83eb3512017-09-05 12:56:096709
6710 // Retry yet again using HTTP/1.1.
6711 MockWrite writes1[] = {
6712 // After restarting with a null identity, this is the
6713 // request we should be issuing -- the final header line contains a Type
6714 // 1 message.
6715 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556716 "Host: server\r\n"
Bence Béky83eb3512017-09-05 12:56:096717 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376718 "Authorization: NTLM "),
6719 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
Bence Béky83eb3512017-09-05 12:56:096720
6721 // After calling trans.RestartWithAuth(), we should send a Type 3 message
6722 // (the credentials for the origin server). The second request continues
6723 // on the same connection.
6724 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556725 "Host: server\r\n"
Bence Béky83eb3512017-09-05 12:56:096726 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376727 "Authorization: NTLM "),
6728 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
Bence Béky83eb3512017-09-05 12:56:096729 };
6730
6731 MockRead reads1[] = {
6732 // The origin server responds with a Type 2 message.
6733 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376734 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6735 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky83eb3512017-09-05 12:56:096736 MockRead("Content-Type: text/html\r\n\r\n"),
6737 MockRead("You are not authorized to view this page\r\n"),
6738
6739 // Lastly we get the desired content.
6740 MockRead("HTTP/1.1 200 OK\r\n"),
6741 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
Bence Béky1e4ef192017-09-18 19:58:026742 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
Bence Béky83eb3512017-09-05 12:56:096743 };
Ryan Sleevib8d7ea02018-05-07 20:01:016744 SequencedSocketData data0(reads0, writes0);
6745 StaticSocketDataProvider data1(reads1, writes1);
Bence Béky83eb3512017-09-05 12:56:096746 session_deps_.socket_factory->AddSocketDataProvider(&data0);
6747 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6748
6749 SSLSocketDataProvider ssl0(ASYNC, OK);
6750 ssl0.next_proto = kProtoHTTP2;
6751 SSLSocketDataProvider ssl1(ASYNC, OK);
6752 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl0);
6753 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
6754
6755 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6756 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
6757
6758 TestCompletionCallback callback1;
6759 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
6760 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6761
6762 rv = callback1.WaitForResult();
6763 EXPECT_THAT(rv, IsOk());
6764
6765 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
6766
6767 const HttpResponseInfo* response = trans.GetResponseInfo();
6768 ASSERT_TRUE(response);
6769 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
6770
6771 TestCompletionCallback callback2;
6772
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376773 rv = trans.RestartWithAuth(
6774 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
6775 callback2.callback());
Bence Béky83eb3512017-09-05 12:56:096776 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6777
6778 rv = callback2.WaitForResult();
6779 EXPECT_THAT(rv, IsOk());
6780
6781 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
6782
6783 response = trans.GetResponseInfo();
6784 ASSERT_TRUE(response);
6785 EXPECT_FALSE(response->auth_challenge);
6786
6787 TestCompletionCallback callback3;
6788
6789 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
6790 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6791
6792 rv = callback3.WaitForResult();
6793 EXPECT_THAT(rv, IsOk());
6794
6795 response = trans.GetResponseInfo();
6796 ASSERT_TRUE(response);
6797 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:026798 EXPECT_EQ(14, response->headers->GetContentLength());
6799
6800 std::string response_data;
6801 rv = ReadTransaction(&trans, &response_data);
6802 EXPECT_THAT(rv, IsOk());
6803 EXPECT_EQ("Please Login\r\n", response_data);
6804
6805 EXPECT_TRUE(data0.AllReadDataConsumed());
6806 EXPECT_TRUE(data0.AllWriteDataConsumed());
6807 EXPECT_TRUE(data1.AllReadDataConsumed());
6808 EXPECT_TRUE(data1.AllWriteDataConsumed());
Bence Béky83eb3512017-09-05 12:56:096809}
David Benjamin5cb91132018-04-06 05:54:496810
6811// Test that, if we have an NTLM proxy and the origin resets the connection, we
6812// do no retry forever checking for TLS version interference. This is a
6813// regression test for https://crbug.com/823387.
6814TEST_F(HttpNetworkTransactionTest, NTLMProxyTLSHandshakeReset) {
6815 // The NTLM test data expects the proxy to be named 'server'. The origin is
6816 // https://origin/.
6817 session_deps_.proxy_resolution_service =
6818 ProxyResolutionService::CreateFixedFromPacResult(
6819 "PROXY server", TRAFFIC_ANNOTATION_FOR_TESTS);
6820
6821 SSLConfig config;
6822 config.version_max = SSL_PROTOCOL_VERSION_TLS1_3;
6823 session_deps_.ssl_config_service =
6824 base::MakeRefCounted<TestSSLConfigService>(config);
6825
6826 HttpRequestInfo request;
6827 request.method = "GET";
6828 request.url = GURL("https://origin/");
6829 request.traffic_annotation =
6830 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6831
6832 // Ensure load is not disrupted by flags which suppress behaviour specific
6833 // to other auth schemes.
6834 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
6835
6836 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
6837 MockGetMSTime, MockGenerateRandom, MockGetHostName);
6838 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6839
6840 // Generate the NTLM messages based on known test data.
6841 std::string negotiate_msg;
6842 std::string challenge_msg;
6843 std::string authenticate_msg;
6844 base::Base64Encode(
6845 base::StringPiece(
6846 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
6847 arraysize(ntlm::test::kExpectedNegotiateMsg)),
6848 &negotiate_msg);
6849 base::Base64Encode(
6850 base::StringPiece(
6851 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
6852 arraysize(ntlm::test::kChallengeMsgFromSpecV2)),
6853 &challenge_msg);
6854 base::Base64Encode(
6855 base::StringPiece(
6856 reinterpret_cast<const char*>(
6857 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
6858 arraysize(
6859 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
6860 &authenticate_msg);
6861
6862 MockWrite data_writes[] = {
6863 // The initial CONNECT request.
6864 MockWrite("CONNECT origin:443 HTTP/1.1\r\n"
6865 "Host: origin:443\r\n"
6866 "Proxy-Connection: keep-alive\r\n\r\n"),
6867
6868 // After restarting with an identity.
6869 MockWrite("CONNECT origin:443 HTTP/1.1\r\n"
6870 "Host: origin:443\r\n"
6871 "Proxy-Connection: keep-alive\r\n"
6872 "Proxy-Authorization: NTLM "),
6873 MockWrite(negotiate_msg.c_str()),
6874 // End headers.
6875 MockWrite("\r\n\r\n"),
6876
6877 // The second restart.
6878 MockWrite("CONNECT origin:443 HTTP/1.1\r\n"
6879 "Host: origin:443\r\n"
6880 "Proxy-Connection: keep-alive\r\n"
6881 "Proxy-Authorization: NTLM "),
6882 MockWrite(authenticate_msg.c_str()),
6883 // End headers.
6884 MockWrite("\r\n\r\n"),
6885 };
6886
6887 MockRead data_reads[] = {
6888 // The initial NTLM response.
6889 MockRead("HTTP/1.1 407 Access Denied\r\n"
6890 "Content-Length: 0\r\n"
6891 "Proxy-Authenticate: NTLM\r\n\r\n"),
6892
6893 // The NTLM challenge message.
6894 MockRead("HTTP/1.1 407 Access Denied\r\n"
6895 "Content-Length: 0\r\n"
6896 "Proxy-Authenticate: NTLM "),
6897 MockRead(challenge_msg.c_str()),
6898 // End headers.
6899 MockRead("\r\n\r\n"),
6900
6901 // Finally the tunnel is established.
6902 MockRead("HTTP/1.1 200 Connected\r\n\r\n"),
6903 };
6904
Ryan Sleevib8d7ea02018-05-07 20:01:016905 StaticSocketDataProvider data(data_reads, data_writes);
David Benjamin5cb91132018-04-06 05:54:496906 SSLSocketDataProvider data_ssl(ASYNC, ERR_CONNECTION_RESET);
Ryan Sleevib8d7ea02018-05-07 20:01:016907 StaticSocketDataProvider data2(data_reads, data_writes);
David Benjamin5cb91132018-04-06 05:54:496908 SSLSocketDataProvider data_ssl2(ASYNC, ERR_CONNECTION_RESET);
6909 session_deps_.socket_factory->AddSocketDataProvider(&data);
6910 session_deps_.socket_factory->AddSSLSocketDataProvider(&data_ssl);
6911 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6912 session_deps_.socket_factory->AddSSLSocketDataProvider(&data_ssl2);
6913
6914 // Start the transaction. The proxy responds with an NTLM authentication
6915 // request.
6916 TestCompletionCallback callback;
6917 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
6918 int rv = callback.GetResult(
6919 trans.Start(&request, callback.callback(), NetLogWithSource()));
6920
6921 EXPECT_THAT(rv, IsOk());
6922 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
6923 const HttpResponseInfo* response = trans.GetResponseInfo();
6924 ASSERT_TRUE(response);
6925 EXPECT_TRUE(CheckNTLMProxyAuth(response->auth_challenge.get()));
6926
6927 // Configure credentials. The proxy responds with the challenge message.
6928 rv = callback.GetResult(trans.RestartWithAuth(
6929 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
6930 callback.callback()));
6931 EXPECT_THAT(rv, IsOk());
6932 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
6933 response = trans.GetResponseInfo();
6934 ASSERT_TRUE(response);
6935 EXPECT_FALSE(response->auth_challenge);
6936
6937 // Restart once more. The tunnel will be established and the the SSL handshake
6938 // will reset. The TLS 1.3 version interference probe will then kick in and
6939 // restart the process. The proxy responds with another NTLM authentiation
6940 // request, but we don't need to provide credentials as the cached ones work/
6941 rv = callback.GetResult(
6942 trans.RestartWithAuth(AuthCredentials(), callback.callback()));
6943 EXPECT_THAT(rv, IsOk());
6944 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
6945 response = trans.GetResponseInfo();
6946 ASSERT_TRUE(response);
6947 EXPECT_FALSE(response->auth_challenge);
6948
6949 // The proxy responds with the NTLM challenge message.
6950 rv = callback.GetResult(
6951 trans.RestartWithAuth(AuthCredentials(), callback.callback()));
6952 EXPECT_THAT(rv, IsOk());
6953 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
6954 response = trans.GetResponseInfo();
6955 ASSERT_TRUE(response);
6956 EXPECT_FALSE(response->auth_challenge);
6957
6958 // Send the NTLM authenticate message. The tunnel is established and the
6959 // handshake resets again. We should not retry again.
6960 rv = callback.GetResult(
6961 trans.RestartWithAuth(AuthCredentials(), callback.callback()));
6962 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
6963}
6964
[email protected]ea9dc9a2009-09-05 00:43:326965#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:296966
[email protected]4ddaf2502008-10-23 18:26:196967// Test reading a server response which has only headers, and no body.
6968// After some maximum number of bytes is consumed, the transaction should
6969// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
bncd16676a2016-07-20 16:23:016970TEST_F(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:426971 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:196972 request.method = "GET";
bncce36dca22015-04-21 22:11:236973 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:106974 request.traffic_annotation =
6975 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]4ddaf2502008-10-23 18:26:196976
danakj1fd259a02016-04-16 03:17:096977 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166978 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:276979
[email protected]b75b7b2f2009-10-06 00:54:536980 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:436981 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:536982 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:196983
6984 MockRead data_reads[] = {
6985 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:066986 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:196987 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:066988 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:196989 };
Ryan Sleevib8d7ea02018-05-07 20:01:016990 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:076991 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:196992
[email protected]49639fa2011-12-20 23:22:416993 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:196994
tfarina42834112016-09-22 13:38:206995 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016996 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]4ddaf2502008-10-23 18:26:196997
6998 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016999 EXPECT_THAT(rv, IsError(ERR_RESPONSE_HEADERS_TOO_BIG));
[email protected]4ddaf2502008-10-23 18:26:197000}
[email protected]f4e426b2008-11-05 00:24:497001
7002// Make sure that we don't try to reuse a TCPClientSocket when failing to
7003// establish tunnel.
7004// http://code.google.com/p/chromium/issues/detail?id=3772
bncd16676a2016-07-20 16:23:017005TEST_F(HttpNetworkTransactionTest, DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:277006 HttpRequestInfo request;
7007 request.method = "GET";
bncce36dca22015-04-21 22:11:237008 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:107009 request.traffic_annotation =
7010 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:277011
[email protected]f4e426b2008-11-05 00:24:497012 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:497013 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
7014 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]db8f44c2008-12-13 04:52:017015
danakj1fd259a02016-04-16 03:17:097016 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:497017
bnc87dcefc2017-05-25 12:47:587018 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:197019 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]f4e426b2008-11-05 00:24:497020
[email protected]f4e426b2008-11-05 00:24:497021 // Since we have proxy, should try to establish tunnel.
7022 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:177023 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7024 "Host: www.example.org:443\r\n"
7025 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:497026 };
7027
[email protected]77848d12008-11-14 00:00:227028 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:497029 // connection. Usually a proxy would return 501 (not implemented),
7030 // or 200 (tunnel established).
7031 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:237032 MockRead("HTTP/1.1 404 Not Found\r\n"),
7033 MockRead("Content-Length: 10\r\n\r\n"),
7034 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]f4e426b2008-11-05 00:24:497035 };
7036
Ryan Sleevib8d7ea02018-05-07 20:01:017037 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:077038 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:497039
[email protected]49639fa2011-12-20 23:22:417040 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:497041
tfarina42834112016-09-22 13:38:207042 int rv = trans->Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017043 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f4e426b2008-11-05 00:24:497044
7045 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017046 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]f4e426b2008-11-05 00:24:497047
[email protected]b4404c02009-04-10 16:38:527048 // Empty the current queue. This is necessary because idle sockets are
7049 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557050 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:527051
[email protected]f4e426b2008-11-05 00:24:497052 // We now check to make sure the TCPClientSocket was not added back to
7053 // the pool.
[email protected]90499482013-06-01 00:39:507054 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:497055 trans.reset();
fdoray92e35a72016-06-10 15:54:557056 base::RunLoop().RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:497057 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:507058 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:497059}
[email protected]372d34a2008-11-05 21:30:517060
[email protected]1b157c02009-04-21 01:55:407061// Make sure that we recycle a socket after reading all of the response body.
bncd16676a2016-07-20 16:23:017062TEST_F(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:427063 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:407064 request.method = "GET";
bncce36dca22015-04-21 22:11:237065 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:107066 request.traffic_annotation =
7067 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1b157c02009-04-21 01:55:407068
danakj1fd259a02016-04-16 03:17:097069 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277070
bnc691fda62016-08-12 00:43:167071 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277072
[email protected]1b157c02009-04-21 01:55:407073 MockRead data_reads[] = {
7074 // A part of the response body is received with the response headers.
7075 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
7076 // The rest of the response body is received in two parts.
7077 MockRead("lo"),
7078 MockRead(" world"),
7079 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:067080 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:407081 };
7082
Ryan Sleevib8d7ea02018-05-07 20:01:017083 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:077084 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:407085
[email protected]49639fa2011-12-20 23:22:417086 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:407087
tfarina42834112016-09-22 13:38:207088 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017089 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1b157c02009-04-21 01:55:407090
7091 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017092 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:407093
bnc691fda62016-08-12 00:43:167094 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527095 ASSERT_TRUE(response);
[email protected]1b157c02009-04-21 01:55:407096
wezca1070932016-05-26 20:30:527097 EXPECT_TRUE(response->headers);
[email protected]1b157c02009-04-21 01:55:407098 std::string status_line = response->headers->GetStatusLine();
7099 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
7100
[email protected]90499482013-06-01 00:39:507101 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:407102
7103 std::string response_data;
bnc691fda62016-08-12 00:43:167104 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017105 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:407106 EXPECT_EQ("hello world", response_data);
7107
7108 // Empty the current queue. This is necessary because idle sockets are
7109 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557110 base::RunLoop().RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:407111
7112 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507113 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:407114}
7115
[email protected]76a505b2010-08-25 06:23:007116// Make sure that we recycle a SSL socket after reading all of the response
7117// body.
bncd16676a2016-07-20 16:23:017118TEST_F(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:007119 HttpRequestInfo request;
7120 request.method = "GET";
bncce36dca22015-04-21 22:11:237121 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:107122 request.traffic_annotation =
7123 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:007124
7125 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237126 MockWrite(
7127 "GET / HTTP/1.1\r\n"
7128 "Host: www.example.org\r\n"
7129 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:007130 };
7131
7132 MockRead data_reads[] = {
7133 MockRead("HTTP/1.1 200 OK\r\n"),
7134 MockRead("Content-Length: 11\r\n\r\n"),
7135 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:067136 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:007137 };
7138
[email protected]8ddf8322012-02-23 18:08:067139 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077140 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:007141
Ryan Sleevib8d7ea02018-05-07 20:01:017142 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:077143 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:007144
[email protected]49639fa2011-12-20 23:22:417145 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:007146
danakj1fd259a02016-04-16 03:17:097147 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167148 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:007149
tfarina42834112016-09-22 13:38:207150 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:007151
robpercival214763f2016-07-01 23:27:017152 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7153 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:007154
bnc691fda62016-08-12 00:43:167155 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527156 ASSERT_TRUE(response);
7157 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:007158 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7159
[email protected]90499482013-06-01 00:39:507160 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007161
7162 std::string response_data;
bnc691fda62016-08-12 00:43:167163 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017164 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:007165 EXPECT_EQ("hello world", response_data);
7166
7167 // Empty the current queue. This is necessary because idle sockets are
7168 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557169 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:007170
7171 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507172 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007173}
7174
7175// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
7176// from the pool and make sure that we recover okay.
bncd16676a2016-07-20 16:23:017177TEST_F(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:007178 HttpRequestInfo request;
7179 request.method = "GET";
bncce36dca22015-04-21 22:11:237180 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:107181 request.traffic_annotation =
7182 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:007183
7184 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237185 MockWrite(
7186 "GET / HTTP/1.1\r\n"
7187 "Host: www.example.org\r\n"
7188 "Connection: keep-alive\r\n\r\n"),
7189 MockWrite(
7190 "GET / HTTP/1.1\r\n"
7191 "Host: www.example.org\r\n"
7192 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:007193 };
7194
7195 MockRead data_reads[] = {
mmenke911ee0222015-12-04 03:58:427196 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
7197 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
[email protected]76a505b2010-08-25 06:23:007198
[email protected]8ddf8322012-02-23 18:08:067199 SSLSocketDataProvider ssl(ASYNC, OK);
7200 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077201 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7202 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:007203
Ryan Sleevib8d7ea02018-05-07 20:01:017204 StaticSocketDataProvider data(data_reads, data_writes);
7205 StaticSocketDataProvider data2(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:077206 session_deps_.socket_factory->AddSocketDataProvider(&data);
7207 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:007208
[email protected]49639fa2011-12-20 23:22:417209 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:007210
danakj1fd259a02016-04-16 03:17:097211 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:587212 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:197213 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:007214
tfarina42834112016-09-22 13:38:207215 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:007216
robpercival214763f2016-07-01 23:27:017217 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7218 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:007219
7220 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:527221 ASSERT_TRUE(response);
7222 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:007223 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7224
[email protected]90499482013-06-01 00:39:507225 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007226
7227 std::string response_data;
7228 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:017229 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:007230 EXPECT_EQ("hello world", response_data);
7231
7232 // Empty the current queue. This is necessary because idle sockets are
7233 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557234 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:007235
7236 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507237 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007238
7239 // Now start the second transaction, which should reuse the previous socket.
7240
bnc87dcefc2017-05-25 12:47:587241 trans =
Jeremy Roman0579ed62017-08-29 15:56:197242 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:007243
tfarina42834112016-09-22 13:38:207244 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:007245
robpercival214763f2016-07-01 23:27:017246 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7247 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:007248
7249 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:527250 ASSERT_TRUE(response);
7251 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:007252 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7253
[email protected]90499482013-06-01 00:39:507254 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007255
7256 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:017257 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:007258 EXPECT_EQ("hello world", response_data);
7259
7260 // Empty the current queue. This is necessary because idle sockets are
7261 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557262 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:007263
7264 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507265 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007266}
7267
maksim.sisov0adf8592016-07-15 06:25:567268// Grab a socket, use it, and put it back into the pool. Then, make
7269// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:017270TEST_F(HttpNetworkTransactionTest, FlushSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:567271 HttpRequestInfo request;
7272 request.method = "GET";
7273 request.url = GURL("http://www.example.org/");
7274 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:107275 request.traffic_annotation =
7276 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
maksim.sisov0adf8592016-07-15 06:25:567277
7278 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7279
bnc691fda62016-08-12 00:43:167280 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:567281
7282 MockRead data_reads[] = {
7283 // A part of the response body is received with the response headers.
7284 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
7285 // The rest of the response body is received in two parts.
7286 MockRead("lo"), MockRead(" world"),
7287 MockRead("junk"), // Should not be read!!
7288 MockRead(SYNCHRONOUS, OK),
7289 };
7290
Ryan Sleevib8d7ea02018-05-07 20:01:017291 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
maksim.sisov0adf8592016-07-15 06:25:567292 session_deps_.socket_factory->AddSocketDataProvider(&data);
7293
7294 TestCompletionCallback callback;
7295
tfarina42834112016-09-22 13:38:207296 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:567297 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7298
7299 EXPECT_THAT(callback.GetResult(rv), IsOk());
7300
bnc691fda62016-08-12 00:43:167301 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:567302 ASSERT_TRUE(response);
7303 EXPECT_TRUE(response->headers);
7304 std::string status_line = response->headers->GetStatusLine();
7305 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
7306
7307 // Make memory critical notification and ensure the transaction still has been
7308 // operating right.
7309 base::MemoryPressureListener::NotifyMemoryPressure(
7310 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7311 base::RunLoop().RunUntilIdle();
7312
7313 // Socket should not be flushed as long as it is not idle.
7314 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
7315
7316 std::string response_data;
bnc691fda62016-08-12 00:43:167317 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:567318 EXPECT_THAT(rv, IsOk());
7319 EXPECT_EQ("hello world", response_data);
7320
7321 // Empty the current queue. This is necessary because idle sockets are
7322 // added to the connection pool asynchronously with a PostTask.
7323 base::RunLoop().RunUntilIdle();
7324
7325 // We now check to make sure the socket was added back to the pool.
7326 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
7327
7328 // Idle sockets should be flushed now.
7329 base::MemoryPressureListener::NotifyMemoryPressure(
7330 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7331 base::RunLoop().RunUntilIdle();
7332
7333 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
7334}
7335
yucliu48f235d2018-01-11 00:59:557336// Disable idle socket closing on memory pressure.
7337// Grab a socket, use it, and put it back into the pool. Then, make
7338// low memory notification and ensure the socket pool is NOT flushed.
7339TEST_F(HttpNetworkTransactionTest, NoFlushSocketPoolOnLowMemoryNotifications) {
7340 HttpRequestInfo request;
7341 request.method = "GET";
7342 request.url = GURL("http://www.example.org/");
7343 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:107344 request.traffic_annotation =
7345 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
yucliu48f235d2018-01-11 00:59:557346
7347 // Disable idle socket closing on memory pressure.
7348 session_deps_.disable_idle_sockets_close_on_memory_pressure = true;
7349 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7350
7351 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
7352
7353 MockRead data_reads[] = {
7354 // A part of the response body is received with the response headers.
7355 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
7356 // The rest of the response body is received in two parts.
7357 MockRead("lo"), MockRead(" world"),
7358 MockRead("junk"), // Should not be read!!
7359 MockRead(SYNCHRONOUS, OK),
7360 };
7361
Ryan Sleevib8d7ea02018-05-07 20:01:017362 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
yucliu48f235d2018-01-11 00:59:557363 session_deps_.socket_factory->AddSocketDataProvider(&data);
7364
7365 TestCompletionCallback callback;
7366
7367 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
7368 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7369
7370 EXPECT_THAT(callback.GetResult(rv), IsOk());
7371
7372 const HttpResponseInfo* response = trans.GetResponseInfo();
7373 ASSERT_TRUE(response);
7374 EXPECT_TRUE(response->headers);
7375 std::string status_line = response->headers->GetStatusLine();
7376 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
7377
7378 // Make memory critical notification and ensure the transaction still has been
7379 // operating right.
7380 base::MemoryPressureListener::NotifyMemoryPressure(
7381 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7382 base::RunLoop().RunUntilIdle();
7383
7384 // Socket should not be flushed as long as it is not idle.
7385 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
7386
7387 std::string response_data;
7388 rv = ReadTransaction(&trans, &response_data);
7389 EXPECT_THAT(rv, IsOk());
7390 EXPECT_EQ("hello world", response_data);
7391
7392 // Empty the current queue. This is necessary because idle sockets are
7393 // added to the connection pool asynchronously with a PostTask.
7394 base::RunLoop().RunUntilIdle();
7395
7396 // We now check to make sure the socket was added back to the pool.
7397 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
7398
7399 // Idle sockets should NOT be flushed on moderate memory pressure.
7400 base::MemoryPressureListener::NotifyMemoryPressure(
7401 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE);
7402 base::RunLoop().RunUntilIdle();
7403
7404 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
7405
7406 // Idle sockets should NOT be flushed on critical memory pressure.
7407 base::MemoryPressureListener::NotifyMemoryPressure(
7408 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7409 base::RunLoop().RunUntilIdle();
7410
7411 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
7412}
7413
maksim.sisov0adf8592016-07-15 06:25:567414// Grab an SSL socket, use it, and put it back into the pool. Then, make
7415// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:017416TEST_F(HttpNetworkTransactionTest, FlushSSLSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:567417 HttpRequestInfo request;
7418 request.method = "GET";
7419 request.url = GURL("https://www.example.org/");
7420 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:107421 request.traffic_annotation =
7422 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
maksim.sisov0adf8592016-07-15 06:25:567423
7424 MockWrite data_writes[] = {
7425 MockWrite("GET / HTTP/1.1\r\n"
7426 "Host: www.example.org\r\n"
7427 "Connection: keep-alive\r\n\r\n"),
7428 };
7429
7430 MockRead data_reads[] = {
7431 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
7432 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
7433
7434 SSLSocketDataProvider ssl(ASYNC, OK);
7435 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7436
Ryan Sleevib8d7ea02018-05-07 20:01:017437 StaticSocketDataProvider data(data_reads, data_writes);
maksim.sisov0adf8592016-07-15 06:25:567438 session_deps_.socket_factory->AddSocketDataProvider(&data);
7439
7440 TestCompletionCallback callback;
7441
7442 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167443 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:567444
7445 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
tfarina42834112016-09-22 13:38:207446 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:567447
7448 EXPECT_THAT(callback.GetResult(rv), IsOk());
7449
bnc691fda62016-08-12 00:43:167450 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:567451 ASSERT_TRUE(response);
7452 ASSERT_TRUE(response->headers);
7453 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7454
7455 // Make memory critical notification and ensure the transaction still has been
7456 // operating right.
7457 base::MemoryPressureListener::NotifyMemoryPressure(
7458 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7459 base::RunLoop().RunUntilIdle();
7460
7461 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
7462
7463 std::string response_data;
bnc691fda62016-08-12 00:43:167464 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:567465 EXPECT_THAT(rv, IsOk());
7466 EXPECT_EQ("hello world", response_data);
7467
7468 // Empty the current queue. This is necessary because idle sockets are
7469 // added to the connection pool asynchronously with a PostTask.
7470 base::RunLoop().RunUntilIdle();
7471
7472 // We now check to make sure the socket was added back to the pool.
7473 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
7474
7475 // Make memory notification once again and ensure idle socket is closed.
7476 base::MemoryPressureListener::NotifyMemoryPressure(
7477 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7478 base::RunLoop().RunUntilIdle();
7479
7480 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
7481}
7482
[email protected]b4404c02009-04-10 16:38:527483// Make sure that we recycle a socket after a zero-length response.
7484// http://crbug.com/9880
bncd16676a2016-07-20 16:23:017485TEST_F(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:427486 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:527487 request.method = "GET";
bncce36dca22015-04-21 22:11:237488 request.url = GURL(
7489 "http://www.example.org/csi?v=3&s=web&action=&"
7490 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
7491 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
7492 "rt=prt.2642,ol.2649,xjs.2951");
Ramin Halavatib5e433e62018-02-07 07:41:107493 request.traffic_annotation =
7494 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]b4404c02009-04-10 16:38:527495
danakj1fd259a02016-04-16 03:17:097496 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277497
[email protected]b4404c02009-04-10 16:38:527498 MockRead data_reads[] = {
7499 MockRead("HTTP/1.1 204 No Content\r\n"
7500 "Content-Length: 0\r\n"
7501 "Content-Type: text/html\r\n\r\n"),
7502 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:067503 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:527504 };
7505
Ryan Sleevib8d7ea02018-05-07 20:01:017506 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:077507 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:527508
mmenkecc2298e2015-12-07 18:20:187509 // Transaction must be created after the MockReads, so it's destroyed before
7510 // them.
bnc691fda62016-08-12 00:43:167511 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkecc2298e2015-12-07 18:20:187512
[email protected]49639fa2011-12-20 23:22:417513 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:527514
tfarina42834112016-09-22 13:38:207515 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017516 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]b4404c02009-04-10 16:38:527517
7518 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017519 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:527520
bnc691fda62016-08-12 00:43:167521 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527522 ASSERT_TRUE(response);
[email protected]b4404c02009-04-10 16:38:527523
wezca1070932016-05-26 20:30:527524 EXPECT_TRUE(response->headers);
[email protected]b4404c02009-04-10 16:38:527525 std::string status_line = response->headers->GetStatusLine();
7526 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
7527
[email protected]90499482013-06-01 00:39:507528 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:527529
7530 std::string response_data;
bnc691fda62016-08-12 00:43:167531 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017532 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:527533 EXPECT_EQ("", response_data);
7534
7535 // Empty the current queue. This is necessary because idle sockets are
7536 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557537 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:527538
7539 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507540 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:527541}
7542
bncd16676a2016-07-20 16:23:017543TEST_F(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
danakj1fd259a02016-04-16 03:17:097544 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:227545 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:197546 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:227547 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:277548
[email protected]1c773ea12009-04-28 19:58:427549 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:517550 // Transaction 1: a GET request that succeeds. The socket is recycled
7551 // after use.
7552 request[0].method = "GET";
7553 request[0].url = GURL("http://www.google.com/");
7554 request[0].load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:107555 request[0].traffic_annotation =
7556 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]372d34a2008-11-05 21:30:517557 // Transaction 2: a POST request. Reuses the socket kept alive from
7558 // transaction 1. The first attempts fails when writing the POST data.
7559 // This causes the transaction to retry with a new socket. The second
7560 // attempt succeeds.
7561 request[1].method = "POST";
7562 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:277563 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:517564 request[1].load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:107565 request[1].traffic_annotation =
7566 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]372d34a2008-11-05 21:30:517567
danakj1fd259a02016-04-16 03:17:097568 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:517569
7570 // The first socket is used for transaction 1 and the first attempt of
7571 // transaction 2.
7572
7573 // The response of transaction 1.
7574 MockRead data_reads1[] = {
7575 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
7576 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:067577 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:517578 };
7579 // The mock write results of transaction 1 and the first attempt of
7580 // transaction 2.
7581 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:067582 MockWrite(SYNCHRONOUS, 64), // GET
7583 MockWrite(SYNCHRONOUS, 93), // POST
7584 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:517585 };
Ryan Sleevib8d7ea02018-05-07 20:01:017586 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]372d34a2008-11-05 21:30:517587
7588 // The second socket is used for the second attempt of transaction 2.
7589
7590 // The response of transaction 2.
7591 MockRead data_reads2[] = {
7592 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
7593 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:067594 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:517595 };
7596 // The mock write results of the second attempt of transaction 2.
7597 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:067598 MockWrite(SYNCHRONOUS, 93), // POST
7599 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:517600 };
Ryan Sleevib8d7ea02018-05-07 20:01:017601 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]372d34a2008-11-05 21:30:517602
[email protected]bb88e1d32013-05-03 23:11:077603 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7604 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:517605
thestig9d3bb0c2015-01-24 00:49:517606 const char* const kExpectedResponseData[] = {
[email protected]372d34a2008-11-05 21:30:517607 "hello world", "welcome"
7608 };
7609
7610 for (int i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:167611 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]372d34a2008-11-05 21:30:517612
[email protected]49639fa2011-12-20 23:22:417613 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:517614
tfarina42834112016-09-22 13:38:207615 int rv = trans.Start(&request[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017616 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]372d34a2008-11-05 21:30:517617
7618 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017619 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:517620
bnc691fda62016-08-12 00:43:167621 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527622 ASSERT_TRUE(response);
[email protected]372d34a2008-11-05 21:30:517623
wezca1070932016-05-26 20:30:527624 EXPECT_TRUE(response->headers);
[email protected]372d34a2008-11-05 21:30:517625 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7626
7627 std::string response_data;
bnc691fda62016-08-12 00:43:167628 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017629 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:517630 EXPECT_EQ(kExpectedResponseData[i], response_data);
7631 }
7632}
[email protected]f9ee6b52008-11-08 06:46:237633
7634// Test the request-challenge-retry sequence for basic auth when there is
7635// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:167636// it fails the identity from the URL is used to answer the challenge.
bncd16676a2016-07-20 16:23:017637TEST_F(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:427638 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237639 request.method = "GET";
bncce36dca22015-04-21 22:11:237640 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:417641 request.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:107642 request.traffic_annotation =
7643 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]a97cca42009-08-14 01:00:297644
danakj1fd259a02016-04-16 03:17:097645 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167646 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277647
[email protected]a97cca42009-08-14 01:00:297648 // The password contains an escaped character -- for this test to pass it
7649 // will need to be unescaped by HttpNetworkTransaction.
7650 EXPECT_EQ("b%40r", request.url.password());
7651
[email protected]f9ee6b52008-11-08 06:46:237652 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237653 MockWrite(
7654 "GET / HTTP/1.1\r\n"
7655 "Host: www.example.org\r\n"
7656 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237657 };
7658
7659 MockRead data_reads1[] = {
7660 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7661 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7662 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067663 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237664 };
7665
[email protected]2262e3a2012-05-22 16:08:167666 // After the challenge above, the transaction will be restarted using the
7667 // identity from the url (foo, b@r) to answer the challenge.
7668 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237669 MockWrite(
7670 "GET / HTTP/1.1\r\n"
7671 "Host: www.example.org\r\n"
7672 "Connection: keep-alive\r\n"
7673 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167674 };
7675
7676 MockRead data_reads2[] = {
7677 MockRead("HTTP/1.0 200 OK\r\n"),
7678 MockRead("Content-Length: 100\r\n\r\n"),
7679 MockRead(SYNCHRONOUS, OK),
7680 };
7681
Ryan Sleevib8d7ea02018-05-07 20:01:017682 StaticSocketDataProvider data1(data_reads1, data_writes1);
7683 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:077684 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7685 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237686
[email protected]49639fa2011-12-20 23:22:417687 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:207688 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017689 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237690 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017691 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167692 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167693
7694 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167695 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017696 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167697 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017698 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167699 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227700
bnc691fda62016-08-12 00:43:167701 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527702 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:167703
7704 // There is no challenge info, since the identity in URL worked.
wezca1070932016-05-26 20:30:527705 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:167706
7707 EXPECT_EQ(100, response->headers->GetContentLength());
7708
7709 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557710 base::RunLoop().RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:167711}
7712
7713// Test the request-challenge-retry sequence for basic auth when there is an
7714// incorrect identity in the URL. The identity from the URL should be used only
7715// once.
bncd16676a2016-07-20 16:23:017716TEST_F(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:167717 HttpRequestInfo request;
7718 request.method = "GET";
7719 // Note: the URL has a username:password in it. The password "baz" is
7720 // wrong (should be "bar").
bncce36dca22015-04-21 22:11:237721 request.url = GURL("http://foo:[email protected]/");
[email protected]2262e3a2012-05-22 16:08:167722
7723 request.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:107724 request.traffic_annotation =
7725 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2262e3a2012-05-22 16:08:167726
danakj1fd259a02016-04-16 03:17:097727 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167728 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2262e3a2012-05-22 16:08:167729
7730 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237731 MockWrite(
7732 "GET / HTTP/1.1\r\n"
7733 "Host: www.example.org\r\n"
7734 "Connection: keep-alive\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167735 };
7736
7737 MockRead data_reads1[] = {
7738 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7739 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7740 MockRead("Content-Length: 10\r\n\r\n"),
7741 MockRead(SYNCHRONOUS, ERR_FAILED),
7742 };
7743
7744 // After the challenge above, the transaction will be restarted using the
7745 // identity from the url (foo, baz) to answer the challenge.
7746 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237747 MockWrite(
7748 "GET / HTTP/1.1\r\n"
7749 "Host: www.example.org\r\n"
7750 "Connection: keep-alive\r\n"
7751 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167752 };
7753
7754 MockRead data_reads2[] = {
7755 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7756 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7757 MockRead("Content-Length: 10\r\n\r\n"),
7758 MockRead(SYNCHRONOUS, ERR_FAILED),
7759 };
7760
7761 // After the challenge above, the transaction will be restarted using the
7762 // identity supplied by the user (foo, bar) to answer the challenge.
7763 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237764 MockWrite(
7765 "GET / HTTP/1.1\r\n"
7766 "Host: www.example.org\r\n"
7767 "Connection: keep-alive\r\n"
7768 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167769 };
7770
7771 MockRead data_reads3[] = {
7772 MockRead("HTTP/1.0 200 OK\r\n"),
7773 MockRead("Content-Length: 100\r\n\r\n"),
7774 MockRead(SYNCHRONOUS, OK),
7775 };
7776
Ryan Sleevib8d7ea02018-05-07 20:01:017777 StaticSocketDataProvider data1(data_reads1, data_writes1);
7778 StaticSocketDataProvider data2(data_reads2, data_writes2);
7779 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]bb88e1d32013-05-03 23:11:077780 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7781 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7782 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:167783
7784 TestCompletionCallback callback1;
7785
tfarina42834112016-09-22 13:38:207786 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017787 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167788
7789 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017790 EXPECT_THAT(rv, IsOk());
[email protected]2262e3a2012-05-22 16:08:167791
bnc691fda62016-08-12 00:43:167792 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167793 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167794 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017795 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167796 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017797 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167798 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167799
bnc691fda62016-08-12 00:43:167800 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527801 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:167802 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
7803
7804 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:167805 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:017806 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167807 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017808 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167809 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167810
bnc691fda62016-08-12 00:43:167811 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527812 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:167813
7814 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:527815 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:167816
7817 EXPECT_EQ(100, response->headers->GetContentLength());
7818
[email protected]ea9dc9a2009-09-05 00:43:327819 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557820 base::RunLoop().RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:327821}
7822
[email protected]2217aa22013-10-11 03:03:547823
7824// Test the request-challenge-retry sequence for basic auth when there is a
7825// correct identity in the URL, but its use is being suppressed. The identity
7826// from the URL should never be used.
bncd16676a2016-07-20 16:23:017827TEST_F(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
[email protected]2217aa22013-10-11 03:03:547828 HttpRequestInfo request;
7829 request.method = "GET";
bncce36dca22015-04-21 22:11:237830 request.url = GURL("http://foo:[email protected]/");
[email protected]2217aa22013-10-11 03:03:547831 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
Ramin Halavatib5e433e62018-02-07 07:41:107832 request.traffic_annotation =
7833 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2217aa22013-10-11 03:03:547834
danakj1fd259a02016-04-16 03:17:097835 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167836 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2217aa22013-10-11 03:03:547837
7838 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237839 MockWrite(
7840 "GET / HTTP/1.1\r\n"
7841 "Host: www.example.org\r\n"
7842 "Connection: keep-alive\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:547843 };
7844
7845 MockRead data_reads1[] = {
7846 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7847 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7848 MockRead("Content-Length: 10\r\n\r\n"),
7849 MockRead(SYNCHRONOUS, ERR_FAILED),
7850 };
7851
7852 // After the challenge above, the transaction will be restarted using the
7853 // identity supplied by the user, not the one in the URL, to answer the
7854 // challenge.
7855 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237856 MockWrite(
7857 "GET / HTTP/1.1\r\n"
7858 "Host: www.example.org\r\n"
7859 "Connection: keep-alive\r\n"
7860 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:547861 };
7862
7863 MockRead data_reads3[] = {
7864 MockRead("HTTP/1.0 200 OK\r\n"),
7865 MockRead("Content-Length: 100\r\n\r\n"),
7866 MockRead(SYNCHRONOUS, OK),
7867 };
7868
Ryan Sleevib8d7ea02018-05-07 20:01:017869 StaticSocketDataProvider data1(data_reads1, data_writes1);
7870 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]2217aa22013-10-11 03:03:547871 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7872 session_deps_.socket_factory->AddSocketDataProvider(&data3);
7873
7874 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:207875 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017876 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:547877 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017878 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167879 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:547880
bnc691fda62016-08-12 00:43:167881 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527882 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:547883 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
7884
7885 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:167886 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:017887 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:547888 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017889 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167890 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:547891
bnc691fda62016-08-12 00:43:167892 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527893 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:547894
7895 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:527896 EXPECT_FALSE(response->auth_challenge);
[email protected]2217aa22013-10-11 03:03:547897 EXPECT_EQ(100, response->headers->GetContentLength());
7898
7899 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557900 base::RunLoop().RunUntilIdle();
[email protected]2217aa22013-10-11 03:03:547901}
7902
[email protected]f9ee6b52008-11-08 06:46:237903// Test that previously tried username/passwords for a realm get re-used.
bncd16676a2016-07-20 16:23:017904TEST_F(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
danakj1fd259a02016-04-16 03:17:097905 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:237906
7907 // Transaction 1: authenticate (foo, bar) on MyRealm1
7908 {
[email protected]1c773ea12009-04-28 19:58:427909 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237910 request.method = "GET";
bncce36dca22015-04-21 22:11:237911 request.url = GURL("http://www.example.org/x/y/z");
Ramin Halavatib5e433e62018-02-07 07:41:107912 request.traffic_annotation =
7913 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:237914
bnc691fda62016-08-12 00:43:167915 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277916
[email protected]f9ee6b52008-11-08 06:46:237917 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237918 MockWrite(
7919 "GET /x/y/z HTTP/1.1\r\n"
7920 "Host: www.example.org\r\n"
7921 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237922 };
7923
7924 MockRead data_reads1[] = {
7925 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7926 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7927 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067928 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237929 };
7930
7931 // Resend with authorization (username=foo, password=bar)
7932 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237933 MockWrite(
7934 "GET /x/y/z HTTP/1.1\r\n"
7935 "Host: www.example.org\r\n"
7936 "Connection: keep-alive\r\n"
7937 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237938 };
7939
7940 // Sever accepts the authorization.
7941 MockRead data_reads2[] = {
7942 MockRead("HTTP/1.0 200 OK\r\n"),
7943 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067944 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237945 };
7946
Ryan Sleevib8d7ea02018-05-07 20:01:017947 StaticSocketDataProvider data1(data_reads1, data_writes1);
7948 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:077949 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7950 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237951
[email protected]49639fa2011-12-20 23:22:417952 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237953
tfarina42834112016-09-22 13:38:207954 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017955 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237956
7957 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017958 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237959
bnc691fda62016-08-12 00:43:167960 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527961 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047962 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:237963
[email protected]49639fa2011-12-20 23:22:417964 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:237965
bnc691fda62016-08-12 00:43:167966 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
7967 callback2.callback());
robpercival214763f2016-07-01 23:27:017968 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237969
7970 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017971 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237972
bnc691fda62016-08-12 00:43:167973 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527974 ASSERT_TRUE(response);
7975 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237976 EXPECT_EQ(100, response->headers->GetContentLength());
7977 }
7978
7979 // ------------------------------------------------------------------------
7980
7981 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
7982 {
[email protected]1c773ea12009-04-28 19:58:427983 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237984 request.method = "GET";
7985 // Note that Transaction 1 was at /x/y/z, so this is in the same
7986 // protection space as MyRealm1.
bncce36dca22015-04-21 22:11:237987 request.url = GURL("http://www.example.org/x/y/a/b");
Ramin Halavatib5e433e62018-02-07 07:41:107988 request.traffic_annotation =
7989 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:237990
bnc691fda62016-08-12 00:43:167991 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277992
[email protected]f9ee6b52008-11-08 06:46:237993 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237994 MockWrite(
7995 "GET /x/y/a/b HTTP/1.1\r\n"
7996 "Host: www.example.org\r\n"
7997 "Connection: keep-alive\r\n"
7998 // Send preemptive authorization for MyRealm1
7999 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238000 };
8001
8002 // The server didn't like the preemptive authorization, and
8003 // challenges us for a different realm (MyRealm2).
8004 MockRead data_reads1[] = {
8005 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8006 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
8007 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068008 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238009 };
8010
8011 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
8012 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238013 MockWrite(
8014 "GET /x/y/a/b HTTP/1.1\r\n"
8015 "Host: www.example.org\r\n"
8016 "Connection: keep-alive\r\n"
8017 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238018 };
8019
8020 // Sever accepts the authorization.
8021 MockRead data_reads2[] = {
8022 MockRead("HTTP/1.0 200 OK\r\n"),
8023 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068024 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238025 };
8026
Ryan Sleevib8d7ea02018-05-07 20:01:018027 StaticSocketDataProvider data1(data_reads1, data_writes1);
8028 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:078029 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8030 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:238031
[email protected]49639fa2011-12-20 23:22:418032 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238033
tfarina42834112016-09-22 13:38:208034 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018035 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238036
8037 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018038 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238039
bnc691fda62016-08-12 00:43:168040 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528041 ASSERT_TRUE(response);
8042 ASSERT_TRUE(response->auth_challenge);
[email protected]79cb5c12011-09-12 13:12:048043 EXPECT_FALSE(response->auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:438044 EXPECT_EQ("http://www.example.org",
8045 response->auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:048046 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
aberentbba302d2015-12-03 10:20:198047 EXPECT_EQ(kBasicAuthScheme, response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:238048
[email protected]49639fa2011-12-20 23:22:418049 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:238050
bnc691fda62016-08-12 00:43:168051 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
8052 callback2.callback());
robpercival214763f2016-07-01 23:27:018053 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238054
8055 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018056 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238057
bnc691fda62016-08-12 00:43:168058 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528059 ASSERT_TRUE(response);
8060 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238061 EXPECT_EQ(100, response->headers->GetContentLength());
8062 }
8063
8064 // ------------------------------------------------------------------------
8065
8066 // Transaction 3: Resend a request in MyRealm's protection space --
8067 // succeed with preemptive authorization.
8068 {
[email protected]1c773ea12009-04-28 19:58:428069 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238070 request.method = "GET";
bncce36dca22015-04-21 22:11:238071 request.url = GURL("http://www.example.org/x/y/z2");
Ramin Halavatib5e433e62018-02-07 07:41:108072 request.traffic_annotation =
8073 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238074
bnc691fda62016-08-12 00:43:168075 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278076
[email protected]f9ee6b52008-11-08 06:46:238077 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238078 MockWrite(
8079 "GET /x/y/z2 HTTP/1.1\r\n"
8080 "Host: www.example.org\r\n"
8081 "Connection: keep-alive\r\n"
8082 // The authorization for MyRealm1 gets sent preemptively
8083 // (since the url is in the same protection space)
8084 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238085 };
8086
8087 // Sever accepts the preemptive authorization
8088 MockRead data_reads1[] = {
8089 MockRead("HTTP/1.0 200 OK\r\n"),
8090 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068091 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238092 };
8093
Ryan Sleevib8d7ea02018-05-07 20:01:018094 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:078095 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:238096
[email protected]49639fa2011-12-20 23:22:418097 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238098
tfarina42834112016-09-22 13:38:208099 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018100 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238101
8102 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018103 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238104
bnc691fda62016-08-12 00:43:168105 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528106 ASSERT_TRUE(response);
[email protected]f9ee6b52008-11-08 06:46:238107
wezca1070932016-05-26 20:30:528108 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238109 EXPECT_EQ(100, response->headers->GetContentLength());
8110 }
8111
8112 // ------------------------------------------------------------------------
8113
8114 // Transaction 4: request another URL in MyRealm (however the
8115 // url is not known to belong to the protection space, so no pre-auth).
8116 {
[email protected]1c773ea12009-04-28 19:58:428117 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238118 request.method = "GET";
bncce36dca22015-04-21 22:11:238119 request.url = GURL("http://www.example.org/x/1");
Ramin Halavatib5e433e62018-02-07 07:41:108120 request.traffic_annotation =
8121 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238122
bnc691fda62016-08-12 00:43:168123 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278124
[email protected]f9ee6b52008-11-08 06:46:238125 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238126 MockWrite(
8127 "GET /x/1 HTTP/1.1\r\n"
8128 "Host: www.example.org\r\n"
8129 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238130 };
8131
8132 MockRead data_reads1[] = {
8133 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8134 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8135 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068136 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238137 };
8138
8139 // Resend with authorization from MyRealm's cache.
8140 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238141 MockWrite(
8142 "GET /x/1 HTTP/1.1\r\n"
8143 "Host: www.example.org\r\n"
8144 "Connection: keep-alive\r\n"
8145 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238146 };
8147
8148 // Sever accepts the authorization.
8149 MockRead data_reads2[] = {
8150 MockRead("HTTP/1.0 200 OK\r\n"),
8151 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068152 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238153 };
8154
Ryan Sleevib8d7ea02018-05-07 20:01:018155 StaticSocketDataProvider data1(data_reads1, data_writes1);
8156 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:078157 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8158 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:238159
[email protected]49639fa2011-12-20 23:22:418160 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238161
tfarina42834112016-09-22 13:38:208162 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018163 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238164
8165 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018166 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238167
bnc691fda62016-08-12 00:43:168168 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:418169 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:168170 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:018171 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:228172 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018173 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168174 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:228175
bnc691fda62016-08-12 00:43:168176 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528177 ASSERT_TRUE(response);
8178 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238179 EXPECT_EQ(100, response->headers->GetContentLength());
8180 }
8181
8182 // ------------------------------------------------------------------------
8183
8184 // Transaction 5: request a URL in MyRealm, but the server rejects the
8185 // cached identity. Should invalidate and re-prompt.
8186 {
[email protected]1c773ea12009-04-28 19:58:428187 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238188 request.method = "GET";
bncce36dca22015-04-21 22:11:238189 request.url = GURL("http://www.example.org/p/q/t");
Ramin Halavatib5e433e62018-02-07 07:41:108190 request.traffic_annotation =
8191 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238192
bnc691fda62016-08-12 00:43:168193 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278194
[email protected]f9ee6b52008-11-08 06:46:238195 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238196 MockWrite(
8197 "GET /p/q/t HTTP/1.1\r\n"
8198 "Host: www.example.org\r\n"
8199 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238200 };
8201
8202 MockRead data_reads1[] = {
8203 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8204 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8205 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068206 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238207 };
8208
8209 // Resend with authorization from cache for MyRealm.
8210 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238211 MockWrite(
8212 "GET /p/q/t HTTP/1.1\r\n"
8213 "Host: www.example.org\r\n"
8214 "Connection: keep-alive\r\n"
8215 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238216 };
8217
8218 // Sever rejects the authorization.
8219 MockRead data_reads2[] = {
8220 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8221 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8222 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068223 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238224 };
8225
8226 // At this point we should prompt for new credentials for MyRealm.
8227 // Restart with username=foo3, password=foo4.
8228 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:238229 MockWrite(
8230 "GET /p/q/t HTTP/1.1\r\n"
8231 "Host: www.example.org\r\n"
8232 "Connection: keep-alive\r\n"
8233 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238234 };
8235
8236 // Sever accepts the authorization.
8237 MockRead data_reads3[] = {
8238 MockRead("HTTP/1.0 200 OK\r\n"),
8239 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068240 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238241 };
8242
Ryan Sleevib8d7ea02018-05-07 20:01:018243 StaticSocketDataProvider data1(data_reads1, data_writes1);
8244 StaticSocketDataProvider data2(data_reads2, data_writes2);
8245 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]bb88e1d32013-05-03 23:11:078246 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8247 session_deps_.socket_factory->AddSocketDataProvider(&data2);
8248 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:238249
[email protected]49639fa2011-12-20 23:22:418250 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238251
tfarina42834112016-09-22 13:38:208252 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018253 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238254
8255 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018256 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238257
bnc691fda62016-08-12 00:43:168258 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:418259 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:168260 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:018261 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:228262 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018263 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168264 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:228265
bnc691fda62016-08-12 00:43:168266 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528267 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:048268 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:238269
[email protected]49639fa2011-12-20 23:22:418270 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:238271
bnc691fda62016-08-12 00:43:168272 rv = trans.RestartWithAuth(AuthCredentials(kFoo3, kBar3),
8273 callback3.callback());
robpercival214763f2016-07-01 23:27:018274 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238275
[email protected]0757e7702009-03-27 04:00:228276 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:018277 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238278
bnc691fda62016-08-12 00:43:168279 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528280 ASSERT_TRUE(response);
8281 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238282 EXPECT_EQ(100, response->headers->GetContentLength());
8283 }
8284}
[email protected]89ceba9a2009-03-21 03:46:068285
[email protected]3c32c5f2010-05-18 15:18:128286// Tests that nonce count increments when multiple auth attempts
8287// are started with the same nonce.
bncd16676a2016-07-20 16:23:018288TEST_F(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:448289 HttpAuthHandlerDigest::Factory* digest_factory =
8290 new HttpAuthHandlerDigest::Factory();
8291 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
8292 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
8293 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:078294 session_deps_.http_auth_handler_factory.reset(digest_factory);
danakj1fd259a02016-04-16 03:17:098295 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:128296
8297 // Transaction 1: authenticate (foo, bar) on MyRealm1
8298 {
[email protected]3c32c5f2010-05-18 15:18:128299 HttpRequestInfo request;
8300 request.method = "GET";
bncce36dca22015-04-21 22:11:238301 request.url = GURL("http://www.example.org/x/y/z");
Ramin Halavatib5e433e62018-02-07 07:41:108302 request.traffic_annotation =
8303 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3c32c5f2010-05-18 15:18:128304
bnc691fda62016-08-12 00:43:168305 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278306
[email protected]3c32c5f2010-05-18 15:18:128307 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238308 MockWrite(
8309 "GET /x/y/z HTTP/1.1\r\n"
8310 "Host: www.example.org\r\n"
8311 "Connection: keep-alive\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:128312 };
8313
8314 MockRead data_reads1[] = {
8315 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8316 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
8317 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068318 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:128319 };
8320
8321 // Resend with authorization (username=foo, password=bar)
8322 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238323 MockWrite(
8324 "GET /x/y/z HTTP/1.1\r\n"
8325 "Host: www.example.org\r\n"
8326 "Connection: keep-alive\r\n"
8327 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
8328 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
8329 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
8330 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:128331 };
8332
8333 // Sever accepts the authorization.
8334 MockRead data_reads2[] = {
zmo9528c9f42015-08-04 22:12:088335 MockRead("HTTP/1.0 200 OK\r\n"),
8336 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:128337 };
8338
Ryan Sleevib8d7ea02018-05-07 20:01:018339 StaticSocketDataProvider data1(data_reads1, data_writes1);
8340 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:078341 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8342 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:128343
[email protected]49639fa2011-12-20 23:22:418344 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:128345
tfarina42834112016-09-22 13:38:208346 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018347 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:128348
8349 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018350 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:128351
bnc691fda62016-08-12 00:43:168352 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528353 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:048354 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:128355
[email protected]49639fa2011-12-20 23:22:418356 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:128357
bnc691fda62016-08-12 00:43:168358 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
8359 callback2.callback());
robpercival214763f2016-07-01 23:27:018360 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:128361
8362 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018363 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:128364
bnc691fda62016-08-12 00:43:168365 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528366 ASSERT_TRUE(response);
8367 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:128368 }
8369
8370 // ------------------------------------------------------------------------
8371
8372 // Transaction 2: Request another resource in digestive's protection space.
8373 // This will preemptively add an Authorization header which should have an
8374 // "nc" value of 2 (as compared to 1 in the first use.
8375 {
[email protected]3c32c5f2010-05-18 15:18:128376 HttpRequestInfo request;
8377 request.method = "GET";
8378 // Note that Transaction 1 was at /x/y/z, so this is in the same
8379 // protection space as digest.
bncce36dca22015-04-21 22:11:238380 request.url = GURL("http://www.example.org/x/y/a/b");
Ramin Halavatib5e433e62018-02-07 07:41:108381 request.traffic_annotation =
8382 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3c32c5f2010-05-18 15:18:128383
bnc691fda62016-08-12 00:43:168384 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278385
[email protected]3c32c5f2010-05-18 15:18:128386 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238387 MockWrite(
8388 "GET /x/y/a/b HTTP/1.1\r\n"
8389 "Host: www.example.org\r\n"
8390 "Connection: keep-alive\r\n"
8391 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
8392 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
8393 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
8394 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:128395 };
8396
8397 // Sever accepts the authorization.
8398 MockRead data_reads1[] = {
8399 MockRead("HTTP/1.0 200 OK\r\n"),
8400 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068401 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:128402 };
8403
Ryan Sleevib8d7ea02018-05-07 20:01:018404 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:078405 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:128406
[email protected]49639fa2011-12-20 23:22:418407 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:128408
tfarina42834112016-09-22 13:38:208409 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018410 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:128411
8412 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018413 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:128414
bnc691fda62016-08-12 00:43:168415 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528416 ASSERT_TRUE(response);
8417 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:128418 }
8419}
8420
[email protected]89ceba9a2009-03-21 03:46:068421// Test the ResetStateForRestart() private method.
bncd16676a2016-07-20 16:23:018422TEST_F(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:068423 // Create a transaction (the dependencies aren't important).
danakj1fd259a02016-04-16 03:17:098424 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168425 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]89ceba9a2009-03-21 03:46:068426
8427 // Setup some state (which we expect ResetStateForRestart() will clear).
bnc691fda62016-08-12 00:43:168428 trans.read_buf_ = new IOBuffer(15);
8429 trans.read_buf_len_ = 15;
8430 trans.request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:068431
8432 // Setup state in response_
bnc691fda62016-08-12 00:43:168433 HttpResponseInfo* response = &trans.response_;
[email protected]0877e3d2009-10-17 22:29:578434 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:088435 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:578436 response->response_time = base::Time::Now();
8437 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:068438
8439 { // Setup state for response_.vary_data
8440 HttpRequestInfo request;
8441 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
8442 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:278443 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:438444 request.extra_headers.SetHeader("Foo", "1");
8445 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:508446 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:068447 }
8448
8449 // Cause the above state to be reset.
bnc691fda62016-08-12 00:43:168450 trans.ResetStateForRestart();
[email protected]89ceba9a2009-03-21 03:46:068451
8452 // Verify that the state that needed to be reset, has been reset.
bnc691fda62016-08-12 00:43:168453 EXPECT_FALSE(trans.read_buf_);
8454 EXPECT_EQ(0, trans.read_buf_len_);
8455 EXPECT_TRUE(trans.request_headers_.IsEmpty());
wezca1070932016-05-26 20:30:528456 EXPECT_FALSE(response->auth_challenge);
8457 EXPECT_FALSE(response->headers);
[email protected]34f40942010-10-04 00:34:048458 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:088459 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:578460 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:068461}
8462
[email protected]bacff652009-03-31 17:50:338463// Test HTTPS connections to a site with a bad certificate
bncd16676a2016-07-20 16:23:018464TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:338465 HttpRequestInfo request;
8466 request.method = "GET";
bncce36dca22015-04-21 22:11:238467 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:108468 request.traffic_annotation =
8469 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]bacff652009-03-31 17:50:338470
danakj1fd259a02016-04-16 03:17:098471 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168472 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278473
[email protected]bacff652009-03-31 17:50:338474 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238475 MockWrite(
8476 "GET / HTTP/1.1\r\n"
8477 "Host: www.example.org\r\n"
8478 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:338479 };
8480
8481 MockRead data_reads[] = {
8482 MockRead("HTTP/1.0 200 OK\r\n"),
8483 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8484 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068485 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:338486 };
8487
[email protected]5ecc992a42009-11-11 01:41:598488 StaticSocketDataProvider ssl_bad_certificate;
Ryan Sleevib8d7ea02018-05-07 20:01:018489 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:068490 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8491 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:338492
[email protected]bb88e1d32013-05-03 23:11:078493 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
8494 session_deps_.socket_factory->AddSocketDataProvider(&data);
8495 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
8496 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:338497
[email protected]49639fa2011-12-20 23:22:418498 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:338499
tfarina42834112016-09-22 13:38:208500 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018501 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:338502
8503 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018504 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:338505
bnc691fda62016-08-12 00:43:168506 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:018507 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:338508
8509 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018510 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:338511
bnc691fda62016-08-12 00:43:168512 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:338513
wezca1070932016-05-26 20:30:528514 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:338515 EXPECT_EQ(100, response->headers->GetContentLength());
8516}
8517
8518// Test HTTPS connections to a site with a bad certificate, going through a
8519// proxy
bncd16676a2016-07-20 16:23:018520TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
Ramin Halavatica8d5252018-03-12 05:33:498521 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
8522 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]bacff652009-03-31 17:50:338523
8524 HttpRequestInfo request;
8525 request.method = "GET";
bncce36dca22015-04-21 22:11:238526 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:108527 request.traffic_annotation =
8528 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]bacff652009-03-31 17:50:338529
8530 MockWrite proxy_writes[] = {
rsleevidb16bb02015-11-12 23:47:178531 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8532 "Host: www.example.org:443\r\n"
8533 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:338534 };
8535
8536 MockRead proxy_reads[] = {
8537 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068538 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:338539 };
8540
8541 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178542 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8543 "Host: www.example.org:443\r\n"
8544 "Proxy-Connection: keep-alive\r\n\r\n"),
8545 MockWrite("GET / HTTP/1.1\r\n"
8546 "Host: www.example.org\r\n"
8547 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:338548 };
8549
8550 MockRead data_reads[] = {
8551 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
8552 MockRead("HTTP/1.0 200 OK\r\n"),
8553 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8554 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068555 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:338556 };
8557
Ryan Sleevib8d7ea02018-05-07 20:01:018558 StaticSocketDataProvider ssl_bad_certificate(proxy_reads, proxy_writes);
8559 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:068560 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8561 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:338562
[email protected]bb88e1d32013-05-03 23:11:078563 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
8564 session_deps_.socket_factory->AddSocketDataProvider(&data);
8565 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
8566 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:338567
[email protected]49639fa2011-12-20 23:22:418568 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:338569
8570 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:078571 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:338572
danakj1fd259a02016-04-16 03:17:098573 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168574 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bacff652009-03-31 17:50:338575
tfarina42834112016-09-22 13:38:208576 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018577 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:338578
8579 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018580 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:338581
bnc691fda62016-08-12 00:43:168582 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:018583 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:338584
8585 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018586 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:338587
bnc691fda62016-08-12 00:43:168588 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:338589
wezca1070932016-05-26 20:30:528590 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:338591 EXPECT_EQ(100, response->headers->GetContentLength());
8592 }
8593}
8594
[email protected]2df19bb2010-08-25 20:13:468595
8596// Test HTTPS connections to a site, going through an HTTPS proxy
bncd16676a2016-07-20 16:23:018597TEST_F(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:598598 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:498599 ProxyResolutionService::CreateFixedFromPacResult(
8600 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:518601 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078602 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:468603
8604 HttpRequestInfo request;
8605 request.method = "GET";
bncce36dca22015-04-21 22:11:238606 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:108607 request.traffic_annotation =
8608 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:468609
8610 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178611 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8612 "Host: www.example.org:443\r\n"
8613 "Proxy-Connection: keep-alive\r\n\r\n"),
8614 MockWrite("GET / HTTP/1.1\r\n"
8615 "Host: www.example.org\r\n"
8616 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:468617 };
8618
8619 MockRead data_reads[] = {
8620 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
8621 MockRead("HTTP/1.1 200 OK\r\n"),
8622 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8623 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068624 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:468625 };
8626
Ryan Sleevib8d7ea02018-05-07 20:01:018627 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:068628 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
8629 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:468630
[email protected]bb88e1d32013-05-03 23:11:078631 session_deps_.socket_factory->AddSocketDataProvider(&data);
8632 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
8633 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:468634
[email protected]49639fa2011-12-20 23:22:418635 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:468636
danakj1fd259a02016-04-16 03:17:098637 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168638 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:468639
tfarina42834112016-09-22 13:38:208640 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018641 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:468642
8643 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018644 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168645 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:468646
wezca1070932016-05-26 20:30:528647 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:468648
tbansal2ecbbc72016-10-06 17:15:478649 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:468650 EXPECT_TRUE(response->headers->IsKeepAlive());
8651 EXPECT_EQ(200, response->headers->response_code());
8652 EXPECT_EQ(100, response->headers->GetContentLength());
8653 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:208654
8655 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:168656 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:208657 TestLoadTimingNotReusedWithPac(load_timing_info,
8658 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:468659}
8660
[email protected]511f6f52010-12-17 03:58:298661// Test an HTTPS Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:018662TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:598663 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:498664 ProxyResolutionService::CreateFixedFromPacResult(
8665 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:518666 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078667 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:298668
8669 HttpRequestInfo request;
8670 request.method = "GET";
bncce36dca22015-04-21 22:11:238671 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:108672 request.traffic_annotation =
8673 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298674
8675 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178676 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8677 "Host: www.example.org:443\r\n"
8678 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:298679 };
8680
8681 MockRead data_reads[] = {
8682 MockRead("HTTP/1.1 302 Redirect\r\n"),
8683 MockRead("Location: http://login.example.com/\r\n"),
8684 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068685 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:298686 };
8687
Ryan Sleevib8d7ea02018-05-07 20:01:018688 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:068689 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:298690
[email protected]bb88e1d32013-05-03 23:11:078691 session_deps_.socket_factory->AddSocketDataProvider(&data);
8692 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298693
[email protected]49639fa2011-12-20 23:22:418694 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298695
danakj1fd259a02016-04-16 03:17:098696 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168697 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298698
tfarina42834112016-09-22 13:38:208699 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018700 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298701
8702 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018703 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168704 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:298705
wezca1070932016-05-26 20:30:528706 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:298707
8708 EXPECT_EQ(302, response->headers->response_code());
8709 std::string url;
8710 EXPECT_TRUE(response->headers->IsRedirect(&url));
8711 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:208712
8713 // In the case of redirects from proxies, HttpNetworkTransaction returns
8714 // timing for the proxy connection instead of the connection to the host,
8715 // and no send / receive times.
8716 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
8717 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:168718 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:208719
8720 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:198721 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:208722
8723 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
8724 EXPECT_LE(load_timing_info.proxy_resolve_start,
8725 load_timing_info.proxy_resolve_end);
8726 EXPECT_LE(load_timing_info.proxy_resolve_end,
8727 load_timing_info.connect_timing.connect_start);
8728 ExpectConnectTimingHasTimes(
8729 load_timing_info.connect_timing,
8730 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
8731
8732 EXPECT_TRUE(load_timing_info.send_start.is_null());
8733 EXPECT_TRUE(load_timing_info.send_end.is_null());
8734 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:298735}
8736
8737// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:018738TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
Ramin Halavatica8d5252018-03-12 05:33:498739 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
8740 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298741
8742 HttpRequestInfo request;
8743 request.method = "GET";
bncce36dca22015-04-21 22:11:238744 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:108745 request.traffic_annotation =
8746 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298747
Ryan Hamilton0239aac2018-05-19 00:03:138748 spdy::SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238749 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:138750 spdy::SpdySerializedFrame goaway(
8751 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:298752 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:418753 CreateMockWrite(conn, 0, SYNCHRONOUS),
8754 CreateMockWrite(goaway, 2, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:298755 };
8756
8757 static const char* const kExtraHeaders[] = {
8758 "location",
8759 "http://login.example.com/",
8760 };
Ryan Hamilton0239aac2018-05-19 00:03:138761 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:238762 "302", kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
[email protected]511f6f52010-12-17 03:58:298763 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:418764 CreateMockRead(resp, 1), MockRead(ASYNC, 0, 3), // EOF
[email protected]511f6f52010-12-17 03:58:298765 };
8766
Ryan Sleevib8d7ea02018-05-07 20:01:018767 SequencedSocketData data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:068768 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:368769 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:298770
[email protected]bb88e1d32013-05-03 23:11:078771 session_deps_.socket_factory->AddSocketDataProvider(&data);
8772 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298773
[email protected]49639fa2011-12-20 23:22:418774 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298775
danakj1fd259a02016-04-16 03:17:098776 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168777 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298778
tfarina42834112016-09-22 13:38:208779 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018780 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298781
8782 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018783 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168784 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:298785
wezca1070932016-05-26 20:30:528786 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:298787
8788 EXPECT_EQ(302, response->headers->response_code());
8789 std::string url;
8790 EXPECT_TRUE(response->headers->IsRedirect(&url));
8791 EXPECT_EQ("http://login.example.com/", url);
8792}
8793
[email protected]4eddbc732012-08-09 05:40:178794// Test that an HTTPS proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:018795TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaHttpsProxy) {
Ramin Halavatica8d5252018-03-12 05:33:498796 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
8797 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298798
8799 HttpRequestInfo request;
8800 request.method = "GET";
bncce36dca22015-04-21 22:11:238801 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:108802 request.traffic_annotation =
8803 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298804
8805 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178806 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8807 "Host: www.example.org:443\r\n"
8808 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:298809 };
8810
8811 MockRead data_reads[] = {
8812 MockRead("HTTP/1.1 404 Not Found\r\n"),
8813 MockRead("Content-Length: 23\r\n\r\n"),
8814 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:068815 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:298816 };
8817
Ryan Sleevib8d7ea02018-05-07 20:01:018818 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:068819 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:298820
[email protected]bb88e1d32013-05-03 23:11:078821 session_deps_.socket_factory->AddSocketDataProvider(&data);
8822 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298823
[email protected]49639fa2011-12-20 23:22:418824 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298825
danakj1fd259a02016-04-16 03:17:098826 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168827 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298828
tfarina42834112016-09-22 13:38:208829 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018830 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298831
8832 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018833 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:298834
ttuttle960fcbf2016-04-19 13:26:328835 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:298836}
8837
[email protected]4eddbc732012-08-09 05:40:178838// Test that a SPDY proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:018839TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaSpdyProxy) {
Ramin Halavatica8d5252018-03-12 05:33:498840 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
8841 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298842
8843 HttpRequestInfo request;
8844 request.method = "GET";
bncce36dca22015-04-21 22:11:238845 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:108846 request.traffic_annotation =
8847 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298848
Ryan Hamilton0239aac2018-05-19 00:03:138849 spdy::SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238850 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:138851 spdy::SpdySerializedFrame rst(
8852 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:298853 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:418854 CreateMockWrite(conn, 0), CreateMockWrite(rst, 3),
[email protected]511f6f52010-12-17 03:58:298855 };
8856
8857 static const char* const kExtraHeaders[] = {
8858 "location",
8859 "http://login.example.com/",
8860 };
Ryan Hamilton0239aac2018-05-19 00:03:138861 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:238862 "404", kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
Ryan Hamilton0239aac2018-05-19 00:03:138863 spdy::SpdySerializedFrame body(
Bence Békyd74f4382018-02-20 18:26:198864 spdy_util_.ConstructSpdyDataFrame(1, "The host does not exist", true));
[email protected]511f6f52010-12-17 03:58:298865 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:418866 CreateMockRead(resp, 1), CreateMockRead(body, 2),
rch8e6c6c42015-05-01 14:05:138867 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:298868 };
8869
Ryan Sleevib8d7ea02018-05-07 20:01:018870 SequencedSocketData data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:068871 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:368872 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:298873
[email protected]bb88e1d32013-05-03 23:11:078874 session_deps_.socket_factory->AddSocketDataProvider(&data);
8875 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298876
[email protected]49639fa2011-12-20 23:22:418877 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298878
danakj1fd259a02016-04-16 03:17:098879 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168880 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298881
tfarina42834112016-09-22 13:38:208882 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018883 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298884
8885 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018886 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:298887
ttuttle960fcbf2016-04-19 13:26:328888 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:298889}
8890
[email protected]0c5fb722012-02-28 11:50:358891// Test the request-challenge-retry sequence for basic auth, through
8892// a SPDY proxy over a single SPDY session.
bncd16676a2016-07-20 16:23:018893TEST_F(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:358894 HttpRequestInfo request;
8895 request.method = "GET";
bncce36dca22015-04-21 22:11:238896 request.url = GURL("https://www.example.org/");
[email protected]0c5fb722012-02-28 11:50:358897 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:298898 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:108899 request.traffic_annotation =
8900 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0c5fb722012-02-28 11:50:358901
8902 // Configure against https proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:598903 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:498904 ProxyResolutionService::CreateFixedFromPacResult(
8905 "HTTPS myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:518906 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078907 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:098908 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:358909
8910 // Since we have proxy, should try to establish tunnel.
Ryan Hamilton0239aac2018-05-19 00:03:138911 spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238912 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:138913 spdy::SpdySerializedFrame rst(
8914 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
rdsmithebb50aa2015-11-12 03:44:388915 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]0c5fb722012-02-28 11:50:358916
bnc691fda62016-08-12 00:43:168917 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0c5fb722012-02-28 11:50:358918 // be issuing -- the final header line contains the credentials.
8919 const char* const kAuthCredentials[] = {
8920 "proxy-authorization", "Basic Zm9vOmJhcg==",
8921 };
Ryan Hamilton0239aac2018-05-19 00:03:138922 spdy::SpdySerializedFrame connect2(spdy_util_.ConstructSpdyConnect(
lgarrona91df87f2014-12-05 00:51:348923 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST,
bncce36dca22015-04-21 22:11:238924 HostPortPair("www.example.org", 443)));
8925 // fetch https://www.example.org/ via HTTP
8926 const char get[] =
8927 "GET / HTTP/1.1\r\n"
8928 "Host: www.example.org\r\n"
8929 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:138930 spdy::SpdySerializedFrame wrapped_get(
Bence Békyd74f4382018-02-20 18:26:198931 spdy_util_.ConstructSpdyDataFrame(3, get, false));
[email protected]0c5fb722012-02-28 11:50:358932
8933 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418934 CreateMockWrite(req, 0, ASYNC), CreateMockWrite(rst, 2, ASYNC),
8935 CreateMockWrite(connect2, 3), CreateMockWrite(wrapped_get, 5),
[email protected]0c5fb722012-02-28 11:50:358936 };
8937
8938 // The proxy responds to the connect with a 407, using a persistent
8939 // connection.
thestig9d3bb0c2015-01-24 00:49:518940 const char kAuthStatus[] = "407";
[email protected]0c5fb722012-02-28 11:50:358941 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:358942 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
8943 };
Ryan Hamilton0239aac2018-05-19 00:03:138944 spdy::SpdySerializedFrame conn_auth_resp(spdy_util_.ConstructSpdyReplyError(
bncdf80d44fd2016-07-15 20:27:418945 kAuthStatus, kAuthChallenge, arraysize(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:358946
Ryan Hamilton0239aac2018-05-19 00:03:138947 spdy::SpdySerializedFrame conn_resp(
8948 spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:358949 const char resp[] = "HTTP/1.1 200 OK\r\n"
8950 "Content-Length: 5\r\n\r\n";
8951
Ryan Hamilton0239aac2018-05-19 00:03:138952 spdy::SpdySerializedFrame wrapped_get_resp(
Bence Békyd74f4382018-02-20 18:26:198953 spdy_util_.ConstructSpdyDataFrame(3, resp, false));
Ryan Hamilton0239aac2018-05-19 00:03:138954 spdy::SpdySerializedFrame wrapped_body(
Bence Békyd74f4382018-02-20 18:26:198955 spdy_util_.ConstructSpdyDataFrame(3, "hello", false));
[email protected]0c5fb722012-02-28 11:50:358956 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418957 CreateMockRead(conn_auth_resp, 1, ASYNC),
8958 CreateMockRead(conn_resp, 4, ASYNC),
8959 CreateMockRead(wrapped_get_resp, 6, ASYNC),
8960 CreateMockRead(wrapped_body, 7, ASYNC),
rch8e6c6c42015-05-01 14:05:138961 MockRead(ASYNC, OK, 8), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:358962 };
8963
Ryan Sleevib8d7ea02018-05-07 20:01:018964 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:078965 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:358966 // Negotiate SPDY to the proxy
8967 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368968 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:078969 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:358970 // Vanilla SSL to the server
8971 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078972 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:358973
8974 TestCompletionCallback callback1;
8975
bnc87dcefc2017-05-25 12:47:588976 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:198977 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0c5fb722012-02-28 11:50:358978
8979 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018980 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:358981
8982 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018983 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:468984 TestNetLogEntry::List entries;
[email protected]0c5fb722012-02-28 11:50:358985 log.GetEntries(&entries);
8986 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:008987 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
8988 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:358989 ExpectLogContainsSomewhere(
8990 entries, pos,
mikecirone8b85c432016-09-08 19:11:008991 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
8992 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:358993
8994 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528995 ASSERT_TRUE(response);
8996 ASSERT_TRUE(response->headers);
[email protected]0c5fb722012-02-28 11:50:358997 EXPECT_EQ(407, response->headers->response_code());
8998 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
wezca1070932016-05-26 20:30:528999 EXPECT_TRUE(response->auth_challenge);
asanka098c0092016-06-16 20:18:439000 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]0c5fb722012-02-28 11:50:359001
9002 TestCompletionCallback callback2;
9003
9004 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
9005 callback2.callback());
robpercival214763f2016-07-01 23:27:019006 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:359007
9008 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:019009 EXPECT_THAT(rv, IsOk());
[email protected]0c5fb722012-02-28 11:50:359010
9011 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529012 ASSERT_TRUE(response);
[email protected]0c5fb722012-02-28 11:50:359013
9014 EXPECT_TRUE(response->headers->IsKeepAlive());
9015 EXPECT_EQ(200, response->headers->response_code());
9016 EXPECT_EQ(5, response->headers->GetContentLength());
9017 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
9018
9019 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:529020 EXPECT_FALSE(response->auth_challenge);
[email protected]0c5fb722012-02-28 11:50:359021
[email protected]029c83b62013-01-24 05:28:209022 LoadTimingInfo load_timing_info;
9023 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
9024 TestLoadTimingNotReusedWithPac(load_timing_info,
9025 CONNECT_TIMING_HAS_SSL_TIMES);
9026
[email protected]0c5fb722012-02-28 11:50:359027 trans.reset();
9028 session->CloseAllConnections();
9029}
9030
[email protected]7c6f7ba2012-04-03 04:09:299031// Test that an explicitly trusted SPDY proxy can push a resource from an
9032// origin that is different from that of its associated resource.
bncd16676a2016-07-20 16:23:019033TEST_F(HttpNetworkTransactionTest, CrossOriginSPDYProxyPush) {
tbansal28e68f82016-02-04 02:56:159034 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:199035 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:159036 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
9037 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]7c6f7ba2012-04-03 04:09:299038 HttpRequestInfo request;
9039 HttpRequestInfo push_request;
Ramin Halavatib5e433e62018-02-07 07:41:109040 request.traffic_annotation =
9041 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7c6f7ba2012-04-03 04:09:299042
[email protected]7c6f7ba2012-04-03 04:09:299043 request.method = "GET";
bncce36dca22015-04-21 22:11:239044 request.url = GURL("http://www.example.org/");
[email protected]7c6f7ba2012-04-03 04:09:299045 push_request.method = "GET";
9046 push_request.url = GURL("http://www.another-origin.com/foo.dat");
Ramin Halavatib5e433e62018-02-07 07:41:109047 push_request.traffic_annotation =
9048 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7c6f7ba2012-04-03 04:09:299049
tbansal28e68f82016-02-04 02:56:159050 // Configure against https proxy server "myproxy:443".
Lily Houghton8c2f97d2018-01-22 05:06:599051 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499052 ProxyResolutionService::CreateFixedFromPacResult(
9053 "HTTPS myproxy:443", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519054 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:079055 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:509056
inlinechan894515af2016-12-09 02:40:109057 session_deps_.proxy_delegate = std::move(proxy_delegate);
[email protected]61b4efc2012-04-27 18:12:509058
danakj1fd259a02016-04-16 03:17:099059 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:299060
Ryan Hamilton0239aac2018-05-19 00:03:139061 spdy::SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:459062 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:139063 spdy::SpdySerializedFrame stream2_priority(
tombergan5d22c182017-01-11 02:05:359064 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
[email protected]7c6f7ba2012-04-03 04:09:299065
9066 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:419067 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:359068 CreateMockWrite(stream2_priority, 3, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:299069 };
9070
Ryan Hamilton0239aac2018-05-19 00:03:139071 spdy::SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
Bence Béky7bf94362018-01-10 13:19:369072 NULL, 0, 2, 1, "http://www.another-origin.com/foo.dat"));
9073
Ryan Hamilton0239aac2018-05-19 00:03:139074 spdy::SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:159075 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:299076
Ryan Hamilton0239aac2018-05-19 00:03:139077 spdy::SpdySerializedFrame stream1_body(
9078 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:299079
Ryan Hamilton0239aac2018-05-19 00:03:139080 spdy::SpdySerializedFrame stream2_body(
Bence Békyd74f4382018-02-20 18:26:199081 spdy_util_.ConstructSpdyDataFrame(2, "pushed", true));
[email protected]7c6f7ba2012-04-03 04:09:299082
9083 MockRead spdy_reads[] = {
Bence Béky7bf94362018-01-10 13:19:369084 CreateMockRead(stream2_syn, 1, ASYNC),
9085 CreateMockRead(stream1_reply, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:359086 CreateMockRead(stream1_body, 4, ASYNC),
9087 CreateMockRead(stream2_body, 5, ASYNC),
9088 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
[email protected]7c6f7ba2012-04-03 04:09:299089 };
9090
Ryan Sleevib8d7ea02018-05-07 20:01:019091 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:079092 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:299093 // Negotiate SPDY to the proxy
9094 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:369095 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:079096 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:299097
bnc87dcefc2017-05-25 12:47:589098 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:199099 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7c6f7ba2012-04-03 04:09:299100 TestCompletionCallback callback;
9101 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:019102 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:299103
9104 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019105 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:299106 const HttpResponseInfo* response = trans->GetResponseInfo();
9107
bnc87dcefc2017-05-25 12:47:589108 auto push_trans =
Jeremy Roman0579ed62017-08-29 15:56:199109 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]90499482013-06-01 00:39:509110 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:019111 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:299112
9113 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019114 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:299115 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
9116
wezca1070932016-05-26 20:30:529117 ASSERT_TRUE(response);
[email protected]7c6f7ba2012-04-03 04:09:299118 EXPECT_TRUE(response->headers->IsKeepAlive());
9119
9120 EXPECT_EQ(200, response->headers->response_code());
9121 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
9122
9123 std::string response_data;
9124 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:019125 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:299126 EXPECT_EQ("hello!", response_data);
9127
[email protected]029c83b62013-01-24 05:28:209128 LoadTimingInfo load_timing_info;
9129 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
9130 TestLoadTimingNotReusedWithPac(load_timing_info,
9131 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9132
[email protected]7c6f7ba2012-04-03 04:09:299133 // Verify the pushed stream.
wezca1070932016-05-26 20:30:529134 EXPECT_TRUE(push_response->headers);
[email protected]7c6f7ba2012-04-03 04:09:299135 EXPECT_EQ(200, push_response->headers->response_code());
9136
9137 rv = ReadTransaction(push_trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:019138 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:299139 EXPECT_EQ("pushed", response_data);
9140
[email protected]029c83b62013-01-24 05:28:209141 LoadTimingInfo push_load_timing_info;
9142 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
9143 TestLoadTimingReusedWithPac(push_load_timing_info);
9144 // The transactions should share a socket ID, despite being for different
9145 // origins.
9146 EXPECT_EQ(load_timing_info.socket_log_id,
9147 push_load_timing_info.socket_log_id);
9148
[email protected]7c6f7ba2012-04-03 04:09:299149 trans.reset();
9150 push_trans.reset();
9151 session->CloseAllConnections();
9152}
9153
[email protected]8c843192012-04-05 07:15:009154// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
bncd16676a2016-07-20 16:23:019155TEST_F(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:159156 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:199157 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:159158 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
9159 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]8c843192012-04-05 07:15:009160 HttpRequestInfo request;
9161
9162 request.method = "GET";
bncce36dca22015-04-21 22:11:239163 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109164 request.traffic_annotation =
9165 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c843192012-04-05 07:15:009166
Ramin Halavatica8d5252018-03-12 05:33:499167 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9168 "https://myproxy:443", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519169 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:079170 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:509171
9172 // Enable cross-origin push.
inlinechan894515af2016-12-09 02:40:109173 session_deps_.proxy_delegate = std::move(proxy_delegate);
[email protected]61b4efc2012-04-27 18:12:509174
danakj1fd259a02016-04-16 03:17:099175 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:009176
Ryan Hamilton0239aac2018-05-19 00:03:139177 spdy::SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:459178 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
[email protected]8c843192012-04-05 07:15:009179
Ryan Hamilton0239aac2018-05-19 00:03:139180 spdy::SpdySerializedFrame push_rst(
9181 spdy_util_.ConstructSpdyRstStream(2, spdy::ERROR_CODE_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:009182
9183 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:419184 CreateMockWrite(stream1_syn, 0, ASYNC), CreateMockWrite(push_rst, 3),
[email protected]8c843192012-04-05 07:15:009185 };
9186
Ryan Hamilton0239aac2018-05-19 00:03:139187 spdy::SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:159188 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:009189
Ryan Hamilton0239aac2018-05-19 00:03:139190 spdy::SpdySerializedFrame stream1_body(
9191 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]8c843192012-04-05 07:15:009192
Ryan Hamilton0239aac2018-05-19 00:03:139193 spdy::SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
bncb03b1092016-04-06 11:19:559194 NULL, 0, 2, 1, "https://www.another-origin.com/foo.dat"));
[email protected]8c843192012-04-05 07:15:009195
9196 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:419197 CreateMockRead(stream1_reply, 1, ASYNC),
9198 CreateMockRead(stream2_syn, 2, ASYNC),
9199 CreateMockRead(stream1_body, 4, ASYNC),
mmenkee24011922015-12-17 22:12:599200 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
[email protected]8c843192012-04-05 07:15:009201 };
9202
Ryan Sleevib8d7ea02018-05-07 20:01:019203 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:079204 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:009205 // Negotiate SPDY to the proxy
9206 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:369207 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:079208 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:009209
bnc87dcefc2017-05-25 12:47:589210 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:199211 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]8c843192012-04-05 07:15:009212 TestCompletionCallback callback;
9213 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:019214 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c843192012-04-05 07:15:009215
9216 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019217 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:009218 const HttpResponseInfo* response = trans->GetResponseInfo();
9219
wezca1070932016-05-26 20:30:529220 ASSERT_TRUE(response);
[email protected]8c843192012-04-05 07:15:009221 EXPECT_TRUE(response->headers->IsKeepAlive());
9222
9223 EXPECT_EQ(200, response->headers->response_code());
9224 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
9225
9226 std::string response_data;
9227 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:019228 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:009229 EXPECT_EQ("hello!", response_data);
9230
9231 trans.reset();
9232 session->CloseAllConnections();
9233}
9234
tbansal8ef1d3e2016-02-03 04:05:429235// Test that an explicitly trusted SPDY proxy can push same-origin HTTPS
9236// resources.
bncd16676a2016-07-20 16:23:019237TEST_F(HttpNetworkTransactionTest, SameOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:159238 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:199239 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:159240 proxy_delegate->set_trusted_spdy_proxy(
9241 net::ProxyServer::FromURI("myproxy:70", net::ProxyServer::SCHEME_HTTP));
9242
tbansal8ef1d3e2016-02-03 04:05:429243 HttpRequestInfo request;
9244
9245 request.method = "GET";
9246 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109247 request.traffic_annotation =
9248 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal8ef1d3e2016-02-03 04:05:429249
9250 // Configure against https proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:499251 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9252 "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal8ef1d3e2016-02-03 04:05:429253 BoundTestNetLog log;
9254 session_deps_.net_log = log.bound().net_log();
9255
9256 // Enable cross-origin push.
inlinechan894515af2016-12-09 02:40:109257 session_deps_.proxy_delegate = std::move(proxy_delegate);
tbansal8ef1d3e2016-02-03 04:05:429258
danakj1fd259a02016-04-16 03:17:099259 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
tbansal8ef1d3e2016-02-03 04:05:429260
Ryan Hamilton0239aac2018-05-19 00:03:139261 spdy::SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:459262 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:139263 spdy::SpdySerializedFrame stream2_priority(
tombergan5d22c182017-01-11 02:05:359264 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
tbansal8ef1d3e2016-02-03 04:05:429265
9266 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:419267 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:359268 CreateMockWrite(stream2_priority, 3, ASYNC),
tbansal8ef1d3e2016-02-03 04:05:429269 };
9270
Ryan Hamilton0239aac2018-05-19 00:03:139271 spdy::SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:159272 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:429273
Ryan Hamilton0239aac2018-05-19 00:03:139274 spdy::SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
Bence Béky096cf052017-08-08 23:55:339275 nullptr, 0, 2, 1, "http://www.example.org/foo.dat"));
bnc38dcd392016-02-09 23:19:499276
Ryan Hamilton0239aac2018-05-19 00:03:139277 spdy::SpdySerializedFrame stream1_body(
9278 spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:429279
Ryan Hamilton0239aac2018-05-19 00:03:139280 spdy::SpdySerializedFrame stream2_reply(
bnc42331402016-07-25 13:36:159281 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:429282
Ryan Hamilton0239aac2018-05-19 00:03:139283 spdy::SpdySerializedFrame stream2_body(
9284 spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:429285
9286 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:419287 CreateMockRead(stream1_reply, 1, ASYNC),
9288 CreateMockRead(stream2_syn, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:359289 CreateMockRead(stream1_body, 4, ASYNC),
9290 CreateMockRead(stream2_body, 5, ASYNC),
9291 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
tbansal8ef1d3e2016-02-03 04:05:429292 };
9293
Ryan Sleevib8d7ea02018-05-07 20:01:019294 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
tbansal8ef1d3e2016-02-03 04:05:429295 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
9296 // Negotiate SPDY to the proxy
9297 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:369298 proxy.next_proto = kProtoHTTP2;
tbansal8ef1d3e2016-02-03 04:05:429299 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
9300
bnc87dcefc2017-05-25 12:47:589301 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:199302 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tbansal8ef1d3e2016-02-03 04:05:429303 TestCompletionCallback callback;
9304 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:019305 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
tbansal8ef1d3e2016-02-03 04:05:429306
9307 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019308 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:429309 const HttpResponseInfo* response = trans->GetResponseInfo();
9310
wezca1070932016-05-26 20:30:529311 ASSERT_TRUE(response);
tbansal8ef1d3e2016-02-03 04:05:429312 EXPECT_TRUE(response->headers->IsKeepAlive());
9313
9314 EXPECT_EQ(200, response->headers->response_code());
9315 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
9316
9317 std::string response_data;
9318 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:019319 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:429320 EXPECT_EQ("hello!", response_data);
9321
9322 trans.reset();
9323 session->CloseAllConnections();
9324}
9325
[email protected]2df19bb2010-08-25 20:13:469326// Test HTTPS connections to a site with a bad certificate, going through an
9327// HTTPS proxy
bncd16676a2016-07-20 16:23:019328TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
Ramin Halavatica8d5252018-03-12 05:33:499329 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9330 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:469331
9332 HttpRequestInfo request;
9333 request.method = "GET";
bncce36dca22015-04-21 22:11:239334 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109335 request.traffic_annotation =
9336 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:469337
9338 // Attempt to fetch the URL from a server with a bad cert
9339 MockWrite bad_cert_writes[] = {
rsleevidb16bb02015-11-12 23:47:179340 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9341 "Host: www.example.org:443\r\n"
9342 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:469343 };
9344
9345 MockRead bad_cert_reads[] = {
9346 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069347 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:469348 };
9349
9350 // Attempt to fetch the URL with a good cert
9351 MockWrite good_data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179352 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9353 "Host: www.example.org:443\r\n"
9354 "Proxy-Connection: keep-alive\r\n\r\n"),
9355 MockWrite("GET / HTTP/1.1\r\n"
9356 "Host: www.example.org\r\n"
9357 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:469358 };
9359
9360 MockRead good_cert_reads[] = {
9361 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
9362 MockRead("HTTP/1.0 200 OK\r\n"),
9363 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9364 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069365 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:469366 };
9367
Ryan Sleevib8d7ea02018-05-07 20:01:019368 StaticSocketDataProvider ssl_bad_certificate(bad_cert_reads, bad_cert_writes);
9369 StaticSocketDataProvider data(good_cert_reads, good_data_writes);
[email protected]8ddf8322012-02-23 18:08:069370 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
9371 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:469372
9373 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:079374 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9375 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
9376 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:469377
9378 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:079379 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9380 session_deps_.socket_factory->AddSocketDataProvider(&data);
9381 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:469382
[email protected]49639fa2011-12-20 23:22:419383 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:469384
danakj1fd259a02016-04-16 03:17:099385 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169386 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:469387
tfarina42834112016-09-22 13:38:209388 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019389 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:469390
9391 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019392 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]2df19bb2010-08-25 20:13:469393
bnc691fda62016-08-12 00:43:169394 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:019395 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:469396
9397 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019398 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:469399
bnc691fda62016-08-12 00:43:169400 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:469401
wezca1070932016-05-26 20:30:529402 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:469403 EXPECT_EQ(100, response->headers->GetContentLength());
9404}
9405
bncd16676a2016-07-20 16:23:019406TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:429407 HttpRequestInfo request;
9408 request.method = "GET";
bncce36dca22015-04-21 22:11:239409 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:439410 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
9411 "Chromium Ultra Awesome X Edition");
Ramin Halavatib5e433e62018-02-07 07:41:109412 request.traffic_annotation =
9413 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429414
danakj1fd259a02016-04-16 03:17:099415 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169416 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279417
[email protected]1c773ea12009-04-28 19:58:429418 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239419 MockWrite(
9420 "GET / HTTP/1.1\r\n"
9421 "Host: www.example.org\r\n"
9422 "Connection: keep-alive\r\n"
9423 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429424 };
9425
9426 // Lastly, the server responds with the actual content.
9427 MockRead data_reads[] = {
9428 MockRead("HTTP/1.0 200 OK\r\n"),
9429 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9430 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069431 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429432 };
9433
Ryan Sleevib8d7ea02018-05-07 20:01:019434 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:079435 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429436
[email protected]49639fa2011-12-20 23:22:419437 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429438
tfarina42834112016-09-22 13:38:209439 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019440 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429441
9442 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019443 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429444}
9445
bncd16676a2016-07-20 16:23:019446TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:299447 HttpRequestInfo request;
9448 request.method = "GET";
bncce36dca22015-04-21 22:11:239449 request.url = GURL("https://www.example.org/");
[email protected]da81f132010-08-18 23:39:299450 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
9451 "Chromium Ultra Awesome X Edition");
Ramin Halavatib5e433e62018-02-07 07:41:109452 request.traffic_annotation =
9453 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]da81f132010-08-18 23:39:299454
Ramin Halavatica8d5252018-03-12 05:33:499455 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9456 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:099457 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169458 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279459
[email protected]da81f132010-08-18 23:39:299460 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179461 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9462 "Host: www.example.org:443\r\n"
9463 "Proxy-Connection: keep-alive\r\n"
9464 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]da81f132010-08-18 23:39:299465 };
9466 MockRead data_reads[] = {
9467 // Return an error, so the transaction stops here (this test isn't
9468 // interested in the rest).
9469 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
9470 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9471 MockRead("Proxy-Connection: close\r\n\r\n"),
9472 };
9473
Ryan Sleevib8d7ea02018-05-07 20:01:019474 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:079475 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:299476
[email protected]49639fa2011-12-20 23:22:419477 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:299478
tfarina42834112016-09-22 13:38:209479 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019480 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]da81f132010-08-18 23:39:299481
9482 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019483 EXPECT_THAT(rv, IsOk());
[email protected]da81f132010-08-18 23:39:299484}
9485
bncd16676a2016-07-20 16:23:019486TEST_F(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:429487 HttpRequestInfo request;
9488 request.method = "GET";
bncce36dca22015-04-21 22:11:239489 request.url = GURL("http://www.example.org/");
[email protected]c10450102011-06-27 09:06:169490 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
9491 "http://the.previous.site.com/");
Ramin Halavatib5e433e62018-02-07 07:41:109492 request.traffic_annotation =
9493 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429494
danakj1fd259a02016-04-16 03:17:099495 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169496 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279497
[email protected]1c773ea12009-04-28 19:58:429498 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239499 MockWrite(
9500 "GET / HTTP/1.1\r\n"
9501 "Host: www.example.org\r\n"
9502 "Connection: keep-alive\r\n"
9503 "Referer: http://the.previous.site.com/\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429504 };
9505
9506 // Lastly, the server responds with the actual content.
9507 MockRead data_reads[] = {
9508 MockRead("HTTP/1.0 200 OK\r\n"),
9509 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9510 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069511 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429512 };
9513
Ryan Sleevib8d7ea02018-05-07 20:01:019514 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:079515 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429516
[email protected]49639fa2011-12-20 23:22:419517 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429518
tfarina42834112016-09-22 13:38:209519 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019520 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429521
9522 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019523 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429524}
9525
bncd16676a2016-07-20 16:23:019526TEST_F(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:429527 HttpRequestInfo request;
9528 request.method = "POST";
bncce36dca22015-04-21 22:11:239529 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109530 request.traffic_annotation =
9531 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429532
danakj1fd259a02016-04-16 03:17:099533 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169534 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279535
[email protected]1c773ea12009-04-28 19:58:429536 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239537 MockWrite(
9538 "POST / HTTP/1.1\r\n"
9539 "Host: www.example.org\r\n"
9540 "Connection: keep-alive\r\n"
9541 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429542 };
9543
9544 // Lastly, the server responds with the actual content.
9545 MockRead data_reads[] = {
9546 MockRead("HTTP/1.0 200 OK\r\n"),
9547 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9548 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069549 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429550 };
9551
Ryan Sleevib8d7ea02018-05-07 20:01:019552 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:079553 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429554
[email protected]49639fa2011-12-20 23:22:419555 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429556
tfarina42834112016-09-22 13:38:209557 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019558 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429559
9560 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019561 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429562}
9563
bncd16676a2016-07-20 16:23:019564TEST_F(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:429565 HttpRequestInfo request;
9566 request.method = "PUT";
bncce36dca22015-04-21 22:11:239567 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109568 request.traffic_annotation =
9569 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429570
danakj1fd259a02016-04-16 03:17:099571 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169572 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279573
[email protected]1c773ea12009-04-28 19:58:429574 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239575 MockWrite(
9576 "PUT / HTTP/1.1\r\n"
9577 "Host: www.example.org\r\n"
9578 "Connection: keep-alive\r\n"
9579 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429580 };
9581
9582 // Lastly, the server responds with the actual content.
9583 MockRead data_reads[] = {
9584 MockRead("HTTP/1.0 200 OK\r\n"),
9585 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9586 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069587 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429588 };
9589
Ryan Sleevib8d7ea02018-05-07 20:01:019590 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:079591 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429592
[email protected]49639fa2011-12-20 23:22:419593 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429594
tfarina42834112016-09-22 13:38:209595 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019596 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429597
9598 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019599 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429600}
9601
bncd16676a2016-07-20 16:23:019602TEST_F(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:429603 HttpRequestInfo request;
9604 request.method = "HEAD";
bncce36dca22015-04-21 22:11:239605 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109606 request.traffic_annotation =
9607 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429608
danakj1fd259a02016-04-16 03:17:099609 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169610 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279611
[email protected]1c773ea12009-04-28 19:58:429612 MockWrite data_writes[] = {
csharrisonf473dd192015-08-18 13:54:139613 MockWrite("HEAD / HTTP/1.1\r\n"
9614 "Host: www.example.org\r\n"
9615 "Connection: keep-alive\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429616 };
9617
9618 // Lastly, the server responds with the actual content.
9619 MockRead data_reads[] = {
9620 MockRead("HTTP/1.0 200 OK\r\n"),
9621 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9622 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069623 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429624 };
9625
Ryan Sleevib8d7ea02018-05-07 20:01:019626 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:079627 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429628
[email protected]49639fa2011-12-20 23:22:419629 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429630
tfarina42834112016-09-22 13:38:209631 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019632 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429633
9634 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019635 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429636}
9637
bncd16676a2016-07-20 16:23:019638TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:429639 HttpRequestInfo request;
9640 request.method = "GET";
bncce36dca22015-04-21 22:11:239641 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:429642 request.load_flags = LOAD_BYPASS_CACHE;
Ramin Halavatib5e433e62018-02-07 07:41:109643 request.traffic_annotation =
9644 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429645
danakj1fd259a02016-04-16 03:17:099646 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169647 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279648
[email protected]1c773ea12009-04-28 19:58:429649 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239650 MockWrite(
9651 "GET / HTTP/1.1\r\n"
9652 "Host: www.example.org\r\n"
9653 "Connection: keep-alive\r\n"
9654 "Pragma: no-cache\r\n"
9655 "Cache-Control: no-cache\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429656 };
9657
9658 // Lastly, the server responds with the actual content.
9659 MockRead data_reads[] = {
9660 MockRead("HTTP/1.0 200 OK\r\n"),
9661 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9662 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069663 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429664 };
9665
Ryan Sleevib8d7ea02018-05-07 20:01:019666 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:079667 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429668
[email protected]49639fa2011-12-20 23:22:419669 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429670
tfarina42834112016-09-22 13:38:209671 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019672 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429673
9674 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019675 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429676}
9677
bncd16676a2016-07-20 16:23:019678TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:429679 HttpRequestInfo request;
9680 request.method = "GET";
bncce36dca22015-04-21 22:11:239681 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:429682 request.load_flags = LOAD_VALIDATE_CACHE;
Ramin Halavatib5e433e62018-02-07 07:41:109683 request.traffic_annotation =
9684 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429685
danakj1fd259a02016-04-16 03:17:099686 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169687 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279688
[email protected]1c773ea12009-04-28 19:58:429689 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239690 MockWrite(
9691 "GET / HTTP/1.1\r\n"
9692 "Host: www.example.org\r\n"
9693 "Connection: keep-alive\r\n"
9694 "Cache-Control: max-age=0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429695 };
9696
9697 // Lastly, the server responds with the actual content.
9698 MockRead data_reads[] = {
9699 MockRead("HTTP/1.0 200 OK\r\n"),
9700 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9701 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069702 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429703 };
9704
Ryan Sleevib8d7ea02018-05-07 20:01:019705 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:079706 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429707
[email protected]49639fa2011-12-20 23:22:419708 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429709
tfarina42834112016-09-22 13:38:209710 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019711 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429712
9713 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019714 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429715}
9716
bncd16676a2016-07-20 16:23:019717TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:429718 HttpRequestInfo request;
9719 request.method = "GET";
bncce36dca22015-04-21 22:11:239720 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:439721 request.extra_headers.SetHeader("FooHeader", "Bar");
Ramin Halavatib5e433e62018-02-07 07:41:109722 request.traffic_annotation =
9723 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429724
danakj1fd259a02016-04-16 03:17:099725 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169726 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279727
[email protected]1c773ea12009-04-28 19:58:429728 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239729 MockWrite(
9730 "GET / HTTP/1.1\r\n"
9731 "Host: www.example.org\r\n"
9732 "Connection: keep-alive\r\n"
9733 "FooHeader: Bar\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429734 };
9735
9736 // Lastly, the server responds with the actual content.
9737 MockRead data_reads[] = {
9738 MockRead("HTTP/1.0 200 OK\r\n"),
9739 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9740 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069741 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429742 };
9743
Ryan Sleevib8d7ea02018-05-07 20:01:019744 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:079745 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429746
[email protected]49639fa2011-12-20 23:22:419747 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429748
tfarina42834112016-09-22 13:38:209749 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019750 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429751
9752 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019753 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429754}
9755
bncd16676a2016-07-20 16:23:019756TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:479757 HttpRequestInfo request;
9758 request.method = "GET";
bncce36dca22015-04-21 22:11:239759 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:439760 request.extra_headers.SetHeader("referer", "www.foo.com");
9761 request.extra_headers.SetHeader("hEllo", "Kitty");
9762 request.extra_headers.SetHeader("FoO", "bar");
Ramin Halavatib5e433e62018-02-07 07:41:109763 request.traffic_annotation =
9764 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]270c6412010-03-29 22:02:479765
danakj1fd259a02016-04-16 03:17:099766 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169767 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279768
[email protected]270c6412010-03-29 22:02:479769 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239770 MockWrite(
9771 "GET / HTTP/1.1\r\n"
9772 "Host: www.example.org\r\n"
9773 "Connection: keep-alive\r\n"
9774 "referer: www.foo.com\r\n"
9775 "hEllo: Kitty\r\n"
9776 "FoO: bar\r\n\r\n"),
[email protected]270c6412010-03-29 22:02:479777 };
9778
9779 // Lastly, the server responds with the actual content.
9780 MockRead data_reads[] = {
9781 MockRead("HTTP/1.0 200 OK\r\n"),
9782 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9783 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069784 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:479785 };
9786
Ryan Sleevib8d7ea02018-05-07 20:01:019787 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:079788 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:479789
[email protected]49639fa2011-12-20 23:22:419790 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:479791
tfarina42834112016-09-22 13:38:209792 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019793 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]270c6412010-03-29 22:02:479794
9795 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019796 EXPECT_THAT(rv, IsOk());
[email protected]270c6412010-03-29 22:02:479797}
9798
bncd16676a2016-07-20 16:23:019799TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279800 HttpRequestInfo request;
9801 request.method = "GET";
bncce36dca22015-04-21 22:11:239802 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109803 request.traffic_annotation =
9804 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:279805
Lily Houghton8c2f97d2018-01-22 05:06:599806 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499807 ProxyResolutionService::CreateFixedFromPacResult(
9808 "SOCKS myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519809 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079810 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:029811
danakj1fd259a02016-04-16 03:17:099812 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169813 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:029814
[email protected]3cd17242009-06-23 02:59:029815 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
9816 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9817
9818 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239819 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
9820 MockWrite(
9821 "GET / HTTP/1.1\r\n"
9822 "Host: www.example.org\r\n"
9823 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:029824
9825 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:069826 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:029827 MockRead("HTTP/1.0 200 OK\r\n"),
9828 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9829 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069830 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:029831 };
9832
Ryan Sleevib8d7ea02018-05-07 20:01:019833 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:079834 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:029835
[email protected]49639fa2011-12-20 23:22:419836 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:029837
tfarina42834112016-09-22 13:38:209838 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019839 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:029840
9841 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019842 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029843
bnc691fda62016-08-12 00:43:169844 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529845 ASSERT_TRUE(response);
[email protected]3cd17242009-06-23 02:59:029846
tbansal2ecbbc72016-10-06 17:15:479847 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]029c83b62013-01-24 05:28:209848 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169849 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209850 TestLoadTimingNotReusedWithPac(load_timing_info,
9851 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9852
[email protected]3cd17242009-06-23 02:59:029853 std::string response_text;
bnc691fda62016-08-12 00:43:169854 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019855 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029856 EXPECT_EQ("Payload", response_text);
9857}
9858
bncd16676a2016-07-20 16:23:019859TEST_F(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279860 HttpRequestInfo request;
9861 request.method = "GET";
bncce36dca22015-04-21 22:11:239862 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109863 request.traffic_annotation =
9864 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:279865
Lily Houghton8c2f97d2018-01-22 05:06:599866 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499867 ProxyResolutionService::CreateFixedFromPacResult(
9868 "SOCKS myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519869 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079870 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:029871
danakj1fd259a02016-04-16 03:17:099872 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169873 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:029874
[email protected]3cd17242009-06-23 02:59:029875 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
9876 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9877
9878 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239879 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
9880 arraysize(write_buffer)),
9881 MockWrite(
9882 "GET / HTTP/1.1\r\n"
9883 "Host: www.example.org\r\n"
9884 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:029885
9886 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:019887 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
9888 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:359889 MockRead("HTTP/1.0 200 OK\r\n"),
9890 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9891 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069892 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:359893 };
9894
Ryan Sleevib8d7ea02018-05-07 20:01:019895 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:079896 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:359897
[email protected]8ddf8322012-02-23 18:08:069898 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:079899 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:359900
[email protected]49639fa2011-12-20 23:22:419901 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:359902
tfarina42834112016-09-22 13:38:209903 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019904 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:359905
9906 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019907 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359908
[email protected]029c83b62013-01-24 05:28:209909 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169910 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209911 TestLoadTimingNotReusedWithPac(load_timing_info,
9912 CONNECT_TIMING_HAS_SSL_TIMES);
9913
bnc691fda62016-08-12 00:43:169914 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529915 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:479916 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:359917
9918 std::string response_text;
bnc691fda62016-08-12 00:43:169919 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019920 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359921 EXPECT_EQ("Payload", response_text);
9922}
9923
bncd16676a2016-07-20 16:23:019924TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:209925 HttpRequestInfo request;
9926 request.method = "GET";
bncce36dca22015-04-21 22:11:239927 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109928 request.traffic_annotation =
9929 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:209930
Ramin Halavatica8d5252018-03-12 05:33:499931 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9932 "socks4://myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519933 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079934 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:209935
danakj1fd259a02016-04-16 03:17:099936 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169937 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:209938
9939 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
9940 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9941
9942 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239943 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
9944 MockWrite(
9945 "GET / HTTP/1.1\r\n"
9946 "Host: www.example.org\r\n"
9947 "Connection: keep-alive\r\n\r\n")};
[email protected]029c83b62013-01-24 05:28:209948
9949 MockRead data_reads[] = {
9950 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
9951 MockRead("HTTP/1.0 200 OK\r\n"),
9952 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9953 MockRead("Payload"),
9954 MockRead(SYNCHRONOUS, OK)
9955 };
9956
Ryan Sleevib8d7ea02018-05-07 20:01:019957 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:079958 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:209959
9960 TestCompletionCallback callback;
9961
tfarina42834112016-09-22 13:38:209962 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019963 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:209964
9965 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019966 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:209967
bnc691fda62016-08-12 00:43:169968 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529969 ASSERT_TRUE(response);
[email protected]029c83b62013-01-24 05:28:209970
9971 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169972 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209973 TestLoadTimingNotReused(load_timing_info,
9974 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9975
9976 std::string response_text;
bnc691fda62016-08-12 00:43:169977 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019978 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:209979 EXPECT_EQ("Payload", response_text);
9980}
9981
bncd16676a2016-07-20 16:23:019982TEST_F(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279983 HttpRequestInfo request;
9984 request.method = "GET";
bncce36dca22015-04-21 22:11:239985 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109986 request.traffic_annotation =
9987 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:279988
Lily Houghton8c2f97d2018-01-22 05:06:599989 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499990 ProxyResolutionService::CreateFixedFromPacResult(
9991 "SOCKS5 myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519992 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079993 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:359994
danakj1fd259a02016-04-16 03:17:099995 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169996 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:359997
[email protected]e0c27be2009-07-15 13:09:359998 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
9999 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:3710000 const char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:2310001 0x05, // Version
10002 0x01, // Command (CONNECT)
10003 0x00, // Reserved.
10004 0x03, // Address type (DOMAINNAME).
10005 0x0F, // Length of domain (15)
10006 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
10007 '.', 'o', 'r', 'g', 0x00, 0x50, // 16-bit port (80)
[email protected]f209dba2009-12-18 00:24:3710008 };
[email protected]e0c27be2009-07-15 13:09:3510009 const char kSOCKS5OkResponse[] =
10010 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
10011
10012 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310013 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
10014 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
10015 MockWrite(
10016 "GET / HTTP/1.1\r\n"
10017 "Host: www.example.org\r\n"
10018 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:3510019
10020 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:0110021 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
10022 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:3510023 MockRead("HTTP/1.0 200 OK\r\n"),
10024 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
10025 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:0610026 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:3510027 };
10028
Ryan Sleevib8d7ea02018-05-07 20:01:0110029 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710030 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:3510031
[email protected]49639fa2011-12-20 23:22:4110032 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:3510033
tfarina42834112016-09-22 13:38:2010034 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110035 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:3510036
10037 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110038 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3510039
bnc691fda62016-08-12 00:43:1610040 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210041 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:4710042 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:3510043
[email protected]029c83b62013-01-24 05:28:2010044 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1610045 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2010046 TestLoadTimingNotReusedWithPac(load_timing_info,
10047 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
10048
[email protected]e0c27be2009-07-15 13:09:3510049 std::string response_text;
bnc691fda62016-08-12 00:43:1610050 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0110051 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3510052 EXPECT_EQ("Payload", response_text);
10053}
10054
bncd16676a2016-07-20 16:23:0110055TEST_F(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:2710056 HttpRequestInfo request;
10057 request.method = "GET";
bncce36dca22015-04-21 22:11:2310058 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010059 request.traffic_annotation =
10060 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710061
Lily Houghton8c2f97d2018-01-22 05:06:5910062 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910063 ProxyResolutionService::CreateFixedFromPacResult(
10064 "SOCKS5 myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110065 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710066 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:3510067
danakj1fd259a02016-04-16 03:17:0910068 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610069 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:3510070
[email protected]e0c27be2009-07-15 13:09:3510071 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
10072 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:3710073 const unsigned char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:2310074 0x05, // Version
10075 0x01, // Command (CONNECT)
10076 0x00, // Reserved.
10077 0x03, // Address type (DOMAINNAME).
10078 0x0F, // Length of domain (15)
10079 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
10080 '.', 'o', 'r', 'g', 0x01, 0xBB, // 16-bit port (443)
[email protected]f209dba2009-12-18 00:24:3710081 };
10082
[email protected]e0c27be2009-07-15 13:09:3510083 const char kSOCKS5OkResponse[] =
10084 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
10085
10086 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310087 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
10088 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
10089 arraysize(kSOCKS5OkRequest)),
10090 MockWrite(
10091 "GET / HTTP/1.1\r\n"
10092 "Host: www.example.org\r\n"
10093 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:3510094
10095 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:0110096 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
10097 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:0210098 MockRead("HTTP/1.0 200 OK\r\n"),
10099 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
10100 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:0610101 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:0210102 };
10103
Ryan Sleevib8d7ea02018-05-07 20:01:0110104 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710105 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:0210106
[email protected]8ddf8322012-02-23 18:08:0610107 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710108 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:0210109
[email protected]49639fa2011-12-20 23:22:4110110 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:0210111
tfarina42834112016-09-22 13:38:2010112 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110113 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:0210114
10115 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110116 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0210117
bnc691fda62016-08-12 00:43:1610118 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210119 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:4710120 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]3cd17242009-06-23 02:59:0210121
[email protected]029c83b62013-01-24 05:28:2010122 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1610123 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2010124 TestLoadTimingNotReusedWithPac(load_timing_info,
10125 CONNECT_TIMING_HAS_SSL_TIMES);
10126
[email protected]3cd17242009-06-23 02:59:0210127 std::string response_text;
bnc691fda62016-08-12 00:43:1610128 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0110129 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0210130 EXPECT_EQ("Payload", response_text);
10131}
10132
[email protected]448d4ca52012-03-04 04:12:2310133namespace {
10134
[email protected]04e5be32009-06-26 20:00:3110135// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:0610136
10137struct GroupNameTest {
10138 std::string proxy_server;
10139 std::string url;
10140 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:1810141 bool ssl;
[email protected]2d731a32010-04-29 01:04:0610142};
10143
danakj1fd259a02016-04-16 03:17:0910144std::unique_ptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]bb88e1d32013-05-03 23:11:0710145 SpdySessionDependencies* session_deps_) {
danakj1fd259a02016-04-16 03:17:0910146 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:0610147
bnc525e175a2016-06-20 12:36:4010148 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310149 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110150 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnc7dc7e1b42015-07-28 14:43:1210151 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110152 http_server_properties->SetHttp2AlternativeService(
bncaa60ff402016-06-22 19:12:4210153 url::SchemeHostPort("https", "host.with.alternate", 443),
zhongyi3d4a55e72016-04-22 20:36:4610154 alternative_service, expiration);
[email protected]2d731a32010-04-29 01:04:0610155
10156 return session;
10157}
10158
mmenkee65e7af2015-10-13 17:16:4210159int GroupNameTransactionHelper(const std::string& url,
10160 HttpNetworkSession* session) {
[email protected]2d731a32010-04-29 01:04:0610161 HttpRequestInfo request;
10162 request.method = "GET";
10163 request.url = GURL(url);
Ramin Halavatib5e433e62018-02-07 07:41:1010164 request.traffic_annotation =
10165 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d731a32010-04-29 01:04:0610166
bnc691fda62016-08-12 00:43:1610167 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
[email protected]cb9bf6ca2011-01-28 13:15:2710168
[email protected]49639fa2011-12-20 23:22:4110169 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:0610170
10171 // We do not complete this request, the dtor will clean the transaction up.
tfarina42834112016-09-22 13:38:2010172 return trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]2d731a32010-04-29 01:04:0610173}
10174
[email protected]448d4ca52012-03-04 04:12:2310175} // namespace
10176
bncd16676a2016-07-20 16:23:0110177TEST_F(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:0610178 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:2310179 {
10180 "", // unused
10181 "http://www.example.org/direct",
10182 "www.example.org:80",
10183 false,
10184 },
10185 {
10186 "", // unused
10187 "http://[2001:1418:13:1::25]/direct",
10188 "[2001:1418:13:1::25]:80",
10189 false,
10190 },
[email protected]04e5be32009-06-26 20:00:3110191
bncce36dca22015-04-21 22:11:2310192 // SSL Tests
10193 {
10194 "", // unused
10195 "https://www.example.org/direct_ssl",
10196 "ssl/www.example.org:443",
10197 true,
10198 },
10199 {
10200 "", // unused
10201 "https://[2001:1418:13:1::25]/direct",
10202 "ssl/[2001:1418:13:1::25]:443",
10203 true,
10204 },
10205 {
10206 "", // unused
bncaa60ff402016-06-22 19:12:4210207 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:2310208 "ssl/host.with.alternate:443",
10209 true,
10210 },
[email protected]2d731a32010-04-29 01:04:0610211 };
[email protected]2ff8b312010-04-26 22:20:5410212
viettrungluue4a8b882014-10-16 06:17:3810213 for (size_t i = 0; i < arraysize(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5910214 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910215 ProxyResolutionService::CreateFixed(tests[i].proxy_server,
10216 TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:0910217 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:4010218 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:0610219
mmenkee65e7af2015-10-13 17:16:4210220 HttpNetworkSessionPeer peer(session.get());
[email protected]ab739042011-04-07 15:22:2810221 CaptureGroupNameTransportSocketPool* transport_conn_pool =
bnc87dcefc2017-05-25 12:47:5810222 new CaptureGroupNameTransportSocketPool(nullptr, nullptr);
[email protected]2431756e2010-09-29 20:26:1310223 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
bnc87dcefc2017-05-25 12:47:5810224 new CaptureGroupNameSSLSocketPool(nullptr, nullptr);
Jeremy Roman0579ed62017-08-29 15:56:1910225 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
[email protected]a42dbd142011-11-17 16:42:0210226 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
10227 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
dchengc7eeda422015-12-26 03:56:4810228 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:0610229
10230 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:4210231 GroupNameTransactionHelper(tests[i].url, session.get()));
Tarun Bansal162eabe52018-01-20 01:16:3910232 if (tests[i].ssl) {
[email protected]e60e47a2010-07-14 03:37:1810233 EXPECT_EQ(tests[i].expected_group_name,
10234 ssl_conn_pool->last_group_name_received());
Tarun Bansal162eabe52018-01-20 01:16:3910235 } else {
[email protected]e60e47a2010-07-14 03:37:1810236 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:2810237 transport_conn_pool->last_group_name_received());
Tarun Bansal162eabe52018-01-20 01:16:3910238 }
10239 // When SSL proxy is in use, socket must be requested from |ssl_conn_pool|.
10240 EXPECT_EQ(tests[i].ssl, ssl_conn_pool->socket_requested());
10241 // When SSL proxy is not in use, socket must be requested from
10242 // |transport_conn_pool|.
10243 EXPECT_EQ(!tests[i].ssl, transport_conn_pool->socket_requested());
[email protected]2d731a32010-04-29 01:04:0610244 }
[email protected]2d731a32010-04-29 01:04:0610245}
10246
bncd16676a2016-07-20 16:23:0110247TEST_F(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:0610248 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:2310249 {
Matt Menked1eb6d42018-01-17 04:54:0610250 "http_proxy", "http://www.example.org/http_proxy_normal",
10251 "http_proxy/www.example.org:80", false,
bncce36dca22015-04-21 22:11:2310252 },
[email protected]2d731a32010-04-29 01:04:0610253
bncce36dca22015-04-21 22:11:2310254 // SSL Tests
10255 {
Matt Menked1eb6d42018-01-17 04:54:0610256 "http_proxy", "https://www.example.org/http_connect_ssl",
10257 "http_proxy/ssl/www.example.org:443", true,
bncce36dca22015-04-21 22:11:2310258 },
[email protected]af3490e2010-10-16 21:02:2910259
bncce36dca22015-04-21 22:11:2310260 {
Matt Menked1eb6d42018-01-17 04:54:0610261 "http_proxy", "https://host.with.alternate/direct",
10262 "http_proxy/ssl/host.with.alternate:443", true,
bncce36dca22015-04-21 22:11:2310263 },
[email protected]45499252013-01-23 17:12:5610264
bncce36dca22015-04-21 22:11:2310265 {
Matt Menked1eb6d42018-01-17 04:54:0610266 "http_proxy", "ftp://ftp.google.com/http_proxy_normal",
10267 "http_proxy/ftp/ftp.google.com:21", false,
bncce36dca22015-04-21 22:11:2310268 },
[email protected]2d731a32010-04-29 01:04:0610269 };
10270
viettrungluue4a8b882014-10-16 06:17:3810271 for (size_t i = 0; i < arraysize(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5910272 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910273 ProxyResolutionService::CreateFixed(tests[i].proxy_server,
10274 TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:0910275 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:4010276 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:0610277
mmenkee65e7af2015-10-13 17:16:4210278 HttpNetworkSessionPeer peer(session.get());
[email protected]2d731a32010-04-29 01:04:0610279
[email protected]e60e47a2010-07-14 03:37:1810280 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:1310281 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:3410282 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:1310283 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:3410284 new CaptureGroupNameSSLSocketPool(NULL, NULL);
Jeremy Roman0579ed62017-08-29 15:56:1910285 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
aviadef3442016-10-03 18:50:3910286 mock_pool_manager->SetSocketPoolForHTTPProxy(
10287 proxy_host, base::WrapUnique(http_proxy_pool));
10288 mock_pool_manager->SetSocketPoolForSSLWithProxy(
10289 proxy_host, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:4810290 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:0610291
10292 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:4210293 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:1810294 if (tests[i].ssl)
10295 EXPECT_EQ(tests[i].expected_group_name,
10296 ssl_conn_pool->last_group_name_received());
10297 else
10298 EXPECT_EQ(tests[i].expected_group_name,
10299 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:0610300 }
[email protected]2d731a32010-04-29 01:04:0610301}
10302
bncd16676a2016-07-20 16:23:0110303TEST_F(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:0610304 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:2310305 {
10306 "socks4://socks_proxy:1080",
10307 "http://www.example.org/socks4_direct",
10308 "socks4/www.example.org:80",
10309 false,
10310 },
10311 {
10312 "socks5://socks_proxy:1080",
10313 "http://www.example.org/socks5_direct",
10314 "socks5/www.example.org:80",
10315 false,
10316 },
[email protected]2d731a32010-04-29 01:04:0610317
bncce36dca22015-04-21 22:11:2310318 // SSL Tests
10319 {
10320 "socks4://socks_proxy:1080",
10321 "https://www.example.org/socks4_ssl",
10322 "socks4/ssl/www.example.org:443",
10323 true,
10324 },
10325 {
10326 "socks5://socks_proxy:1080",
10327 "https://www.example.org/socks5_ssl",
10328 "socks5/ssl/www.example.org:443",
10329 true,
10330 },
[email protected]af3490e2010-10-16 21:02:2910331
bncce36dca22015-04-21 22:11:2310332 {
10333 "socks4://socks_proxy:1080",
bncaa60ff402016-06-22 19:12:4210334 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:2310335 "socks4/ssl/host.with.alternate:443",
10336 true,
10337 },
[email protected]04e5be32009-06-26 20:00:3110338 };
10339
viettrungluue4a8b882014-10-16 06:17:3810340 for (size_t i = 0; i < arraysize(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5910341 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910342 ProxyResolutionService::CreateFixed(tests[i].proxy_server,
10343 TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:0910344 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:4010345 SetupSessionForGroupNameTests(&session_deps_));
[email protected]8b114dd72011-03-25 05:33:0210346
mmenkee65e7af2015-10-13 17:16:4210347 HttpNetworkSessionPeer peer(session.get());
[email protected]04e5be32009-06-26 20:00:3110348
[email protected]e60e47a2010-07-14 03:37:1810349 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:1310350 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:3410351 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:1310352 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:3410353 new CaptureGroupNameSSLSocketPool(NULL, NULL);
Jeremy Roman0579ed62017-08-29 15:56:1910354 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
aviadef3442016-10-03 18:50:3910355 mock_pool_manager->SetSocketPoolForSOCKSProxy(
10356 proxy_host, base::WrapUnique(socks_conn_pool));
10357 mock_pool_manager->SetSocketPoolForSSLWithProxy(
10358 proxy_host, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:4810359 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]04e5be32009-06-26 20:00:3110360
bnc691fda62016-08-12 00:43:1610361 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]04e5be32009-06-26 20:00:3110362
[email protected]2d731a32010-04-29 01:04:0610363 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:4210364 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:1810365 if (tests[i].ssl)
10366 EXPECT_EQ(tests[i].expected_group_name,
10367 ssl_conn_pool->last_group_name_received());
10368 else
10369 EXPECT_EQ(tests[i].expected_group_name,
10370 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:3110371 }
10372}
10373
bncd16676a2016-07-20 16:23:0110374TEST_F(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:2710375 HttpRequestInfo request;
10376 request.method = "GET";
bncce36dca22015-04-21 22:11:2310377 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010378 request.traffic_annotation =
10379 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710380
Ramin Halavatica8d5252018-03-12 05:33:4910381 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
10382 "myproxy:70;foobar:80", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]b59ff372009-07-15 22:04:3210383
[email protected]69719062010-01-05 20:09:2110384 // This simulates failure resolving all hostnames; that means we will fail
10385 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:0710386 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:3210387
danakj1fd259a02016-04-16 03:17:0910388 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610389 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]9172a982009-06-06 00:30:2510390
[email protected]49639fa2011-12-20 23:22:4110391 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:2510392
tfarina42834112016-09-22 13:38:2010393 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110394 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9172a982009-06-06 00:30:2510395
[email protected]9172a982009-06-06 00:30:2510396 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110397 EXPECT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]9172a982009-06-06 00:30:2510398}
10399
Miriam Gershenson2a01b162018-03-22 22:54:4710400// LOAD_BYPASS_CACHE should trigger the host cache bypass.
10401TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh) {
[email protected]cb9bf6ca2011-01-28 13:15:2710402 // Issue a request, asking to bypass the cache(s).
maksim.sisov31452af2016-07-27 06:38:1010403 HttpRequestInfo request_info;
10404 request_info.method = "GET";
Miriam Gershenson2a01b162018-03-22 22:54:4710405 request_info.load_flags = LOAD_BYPASS_CACHE;
maksim.sisov31452af2016-07-27 06:38:1010406 request_info.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010407 request_info.traffic_annotation =
10408 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710409
[email protected]a2c2fb92009-07-18 07:31:0410410 // Select a host resolver that does caching.
Jeremy Roman0579ed62017-08-29 15:56:1910411 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
[email protected]b59ff372009-07-15 22:04:3210412
danakj1fd259a02016-04-16 03:17:0910413 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610414 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3b9cca42009-06-16 01:08:2810415
bncce36dca22015-04-21 22:11:2310416 // Warm up the host cache so it has an entry for "www.example.org".
[email protected]3b9cca42009-06-16 01:08:2810417 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:2910418 TestCompletionCallback callback;
maksim.sisov31452af2016-07-27 06:38:1010419 std::unique_ptr<HostResolver::Request> request1;
[email protected]bb88e1d32013-05-03 23:11:0710420 int rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:2310421 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:1010422 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request1,
tfarina42834112016-09-22 13:38:2010423 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110424 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4710425 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110426 EXPECT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:2810427
10428 // Verify that it was added to host cache, by doing a subsequent async lookup
10429 // and confirming it completes synchronously.
maksim.sisov31452af2016-07-27 06:38:1010430 std::unique_ptr<HostResolver::Request> request2;
[email protected]bb88e1d32013-05-03 23:11:0710431 rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:2310432 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:1010433 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request2,
tfarina42834112016-09-22 13:38:2010434 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110435 ASSERT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:2810436
bncce36dca22015-04-21 22:11:2310437 // Inject a failure the next time that "www.example.org" is resolved. This way
[email protected]3b9cca42009-06-16 01:08:2810438 // we can tell if the next lookup hit the cache, or the "network".
10439 // (cache --> success, "network" --> failure).
bncce36dca22015-04-21 22:11:2310440 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.example.org");
[email protected]3b9cca42009-06-16 01:08:2810441
10442 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
10443 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:0610444 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
Ryan Sleevib8d7ea02018-05-07 20:01:0110445 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0710446 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:2810447
[email protected]3b9cca42009-06-16 01:08:2810448 // Run the request.
tfarina42834112016-09-22 13:38:2010449 rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110450 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]49639fa2011-12-20 23:22:4110451 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:2810452
10453 // If we bypassed the cache, we would have gotten a failure while resolving
bncce36dca22015-04-21 22:11:2310454 // "www.example.org".
robpercival214763f2016-07-01 23:27:0110455 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]3b9cca42009-06-16 01:08:2810456}
10457
[email protected]0877e3d2009-10-17 22:29:5710458// Make sure we can handle an error when writing the request.
bncd16676a2016-07-20 16:23:0110459TEST_F(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:5710460 HttpRequestInfo request;
10461 request.method = "GET";
10462 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:1010463 request.traffic_annotation =
10464 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5710465
10466 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:0610467 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:5710468 };
Ryan Sleevib8d7ea02018-05-07 20:01:0110469 StaticSocketDataProvider data(base::span<MockRead>(), write_failure);
[email protected]bb88e1d32013-05-03 23:11:0710470 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:0910471 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5710472
[email protected]49639fa2011-12-20 23:22:4110473 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5710474
bnc691fda62016-08-12 00:43:1610475 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5710476
tfarina42834112016-09-22 13:38:2010477 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110478 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710479
10480 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110481 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:5910482
10483 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1610484 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5910485 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:5710486}
10487
zmo9528c9f42015-08-04 22:12:0810488// Check that a connection closed after the start of the headers finishes ok.
bncd16676a2016-07-20 16:23:0110489TEST_F(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:5710490 HttpRequestInfo request;
10491 request.method = "GET";
10492 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:1010493 request.traffic_annotation =
10494 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5710495
10496 MockRead data_reads[] = {
10497 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:0610498 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:5710499 };
10500
Ryan Sleevib8d7ea02018-05-07 20:01:0110501 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0710502 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:0910503 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5710504
[email protected]49639fa2011-12-20 23:22:4110505 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5710506
bnc691fda62016-08-12 00:43:1610507 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5710508
tfarina42834112016-09-22 13:38:2010509 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110510 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710511
10512 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110513 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:0810514
bnc691fda62016-08-12 00:43:1610515 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210516 ASSERT_TRUE(response);
zmo9528c9f42015-08-04 22:12:0810517
wezca1070932016-05-26 20:30:5210518 EXPECT_TRUE(response->headers);
zmo9528c9f42015-08-04 22:12:0810519 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
10520
10521 std::string response_data;
bnc691fda62016-08-12 00:43:1610522 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0110523 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:0810524 EXPECT_EQ("", response_data);
ttuttled9dbc652015-09-29 20:00:5910525
10526 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1610527 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5910528 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:5710529}
10530
10531// Make sure that a dropped connection while draining the body for auth
10532// restart does the right thing.
bncd16676a2016-07-20 16:23:0110533TEST_F(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:5710534 HttpRequestInfo request;
10535 request.method = "GET";
bncce36dca22015-04-21 22:11:2310536 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010537 request.traffic_annotation =
10538 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5710539
10540 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2310541 MockWrite(
10542 "GET / HTTP/1.1\r\n"
10543 "Host: www.example.org\r\n"
10544 "Connection: keep-alive\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:5710545 };
10546
10547 MockRead data_reads1[] = {
10548 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
10549 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
10550 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10551 MockRead("Content-Length: 14\r\n\r\n"),
10552 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:0610553 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:5710554 };
10555
Ryan Sleevib8d7ea02018-05-07 20:01:0110556 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:0710557 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:5710558
bnc691fda62016-08-12 00:43:1610559 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0877e3d2009-10-17 22:29:5710560 // be issuing -- the final header line contains the credentials.
10561 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:2310562 MockWrite(
10563 "GET / HTTP/1.1\r\n"
10564 "Host: www.example.org\r\n"
10565 "Connection: keep-alive\r\n"
10566 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:5710567 };
10568
10569 // Lastly, the server responds with the actual content.
10570 MockRead data_reads2[] = {
10571 MockRead("HTTP/1.1 200 OK\r\n"),
10572 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10573 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610574 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:5710575 };
10576
Ryan Sleevib8d7ea02018-05-07 20:01:0110577 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:0710578 session_deps_.socket_factory->AddSocketDataProvider(&data2);
danakj1fd259a02016-04-16 03:17:0910579 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5710580
[email protected]49639fa2011-12-20 23:22:4110581 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:5710582
bnc691fda62016-08-12 00:43:1610583 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5010584
tfarina42834112016-09-22 13:38:2010585 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110586 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710587
10588 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0110589 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:5710590
bnc691fda62016-08-12 00:43:1610591 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210592 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410593 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:5710594
[email protected]49639fa2011-12-20 23:22:4110595 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:5710596
bnc691fda62016-08-12 00:43:1610597 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:0110598 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710599
10600 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0110601 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:5710602
bnc691fda62016-08-12 00:43:1610603 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210604 ASSERT_TRUE(response);
10605 EXPECT_FALSE(response->auth_challenge);
[email protected]0877e3d2009-10-17 22:29:5710606 EXPECT_EQ(100, response->headers->GetContentLength());
10607}
10608
10609// Test HTTPS connections going through a proxy that sends extra data.
bncd16676a2016-07-20 16:23:0110610TEST_F(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
Ramin Halavatica8d5252018-03-12 05:33:4910611 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
10612 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5710613
10614 HttpRequestInfo request;
10615 request.method = "GET";
bncce36dca22015-04-21 22:11:2310616 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010617 request.traffic_annotation =
10618 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5710619
10620 MockRead proxy_reads[] = {
10621 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:0610622 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:5710623 };
10624
Ryan Sleevib8d7ea02018-05-07 20:01:0110625 StaticSocketDataProvider data(proxy_reads, base::span<MockWrite>());
[email protected]8ddf8322012-02-23 18:08:0610626 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:5710627
[email protected]bb88e1d32013-05-03 23:11:0710628 session_deps_.socket_factory->AddSocketDataProvider(&data);
10629 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:5710630
[email protected]49639fa2011-12-20 23:22:4110631 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5710632
[email protected]bb88e1d32013-05-03 23:11:0710633 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:5710634
danakj1fd259a02016-04-16 03:17:0910635 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610636 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5710637
tfarina42834112016-09-22 13:38:2010638 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110639 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710640
10641 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110642 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]0877e3d2009-10-17 22:29:5710643}
10644
bncd16676a2016-07-20 16:23:0110645TEST_F(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:4610646 HttpRequestInfo request;
10647 request.method = "GET";
bncce36dca22015-04-21 22:11:2310648 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010649 request.traffic_annotation =
10650 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]9492e4a2010-02-24 00:58:4610651
danakj1fd259a02016-04-16 03:17:0910652 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610653 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710654
[email protected]e22e1362009-11-23 21:31:1210655 MockRead data_reads[] = {
10656 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610657 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:1210658 };
[email protected]9492e4a2010-02-24 00:58:4610659
Ryan Sleevib8d7ea02018-05-07 20:01:0110660 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0710661 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:4610662
[email protected]49639fa2011-12-20 23:22:4110663 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:4610664
tfarina42834112016-09-22 13:38:2010665 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110666 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9492e4a2010-02-24 00:58:4610667
robpercival214763f2016-07-01 23:27:0110668 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]9492e4a2010-02-24 00:58:4610669
bnc691fda62016-08-12 00:43:1610670 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210671 ASSERT_TRUE(response);
[email protected]9492e4a2010-02-24 00:58:4610672
wezca1070932016-05-26 20:30:5210673 EXPECT_TRUE(response->headers);
[email protected]9492e4a2010-02-24 00:58:4610674 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
10675
10676 std::string response_data;
bnc691fda62016-08-12 00:43:1610677 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0110678 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]e22e1362009-11-23 21:31:1210679}
10680
bncd16676a2016-07-20 16:23:0110681TEST_F(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:1510682 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:5210683 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
avibf0746c2015-12-09 19:53:1410684 const uint64_t kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:2110685 UploadFileElementReader::ScopedOverridingContentLengthForTests
10686 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:3310687
danakj1fd259a02016-04-16 03:17:0910688 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:1910689 element_readers.push_back(std::make_unique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:1410690 base::ThreadTaskRunnerHandle::Get().get(), temp_file_path, 0,
ricea2deef682016-09-09 08:04:0710691 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:2210692 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:2710693
10694 HttpRequestInfo request;
10695 request.method = "POST";
bncce36dca22015-04-21 22:11:2310696 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:2710697 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1010698 request.traffic_annotation =
10699 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]329b68b2012-11-14 17:54:2710700
danakj1fd259a02016-04-16 03:17:0910701 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610702 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]95d88ffe2010-02-04 21:25:3310703
10704 MockRead data_reads[] = {
10705 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
10706 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610707 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:3310708 };
Ryan Sleevib8d7ea02018-05-07 20:01:0110709 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0710710 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:3310711
[email protected]49639fa2011-12-20 23:22:4110712 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:3310713
tfarina42834112016-09-22 13:38:2010714 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110715 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]95d88ffe2010-02-04 21:25:3310716
10717 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110718 EXPECT_THAT(rv, IsError(ERR_UPLOAD_FILE_CHANGED));
[email protected]95d88ffe2010-02-04 21:25:3310719
bnc691fda62016-08-12 00:43:1610720 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210721 ASSERT_TRUE(response);
[email protected]95d88ffe2010-02-04 21:25:3310722
maksim.sisove869bf52016-06-23 17:11:5210723 EXPECT_FALSE(response->headers);
[email protected]95d88ffe2010-02-04 21:25:3310724
[email protected]dd3aa792013-07-16 19:10:2310725 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:3310726}
10727
bncd16676a2016-07-20 16:23:0110728TEST_F(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:1510729 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:5210730 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:3610731 std::string temp_file_content("Unreadable file.");
lazyboy8df84fc2017-04-12 02:12:4810732 ASSERT_EQ(static_cast<int>(temp_file_content.length()),
10733 base::WriteFile(temp_file, temp_file_content.c_str(),
10734 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:1110735 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:3610736
danakj1fd259a02016-04-16 03:17:0910737 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:1910738 element_readers.push_back(std::make_unique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:1410739 base::ThreadTaskRunnerHandle::Get().get(), temp_file, 0,
ricea2deef682016-09-09 08:04:0710740 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:2210741 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:2710742
10743 HttpRequestInfo request;
10744 request.method = "POST";
bncce36dca22015-04-21 22:11:2310745 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:2710746 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1010747 request.traffic_annotation =
10748 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]329b68b2012-11-14 17:54:2710749
[email protected]999dd8c2013-11-12 06:45:5410750 // If we try to upload an unreadable file, the transaction should fail.
danakj1fd259a02016-04-16 03:17:0910751 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610752 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]6624b4622010-03-29 19:58:3610753
Ryan Sleevib8d7ea02018-05-07 20:01:0110754 StaticSocketDataProvider data;
[email protected]bb88e1d32013-05-03 23:11:0710755 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:3610756
[email protected]49639fa2011-12-20 23:22:4110757 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:3610758
tfarina42834112016-09-22 13:38:2010759 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110760 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6624b4622010-03-29 19:58:3610761
10762 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110763 EXPECT_THAT(rv, IsError(ERR_ACCESS_DENIED));
[email protected]6624b4622010-03-29 19:58:3610764
[email protected]dd3aa792013-07-16 19:10:2310765 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:3610766}
10767
bncd16676a2016-07-20 16:23:0110768TEST_F(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
[email protected]02cad5d2013-10-02 08:14:0310769 class FakeUploadElementReader : public UploadElementReader {
10770 public:
Chris Watkins7a41d3552017-12-01 02:13:2710771 FakeUploadElementReader() = default;
10772 ~FakeUploadElementReader() override = default;
[email protected]02cad5d2013-10-02 08:14:0310773
Matt Menkecc1d3a902018-02-05 18:27:3310774 CompletionOnceCallback TakeCallback() { return std::move(callback_); }
[email protected]02cad5d2013-10-02 08:14:0310775
10776 // UploadElementReader overrides:
Matt Menkecc1d3a902018-02-05 18:27:3310777 int Init(CompletionOnceCallback callback) override {
10778 callback_ = std::move(callback);
[email protected]02cad5d2013-10-02 08:14:0310779 return ERR_IO_PENDING;
10780 }
avibf0746c2015-12-09 19:53:1410781 uint64_t GetContentLength() const override { return 0; }
10782 uint64_t BytesRemaining() const override { return 0; }
dchengb03027d2014-10-21 12:00:2010783 int Read(IOBuffer* buf,
10784 int buf_length,
Matt Menkecc1d3a902018-02-05 18:27:3310785 CompletionOnceCallback callback) override {
[email protected]02cad5d2013-10-02 08:14:0310786 return ERR_FAILED;
10787 }
10788
10789 private:
Matt Menkecc1d3a902018-02-05 18:27:3310790 CompletionOnceCallback callback_;
[email protected]02cad5d2013-10-02 08:14:0310791 };
10792
10793 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
danakj1fd259a02016-04-16 03:17:0910794 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
10795 element_readers.push_back(base::WrapUnique(fake_reader));
olli.raula6df48b2a2015-11-26 07:40:2210796 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02cad5d2013-10-02 08:14:0310797
10798 HttpRequestInfo request;
10799 request.method = "POST";
bncce36dca22015-04-21 22:11:2310800 request.url = GURL("http://www.example.org/upload");
[email protected]02cad5d2013-10-02 08:14:0310801 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1010802 request.traffic_annotation =
10803 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02cad5d2013-10-02 08:14:0310804
danakj1fd259a02016-04-16 03:17:0910805 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5810806 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1910807 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]02cad5d2013-10-02 08:14:0310808
10809 StaticSocketDataProvider data;
10810 session_deps_.socket_factory->AddSocketDataProvider(&data);
10811
10812 TestCompletionCallback callback;
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));
fdoray92e35a72016-06-10 15:54:5510815 base::RunLoop().RunUntilIdle();
[email protected]02cad5d2013-10-02 08:14:0310816
10817 // Transaction is pending on request body initialization.
Matt Menkecc1d3a902018-02-05 18:27:3310818 CompletionOnceCallback init_callback = fake_reader->TakeCallback();
10819 ASSERT_FALSE(init_callback.is_null());
[email protected]02cad5d2013-10-02 08:14:0310820
10821 // Return Init()'s result after the transaction gets destroyed.
10822 trans.reset();
Matt Menkecc1d3a902018-02-05 18:27:3310823 std::move(init_callback).Run(OK); // Should not crash.
[email protected]02cad5d2013-10-02 08:14:0310824}
10825
[email protected]aeefc9e82010-02-19 16:18:2710826// Tests that changes to Auth realms are treated like auth rejections.
bncd16676a2016-07-20 16:23:0110827TEST_F(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:2710828 HttpRequestInfo request;
10829 request.method = "GET";
bncce36dca22015-04-21 22:11:2310830 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010831 request.traffic_annotation =
10832 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]aeefc9e82010-02-19 16:18:2710833
10834 // First transaction will request a resource and receive a Basic challenge
10835 // with realm="first_realm".
10836 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2310837 MockWrite(
10838 "GET / HTTP/1.1\r\n"
10839 "Host: www.example.org\r\n"
10840 "Connection: keep-alive\r\n"
10841 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710842 };
10843 MockRead data_reads1[] = {
10844 MockRead("HTTP/1.1 401 Unauthorized\r\n"
10845 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
10846 "\r\n"),
10847 };
10848
bnc691fda62016-08-12 00:43:1610849 // After calling trans.RestartWithAuth(), provide an Authentication header
[email protected]aeefc9e82010-02-19 16:18:2710850 // for first_realm. The server will reject and provide a challenge with
10851 // second_realm.
10852 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:2310853 MockWrite(
10854 "GET / HTTP/1.1\r\n"
10855 "Host: www.example.org\r\n"
10856 "Connection: keep-alive\r\n"
10857 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
10858 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710859 };
10860 MockRead data_reads2[] = {
10861 MockRead("HTTP/1.1 401 Unauthorized\r\n"
10862 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
10863 "\r\n"),
10864 };
10865
10866 // This again fails, and goes back to first_realm. Make sure that the
10867 // entry is removed from cache.
10868 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:2310869 MockWrite(
10870 "GET / HTTP/1.1\r\n"
10871 "Host: www.example.org\r\n"
10872 "Connection: keep-alive\r\n"
10873 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
10874 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710875 };
10876 MockRead data_reads3[] = {
10877 MockRead("HTTP/1.1 401 Unauthorized\r\n"
10878 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
10879 "\r\n"),
10880 };
10881
10882 // Try one last time (with the correct password) and get the resource.
10883 MockWrite data_writes4[] = {
bncce36dca22015-04-21 22:11:2310884 MockWrite(
10885 "GET / HTTP/1.1\r\n"
10886 "Host: www.example.org\r\n"
10887 "Connection: keep-alive\r\n"
10888 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
10889 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710890 };
10891 MockRead data_reads4[] = {
10892 MockRead("HTTP/1.1 200 OK\r\n"
10893 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:5010894 "Content-Length: 5\r\n"
10895 "\r\n"
10896 "hello"),
[email protected]aeefc9e82010-02-19 16:18:2710897 };
10898
Ryan Sleevib8d7ea02018-05-07 20:01:0110899 StaticSocketDataProvider data1(data_reads1, data_writes1);
10900 StaticSocketDataProvider data2(data_reads2, data_writes2);
10901 StaticSocketDataProvider data3(data_reads3, data_writes3);
10902 StaticSocketDataProvider data4(data_reads4, data_writes4);
[email protected]bb88e1d32013-05-03 23:11:0710903 session_deps_.socket_factory->AddSocketDataProvider(&data1);
10904 session_deps_.socket_factory->AddSocketDataProvider(&data2);
10905 session_deps_.socket_factory->AddSocketDataProvider(&data3);
10906 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:2710907
[email protected]49639fa2011-12-20 23:22:4110908 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:2710909
danakj1fd259a02016-04-16 03:17:0910910 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610911 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5010912
[email protected]aeefc9e82010-02-19 16:18:2710913 // Issue the first request with Authorize headers. There should be a
10914 // password prompt for first_realm waiting to be filled in after the
10915 // transaction completes.
tfarina42834112016-09-22 13:38:2010916 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110917 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710918 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0110919 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610920 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210921 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410922 const AuthChallengeInfo* challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210923 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410924 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310925 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410926 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910927 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710928
10929 // Issue the second request with an incorrect password. There should be a
10930 // password prompt for second_realm waiting to be filled in after the
10931 // transaction completes.
[email protected]49639fa2011-12-20 23:22:4110932 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:1610933 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBaz),
10934 callback2.callback());
robpercival214763f2016-07-01 23:27:0110935 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710936 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0110937 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610938 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210939 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410940 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210941 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410942 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310943 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410944 EXPECT_EQ("second_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910945 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710946
10947 // Issue the third request with another incorrect password. There should be
10948 // a password prompt for first_realm waiting to be filled in. If the password
10949 // prompt is not present, it indicates that the HttpAuthCacheEntry for
10950 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:4110951 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:1610952 rv = trans.RestartWithAuth(AuthCredentials(kSecond, kFou),
10953 callback3.callback());
robpercival214763f2016-07-01 23:27:0110954 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710955 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:0110956 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610957 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210958 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410959 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210960 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410961 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310962 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410963 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910964 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710965
10966 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:4110967 TestCompletionCallback callback4;
bnc691fda62016-08-12 00:43:1610968 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBar),
10969 callback4.callback());
robpercival214763f2016-07-01 23:27:0110970 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710971 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:0110972 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610973 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210974 ASSERT_TRUE(response);
10975 EXPECT_FALSE(response->auth_challenge);
[email protected]aeefc9e82010-02-19 16:18:2710976}
10977
Bence Béky230ac612017-08-30 19:17:0810978// Regression test for https://crbug.com/754395.
10979TEST_F(HttpNetworkTransactionTest, IgnoreAltSvcWithInvalidCert) {
10980 MockRead data_reads[] = {
10981 MockRead("HTTP/1.1 200 OK\r\n"),
10982 MockRead(kAlternativeServiceHttpHeader),
10983 MockRead("\r\n"),
10984 MockRead("hello world"),
10985 MockRead(SYNCHRONOUS, OK),
10986 };
10987
10988 HttpRequestInfo request;
10989 request.method = "GET";
10990 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010991 request.traffic_annotation =
10992 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Béky230ac612017-08-30 19:17:0810993
Ryan Sleevib8d7ea02018-05-07 20:01:0110994 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
Bence Béky230ac612017-08-30 19:17:0810995 session_deps_.socket_factory->AddSocketDataProvider(&data);
10996
10997 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4910998 ssl.ssl_info.cert =
10999 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11000 ASSERT_TRUE(ssl.ssl_info.cert);
11001 ssl.ssl_info.cert_status = CERT_STATUS_COMMON_NAME_INVALID;
Bence Béky230ac612017-08-30 19:17:0811002 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11003
11004 TestCompletionCallback callback;
11005
11006 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11007 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11008
11009 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
11010 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11011
11012 url::SchemeHostPort test_server(request.url);
11013 HttpServerProperties* http_server_properties =
11014 session->http_server_properties();
11015 EXPECT_TRUE(
11016 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
11017
11018 EXPECT_THAT(callback.WaitForResult(), IsOk());
11019
11020 const HttpResponseInfo* response = trans.GetResponseInfo();
11021 ASSERT_TRUE(response);
11022 ASSERT_TRUE(response->headers);
11023 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11024 EXPECT_FALSE(response->was_fetched_via_spdy);
11025 EXPECT_FALSE(response->was_alpn_negotiated);
11026
11027 std::string response_data;
11028 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
11029 EXPECT_EQ("hello world", response_data);
11030
11031 EXPECT_TRUE(
11032 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
11033}
11034
bncd16676a2016-07-20 16:23:0111035TEST_F(HttpNetworkTransactionTest, HonorAlternativeServiceHeader) {
bncc958faa2015-07-31 18:14:5211036 MockRead data_reads[] = {
11037 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311038 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211039 MockRead("\r\n"),
11040 MockRead("hello world"),
11041 MockRead(SYNCHRONOUS, OK),
11042 };
11043
11044 HttpRequestInfo request;
11045 request.method = "GET";
bncb26024382016-06-29 02:39:4511046 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011047 request.traffic_annotation =
11048 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bncc958faa2015-07-31 18:14:5211049
Ryan Sleevib8d7ea02018-05-07 20:01:0111050 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:5211051 session_deps_.socket_factory->AddSocketDataProvider(&data);
11052
bncb26024382016-06-29 02:39:4511053 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911054 ssl.ssl_info.cert =
11055 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11056 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4511057 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11058
bncc958faa2015-07-31 18:14:5211059 TestCompletionCallback callback;
11060
danakj1fd259a02016-04-16 03:17:0911061 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611062 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5211063
tfarina42834112016-09-22 13:38:2011064 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111065 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5211066
bncb26024382016-06-29 02:39:4511067 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4011068 HttpServerProperties* http_server_properties =
11069 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3411070 EXPECT_TRUE(
11071 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5211072
robpercival214763f2016-07-01 23:27:0111073 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5211074
bnc691fda62016-08-12 00:43:1611075 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211076 ASSERT_TRUE(response);
11077 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5211078 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11079 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211080 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5211081
11082 std::string response_data;
bnc691fda62016-08-12 00:43:1611083 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5211084 EXPECT_EQ("hello world", response_data);
11085
zhongyic4de03032017-05-19 04:07:3411086 AlternativeServiceInfoVector alternative_service_info_vector =
11087 http_server_properties->GetAlternativeServiceInfos(test_server);
11088 ASSERT_EQ(1u, alternative_service_info_vector.size());
11089 AlternativeService alternative_service(kProtoHTTP2, "mail.example.org", 443);
11090 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5411091 alternative_service_info_vector[0].alternative_service());
bncc958faa2015-07-31 18:14:5211092}
11093
bnce3dd56f2016-06-01 10:37:1111094// Regression test for https://crbug.com/615497.
bncd16676a2016-07-20 16:23:0111095TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1111096 DoNotParseAlternativeServiceHeaderOnInsecureRequest) {
bnce3dd56f2016-06-01 10:37:1111097 MockRead data_reads[] = {
11098 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311099 MockRead(kAlternativeServiceHttpHeader),
bnce3dd56f2016-06-01 10:37:1111100 MockRead("\r\n"),
11101 MockRead("hello world"),
11102 MockRead(SYNCHRONOUS, OK),
11103 };
11104
11105 HttpRequestInfo request;
11106 request.method = "GET";
11107 request.url = GURL("http://www.example.org/");
11108 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1011109 request.traffic_annotation =
11110 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnce3dd56f2016-06-01 10:37:1111111
Ryan Sleevib8d7ea02018-05-07 20:01:0111112 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
bnce3dd56f2016-06-01 10:37:1111113 session_deps_.socket_factory->AddSocketDataProvider(&data);
11114
11115 TestCompletionCallback callback;
11116
11117 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611118 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1111119
11120 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4011121 HttpServerProperties* http_server_properties =
11122 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3411123 EXPECT_TRUE(
11124 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1111125
tfarina42834112016-09-22 13:38:2011126 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111127 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11128 EXPECT_THAT(callback.WaitForResult(), IsOk());
bnce3dd56f2016-06-01 10:37:1111129
bnc691fda62016-08-12 00:43:1611130 const HttpResponseInfo* response = trans.GetResponseInfo();
bnce3dd56f2016-06-01 10:37:1111131 ASSERT_TRUE(response);
11132 ASSERT_TRUE(response->headers);
11133 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11134 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211135 EXPECT_FALSE(response->was_alpn_negotiated);
bnce3dd56f2016-06-01 10:37:1111136
11137 std::string response_data;
bnc691fda62016-08-12 00:43:1611138 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnce3dd56f2016-06-01 10:37:1111139 EXPECT_EQ("hello world", response_data);
11140
zhongyic4de03032017-05-19 04:07:3411141 EXPECT_TRUE(
11142 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1111143}
11144
bnca86731e2017-04-17 12:31:2811145// HTTP/2 Alternative Services should be disabled by default.
bnc8bef8da22016-05-30 01:28:2511146// TODO(bnc): Remove when https://crbug.com/615413 is fixed.
bncd16676a2016-07-20 16:23:0111147TEST_F(HttpNetworkTransactionTest,
bnc8bef8da22016-05-30 01:28:2511148 DisableHTTP2AlternativeServicesWithDifferentHost) {
bnca86731e2017-04-17 12:31:2811149 session_deps_.enable_http2_alternative_service = false;
bncb26024382016-06-29 02:39:4511150
bnc8bef8da22016-05-30 01:28:2511151 HttpRequestInfo request;
11152 request.method = "GET";
bncb26024382016-06-29 02:39:4511153 request.url = GURL("https://www.example.org/");
bnc8bef8da22016-05-30 01:28:2511154 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1011155 request.traffic_annotation =
11156 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8bef8da22016-05-30 01:28:2511157
11158 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11159 StaticSocketDataProvider first_data;
11160 first_data.set_connect_data(mock_connect);
11161 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4511162 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611163 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511164 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
bnc8bef8da22016-05-30 01:28:2511165
11166 MockRead data_reads[] = {
11167 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
11168 MockRead(ASYNC, OK),
11169 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111170 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
bnc8bef8da22016-05-30 01:28:2511171 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
11172
11173 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11174
bnc525e175a2016-06-20 12:36:4011175 HttpServerProperties* http_server_properties =
bnc8bef8da22016-05-30 01:28:2511176 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2111177 AlternativeService alternative_service(kProtoHTTP2, "different.example.org",
11178 444);
bnc8bef8da22016-05-30 01:28:2511179 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111180 http_server_properties->SetHttp2AlternativeService(
bnc8bef8da22016-05-30 01:28:2511181 url::SchemeHostPort(request.url), alternative_service, expiration);
11182
bnc691fda62016-08-12 00:43:1611183 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc8bef8da22016-05-30 01:28:2511184 TestCompletionCallback callback;
11185
tfarina42834112016-09-22 13:38:2011186 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc8bef8da22016-05-30 01:28:2511187 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0111188 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc8bef8da22016-05-30 01:28:2511189}
11190
bnce3dd56f2016-06-01 10:37:1111191// Regression test for https://crbug.com/615497:
11192// Alternative Services should be disabled for http origin.
bncd16676a2016-07-20 16:23:0111193TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1111194 DisableAlternativeServicesForInsecureOrigin) {
bnce3dd56f2016-06-01 10:37:1111195 HttpRequestInfo request;
11196 request.method = "GET";
11197 request.url = GURL("http://www.example.org/");
11198 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1011199 request.traffic_annotation =
11200 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnce3dd56f2016-06-01 10:37:1111201
11202 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11203 StaticSocketDataProvider first_data;
11204 first_data.set_connect_data(mock_connect);
11205 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
11206
11207 MockRead data_reads[] = {
11208 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
11209 MockRead(ASYNC, OK),
11210 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111211 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
bnce3dd56f2016-06-01 10:37:1111212 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
11213
11214 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11215
bnc525e175a2016-06-20 12:36:4011216 HttpServerProperties* http_server_properties =
bnce3dd56f2016-06-01 10:37:1111217 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2111218 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnce3dd56f2016-06-01 10:37:1111219 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111220 http_server_properties->SetHttp2AlternativeService(
bnce3dd56f2016-06-01 10:37:1111221 url::SchemeHostPort(request.url), alternative_service, expiration);
11222
bnc691fda62016-08-12 00:43:1611223 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1111224 TestCompletionCallback callback;
11225
tfarina42834112016-09-22 13:38:2011226 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnce3dd56f2016-06-01 10:37:1111227 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0111228 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnce3dd56f2016-06-01 10:37:1111229}
11230
bncd16676a2016-07-20 16:23:0111231TEST_F(HttpNetworkTransactionTest, ClearAlternativeServices) {
bnc4f575852015-10-14 18:35:0811232 // Set an alternative service for origin.
danakj1fd259a02016-04-16 03:17:0911233 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4011234 HttpServerProperties* http_server_properties =
11235 session->http_server_properties();
bncb26024382016-06-29 02:39:4511236 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc3472afd2016-11-17 15:27:2111237 AlternativeService alternative_service(kProtoQUIC, "", 80);
bnc4f575852015-10-14 18:35:0811238 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111239 http_server_properties->SetQuicAlternativeService(
11240 test_server, alternative_service, expiration,
11241 session->params().quic_supported_versions);
zhongyic4de03032017-05-19 04:07:3411242 EXPECT_EQ(
11243 1u,
11244 http_server_properties->GetAlternativeServiceInfos(test_server).size());
bnc4f575852015-10-14 18:35:0811245
11246 // Send a clear header.
11247 MockRead data_reads[] = {
11248 MockRead("HTTP/1.1 200 OK\r\n"),
11249 MockRead("Alt-Svc: clear\r\n"),
11250 MockRead("\r\n"),
11251 MockRead("hello world"),
11252 MockRead(SYNCHRONOUS, OK),
11253 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111254 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
bnc4f575852015-10-14 18:35:0811255 session_deps_.socket_factory->AddSocketDataProvider(&data);
11256
bncb26024382016-06-29 02:39:4511257 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911258 ssl.ssl_info.cert =
11259 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11260 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4511261 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11262
bnc4f575852015-10-14 18:35:0811263 HttpRequestInfo request;
11264 request.method = "GET";
bncb26024382016-06-29 02:39:4511265 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011266 request.traffic_annotation =
11267 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc4f575852015-10-14 18:35:0811268
11269 TestCompletionCallback callback;
11270
bnc691fda62016-08-12 00:43:1611271 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc4f575852015-10-14 18:35:0811272
tfarina42834112016-09-22 13:38:2011273 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111274 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc4f575852015-10-14 18:35:0811275
bnc691fda62016-08-12 00:43:1611276 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211277 ASSERT_TRUE(response);
11278 ASSERT_TRUE(response->headers);
bnc4f575852015-10-14 18:35:0811279 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11280 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211281 EXPECT_FALSE(response->was_alpn_negotiated);
bnc4f575852015-10-14 18:35:0811282
11283 std::string response_data;
bnc691fda62016-08-12 00:43:1611284 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc4f575852015-10-14 18:35:0811285 EXPECT_EQ("hello world", response_data);
11286
zhongyic4de03032017-05-19 04:07:3411287 EXPECT_TRUE(
11288 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnc4f575852015-10-14 18:35:0811289}
11290
bncd16676a2016-07-20 16:23:0111291TEST_F(HttpNetworkTransactionTest, HonorMultipleAlternativeServiceHeaders) {
bncc958faa2015-07-31 18:14:5211292 MockRead data_reads[] = {
11293 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311294 MockRead("Alt-Svc: h2=\"www.example.com:443\","),
11295 MockRead("h2=\":1234\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:5211296 MockRead("hello world"),
11297 MockRead(SYNCHRONOUS, OK),
11298 };
11299
11300 HttpRequestInfo request;
11301 request.method = "GET";
bncb26024382016-06-29 02:39:4511302 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011303 request.traffic_annotation =
11304 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bncc958faa2015-07-31 18:14:5211305
Ryan Sleevib8d7ea02018-05-07 20:01:0111306 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:5211307 session_deps_.socket_factory->AddSocketDataProvider(&data);
11308
bncb26024382016-06-29 02:39:4511309 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911310 ssl.ssl_info.cert =
11311 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11312 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4511313 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11314
bncc958faa2015-07-31 18:14:5211315 TestCompletionCallback callback;
11316
danakj1fd259a02016-04-16 03:17:0911317 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611318 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5211319
tfarina42834112016-09-22 13:38:2011320 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111321 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5211322
bncb26024382016-06-29 02:39:4511323 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc525e175a2016-06-20 12:36:4011324 HttpServerProperties* http_server_properties =
11325 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3411326 EXPECT_TRUE(
11327 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5211328
robpercival214763f2016-07-01 23:27:0111329 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5211330
bnc691fda62016-08-12 00:43:1611331 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211332 ASSERT_TRUE(response);
11333 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5211334 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11335 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211336 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5211337
11338 std::string response_data;
bnc691fda62016-08-12 00:43:1611339 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5211340 EXPECT_EQ("hello world", response_data);
11341
zhongyic4de03032017-05-19 04:07:3411342 AlternativeServiceInfoVector alternative_service_info_vector =
11343 http_server_properties->GetAlternativeServiceInfos(test_server);
11344 ASSERT_EQ(2u, alternative_service_info_vector.size());
11345
11346 AlternativeService alternative_service(kProtoHTTP2, "www.example.com", 443);
11347 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5411348 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3411349 AlternativeService alternative_service_2(kProtoHTTP2, "www.example.org",
11350 1234);
11351 EXPECT_EQ(alternative_service_2,
zhongyi422ce352017-06-09 23:28:5411352 alternative_service_info_vector[1].alternative_service());
bncc958faa2015-07-31 18:14:5211353}
11354
bncd16676a2016-07-20 16:23:0111355TEST_F(HttpNetworkTransactionTest, IdentifyQuicBroken) {
zhongyi3d4a55e72016-04-22 20:36:4611356 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0211357 HostPortPair alternative("alternative.example.org", 443);
11358 std::string origin_url = "https://origin.example.org:443";
11359 std::string alternative_url = "https://alternative.example.org:443";
11360
11361 // Negotiate HTTP/1.1 with alternative.example.org.
11362 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611363 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0211364 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11365
11366 // HTTP/1.1 data for request.
11367 MockWrite http_writes[] = {
11368 MockWrite("GET / HTTP/1.1\r\n"
11369 "Host: alternative.example.org\r\n"
11370 "Connection: keep-alive\r\n\r\n"),
11371 };
11372
11373 MockRead http_reads[] = {
11374 MockRead("HTTP/1.1 200 OK\r\n"
11375 "Content-Type: text/html; charset=iso-8859-1\r\n"
11376 "Content-Length: 40\r\n\r\n"
11377 "first HTTP/1.1 response from alternative"),
11378 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111379 StaticSocketDataProvider http_data(http_reads, http_writes);
zhongyi48704c182015-12-07 07:52:0211380 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
11381
11382 StaticSocketDataProvider data_refused;
11383 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
11384 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
11385
zhongyi3d4a55e72016-04-22 20:36:4611386 // Set up a QUIC alternative service for server.
danakj1fd259a02016-04-16 03:17:0911387 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4011388 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0211389 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2111390 AlternativeService alternative_service(kProtoQUIC, alternative);
zhongyi48704c182015-12-07 07:52:0211391 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111392 http_server_properties->SetQuicAlternativeService(
11393 server, alternative_service, expiration,
11394 HttpNetworkSession::Params().quic_supported_versions);
zhongyi48704c182015-12-07 07:52:0211395 // Mark the QUIC alternative service as broken.
11396 http_server_properties->MarkAlternativeServiceBroken(alternative_service);
11397
zhongyi48704c182015-12-07 07:52:0211398 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4611399 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0211400 request.method = "GET";
11401 request.url = GURL(origin_url);
Ramin Halavatib5e433e62018-02-07 07:41:1011402 request.traffic_annotation =
11403 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
11404
zhongyi48704c182015-12-07 07:52:0211405 TestCompletionCallback callback;
11406 NetErrorDetails details;
11407 EXPECT_FALSE(details.quic_broken);
11408
tfarina42834112016-09-22 13:38:2011409 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1611410 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0211411 EXPECT_TRUE(details.quic_broken);
11412}
11413
bncd16676a2016-07-20 16:23:0111414TEST_F(HttpNetworkTransactionTest, IdentifyQuicNotBroken) {
zhongyi3d4a55e72016-04-22 20:36:4611415 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0211416 HostPortPair alternative1("alternative1.example.org", 443);
11417 HostPortPair alternative2("alternative2.example.org", 443);
11418 std::string origin_url = "https://origin.example.org:443";
11419 std::string alternative_url1 = "https://alternative1.example.org:443";
11420 std::string alternative_url2 = "https://alternative2.example.org:443";
11421
11422 // Negotiate HTTP/1.1 with alternative1.example.org.
11423 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611424 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0211425 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11426
11427 // HTTP/1.1 data for request.
11428 MockWrite http_writes[] = {
11429 MockWrite("GET / HTTP/1.1\r\n"
11430 "Host: alternative1.example.org\r\n"
11431 "Connection: keep-alive\r\n\r\n"),
11432 };
11433
11434 MockRead http_reads[] = {
11435 MockRead("HTTP/1.1 200 OK\r\n"
11436 "Content-Type: text/html; charset=iso-8859-1\r\n"
11437 "Content-Length: 40\r\n\r\n"
11438 "first HTTP/1.1 response from alternative1"),
11439 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111440 StaticSocketDataProvider http_data(http_reads, http_writes);
zhongyi48704c182015-12-07 07:52:0211441 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
11442
11443 StaticSocketDataProvider data_refused;
11444 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
11445 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
11446
danakj1fd259a02016-04-16 03:17:0911447 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4011448 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0211449 session->http_server_properties();
11450
zhongyi3d4a55e72016-04-22 20:36:4611451 // Set up two QUIC alternative services for server.
zhongyi48704c182015-12-07 07:52:0211452 AlternativeServiceInfoVector alternative_service_info_vector;
11453 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
11454
bnc3472afd2016-11-17 15:27:2111455 AlternativeService alternative_service1(kProtoQUIC, alternative1);
zhongyie537a002017-06-27 16:48:2111456 alternative_service_info_vector.push_back(
11457 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
11458 alternative_service1, expiration,
11459 session->params().quic_supported_versions));
bnc3472afd2016-11-17 15:27:2111460 AlternativeService alternative_service2(kProtoQUIC, alternative2);
zhongyie537a002017-06-27 16:48:2111461 alternative_service_info_vector.push_back(
11462 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
11463 alternative_service2, expiration,
11464 session->params().quic_supported_versions));
zhongyi48704c182015-12-07 07:52:0211465
11466 http_server_properties->SetAlternativeServices(
zhongyi3d4a55e72016-04-22 20:36:4611467 server, alternative_service_info_vector);
zhongyi48704c182015-12-07 07:52:0211468
11469 // Mark one of the QUIC alternative service as broken.
11470 http_server_properties->MarkAlternativeServiceBroken(alternative_service1);
zhongyic4de03032017-05-19 04:07:3411471 EXPECT_EQ(2u,
11472 http_server_properties->GetAlternativeServiceInfos(server).size());
zhongyi48704c182015-12-07 07:52:0211473
zhongyi48704c182015-12-07 07:52:0211474 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4611475 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0211476 request.method = "GET";
11477 request.url = GURL(origin_url);
Ramin Halavatib5e433e62018-02-07 07:41:1011478 request.traffic_annotation =
11479 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
11480
zhongyi48704c182015-12-07 07:52:0211481 TestCompletionCallback callback;
11482 NetErrorDetails details;
11483 EXPECT_FALSE(details.quic_broken);
11484
tfarina42834112016-09-22 13:38:2011485 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1611486 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0211487 EXPECT_FALSE(details.quic_broken);
11488}
11489
bncd16676a2016-07-20 16:23:0111490TEST_F(HttpNetworkTransactionTest, MarkBrokenAlternateProtocolAndFallback) {
[email protected]564b4912010-03-09 16:30:4211491 HttpRequestInfo request;
11492 request.method = "GET";
bncb26024382016-06-29 02:39:4511493 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011494 request.traffic_annotation =
11495 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]564b4912010-03-09 16:30:4211496
[email protected]d973e99a2012-02-17 21:02:3611497 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:4211498 StaticSocketDataProvider first_data;
11499 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711500 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4511501 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611502 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511503 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]564b4912010-03-09 16:30:4211504
11505 MockRead data_reads[] = {
11506 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11507 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611508 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:4211509 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111510 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711511 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:4211512
danakj1fd259a02016-04-16 03:17:0911513 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:4211514
bnc525e175a2016-06-20 12:36:4011515 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311516 session->http_server_properties();
zhongyi3d4a55e72016-04-22 20:36:4611517 const url::SchemeHostPort server(request.url);
[email protected]3912662a32011-10-04 00:51:1111518 // Port must be < 1024, or the header will be ignored (since initial port was
11519 // port 80 (another restricted port).
zhongyie537a002017-06-27 16:48:2111520 // Port is ignored by MockConnect anyway.
11521 const AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11522 666);
bnc7dc7e1b42015-07-28 14:43:1211523 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111524 http_server_properties->SetHttp2AlternativeService(
11525 server, alternative_service, expiration);
[email protected]564b4912010-03-09 16:30:4211526
bnc691fda62016-08-12 00:43:1611527 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111528 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:4211529
tfarina42834112016-09-22 13:38:2011530 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111531 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11532 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]564b4912010-03-09 16:30:4211533
bnc691fda62016-08-12 00:43:1611534 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211535 ASSERT_TRUE(response);
11536 ASSERT_TRUE(response->headers);
[email protected]564b4912010-03-09 16:30:4211537 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11538
11539 std::string response_data;
bnc691fda62016-08-12 00:43:1611540 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]564b4912010-03-09 16:30:4211541 EXPECT_EQ("hello world", response_data);
11542
zhongyic4de03032017-05-19 04:07:3411543 const AlternativeServiceInfoVector alternative_service_info_vector =
11544 http_server_properties->GetAlternativeServiceInfos(server);
11545 ASSERT_EQ(1u, alternative_service_info_vector.size());
11546 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5411547 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3411548 EXPECT_TRUE(
11549 http_server_properties->IsAlternativeServiceBroken(alternative_service));
[email protected]564b4912010-03-09 16:30:4211550}
11551
bnc55ff9da2015-08-19 18:42:3511552// Ensure that we are not allowed to redirect traffic via an alternate protocol
11553// to an unrestricted (port >= 1024) when the original traffic was on a
11554// restricted port (port < 1024). Ensure that we can redirect in all other
11555// cases.
bncd16676a2016-07-20 16:23:0111556TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:1111557 HttpRequestInfo restricted_port_request;
11558 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511559 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1111560 restricted_port_request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1011561 restricted_port_request.traffic_annotation =
11562 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1111563
[email protected]d973e99a2012-02-17 21:02:3611564 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111565 StaticSocketDataProvider first_data;
11566 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711567 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111568
11569 MockRead data_reads[] = {
11570 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11571 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611572 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111573 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111574 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711575 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4511576 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611577 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511578 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1111579
danakj1fd259a02016-04-16 03:17:0911580 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111581
bnc525e175a2016-06-20 12:36:4011582 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311583 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1111584 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2111585 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11586 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211587 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111588 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611589 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011590 expiration);
[email protected]3912662a32011-10-04 00:51:1111591
bnc691fda62016-08-12 00:43:1611592 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111593 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111594
tfarina42834112016-09-22 13:38:2011595 int rv = trans.Start(&restricted_port_request, callback.callback(),
11596 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111597 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111598 // Invalid change to unrestricted port should fail.
robpercival214763f2016-07-01 23:27:0111599 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_REFUSED));
[email protected]c54c6962013-02-01 04:53:1911600}
[email protected]3912662a32011-10-04 00:51:1111601
bnc55ff9da2015-08-19 18:42:3511602// Ensure that we are allowed to redirect traffic via an alternate protocol to
11603// an unrestricted (port >= 1024) when the original traffic was on a restricted
11604// port (port < 1024) if we set |enable_user_alternate_protocol_ports|.
bncd16676a2016-07-20 16:23:0111605TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedPermitted) {
[email protected]bb88e1d32013-05-03 23:11:0711606 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:1911607
11608 HttpRequestInfo restricted_port_request;
11609 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511610 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]c54c6962013-02-01 04:53:1911611 restricted_port_request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1011612 restricted_port_request.traffic_annotation =
11613 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]c54c6962013-02-01 04:53:1911614
11615 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11616 StaticSocketDataProvider first_data;
11617 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711618 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:1911619
11620 MockRead data_reads[] = {
11621 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11622 MockRead("hello world"),
11623 MockRead(ASYNC, OK),
11624 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111625 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711626 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4511627 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611628 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511629 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]c54c6962013-02-01 04:53:1911630
danakj1fd259a02016-04-16 03:17:0911631 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:1911632
bnc525e175a2016-06-20 12:36:4011633 HttpServerProperties* http_server_properties =
[email protected]c54c6962013-02-01 04:53:1911634 session->http_server_properties();
11635 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2111636 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11637 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211638 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111639 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611640 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011641 expiration);
[email protected]c54c6962013-02-01 04:53:1911642
bnc691fda62016-08-12 00:43:1611643 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]c54c6962013-02-01 04:53:1911644 TestCompletionCallback callback;
11645
tfarina42834112016-09-22 13:38:2011646 EXPECT_EQ(ERR_IO_PENDING,
11647 trans.Start(&restricted_port_request, callback.callback(),
11648 NetLogWithSource()));
[email protected]c54c6962013-02-01 04:53:1911649 // Change to unrestricted port should succeed.
robpercival214763f2016-07-01 23:27:0111650 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111651}
11652
bnc55ff9da2015-08-19 18:42:3511653// Ensure that we are not allowed to redirect traffic via an alternate protocol
11654// to an unrestricted (port >= 1024) when the original traffic was on a
11655// restricted port (port < 1024). Ensure that we can redirect in all other
11656// cases.
bncd16676a2016-07-20 16:23:0111657TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:1111658 HttpRequestInfo restricted_port_request;
11659 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511660 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1111661 restricted_port_request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1011662 restricted_port_request.traffic_annotation =
11663 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1111664
[email protected]d973e99a2012-02-17 21:02:3611665 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111666 StaticSocketDataProvider first_data;
11667 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711668 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111669
11670 MockRead data_reads[] = {
11671 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11672 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611673 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111674 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111675 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711676 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1111677
bncb26024382016-06-29 02:39:4511678 SSLSocketDataProvider ssl(ASYNC, OK);
11679 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11680
danakj1fd259a02016-04-16 03:17:0911681 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111682
bnc525e175a2016-06-20 12:36:4011683 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311684 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1111685 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2111686 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11687 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211688 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111689 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611690 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011691 expiration);
[email protected]3912662a32011-10-04 00:51:1111692
bnc691fda62016-08-12 00:43:1611693 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111694 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111695
tfarina42834112016-09-22 13:38:2011696 int rv = trans.Start(&restricted_port_request, callback.callback(),
11697 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111698 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111699 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0111700 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111701}
11702
bnc55ff9da2015-08-19 18:42:3511703// Ensure that we are not allowed to redirect traffic via an alternate protocol
11704// to an unrestricted (port >= 1024) when the original traffic was on a
11705// restricted port (port < 1024). Ensure that we can redirect in all other
11706// cases.
bncd16676a2016-07-20 16:23:0111707TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:1111708 HttpRequestInfo unrestricted_port_request;
11709 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511710 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1111711 unrestricted_port_request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1011712 unrestricted_port_request.traffic_annotation =
11713 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1111714
[email protected]d973e99a2012-02-17 21:02:3611715 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111716 StaticSocketDataProvider first_data;
11717 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711718 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111719
11720 MockRead data_reads[] = {
11721 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11722 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611723 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111724 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111725 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711726 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4511727 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611728 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511729 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1111730
danakj1fd259a02016-04-16 03:17:0911731 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111732
bnc525e175a2016-06-20 12:36:4011733 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311734 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1111735 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2111736 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11737 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211738 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111739 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611740 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011741 expiration);
[email protected]3912662a32011-10-04 00:51:1111742
bnc691fda62016-08-12 00:43:1611743 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111744 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111745
bnc691fda62016-08-12 00:43:1611746 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2011747 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111748 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111749 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0111750 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111751}
11752
bnc55ff9da2015-08-19 18:42:3511753// Ensure that we are not allowed to redirect traffic via an alternate protocol
11754// to an unrestricted (port >= 1024) when the original traffic was on a
11755// restricted port (port < 1024). Ensure that we can redirect in all other
11756// cases.
bncd16676a2016-07-20 16:23:0111757TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:1111758 HttpRequestInfo unrestricted_port_request;
11759 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511760 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1111761 unrestricted_port_request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1011762 unrestricted_port_request.traffic_annotation =
11763 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1111764
[email protected]d973e99a2012-02-17 21:02:3611765 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111766 StaticSocketDataProvider first_data;
11767 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711768 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111769
11770 MockRead data_reads[] = {
11771 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11772 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611773 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111774 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111775 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711776 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1111777
bncb26024382016-06-29 02:39:4511778 SSLSocketDataProvider ssl(ASYNC, OK);
11779 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11780
danakj1fd259a02016-04-16 03:17:0911781 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111782
bnc525e175a2016-06-20 12:36:4011783 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311784 session->http_server_properties();
bnc0bbb02622015-07-23 10:06:2211785 const int kUnrestrictedAlternatePort = 1025;
bnc3472afd2016-11-17 15:27:2111786 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11787 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211788 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111789 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611790 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011791 expiration);
[email protected]3912662a32011-10-04 00:51:1111792
bnc691fda62016-08-12 00:43:1611793 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111794 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111795
bnc691fda62016-08-12 00:43:1611796 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2011797 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111798 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111799 // Valid change to an unrestricted port should pass.
robpercival214763f2016-07-01 23:27:0111800 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111801}
11802
bnc55ff9da2015-08-19 18:42:3511803// Ensure that we are not allowed to redirect traffic via an alternate protocol
Xida Chen9bfe0b62018-04-24 19:52:2111804// to an unsafe port, and that we resume the second HttpStreamFactory::Job once
11805// the alternate protocol request fails.
bncd16676a2016-07-20 16:23:0111806TEST_F(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:0211807 HttpRequestInfo request;
11808 request.method = "GET";
bncce36dca22015-04-21 22:11:2311809 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011810 request.traffic_annotation =
11811 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]eb6234e2012-01-19 01:50:0211812
11813 // The alternate protocol request will error out before we attempt to connect,
11814 // so only the standard HTTP request will try to connect.
11815 MockRead data_reads[] = {
11816 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11817 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611818 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:0211819 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111820 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711821 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:0211822
danakj1fd259a02016-04-16 03:17:0911823 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:0211824
bnc525e175a2016-06-20 12:36:4011825 HttpServerProperties* http_server_properties =
[email protected]eb6234e2012-01-19 01:50:0211826 session->http_server_properties();
11827 const int kUnsafePort = 7;
bnc3472afd2016-11-17 15:27:2111828 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11829 kUnsafePort);
bnc7dc7e1b42015-07-28 14:43:1211830 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111831 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611832 url::SchemeHostPort(request.url), alternative_service, expiration);
[email protected]eb6234e2012-01-19 01:50:0211833
bnc691fda62016-08-12 00:43:1611834 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]eb6234e2012-01-19 01:50:0211835 TestCompletionCallback callback;
11836
tfarina42834112016-09-22 13:38:2011837 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111838 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]eb6234e2012-01-19 01:50:0211839 // The HTTP request should succeed.
robpercival214763f2016-07-01 23:27:0111840 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb6234e2012-01-19 01:50:0211841
bnc691fda62016-08-12 00:43:1611842 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211843 ASSERT_TRUE(response);
11844 ASSERT_TRUE(response->headers);
[email protected]eb6234e2012-01-19 01:50:0211845 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11846
11847 std::string response_data;
bnc691fda62016-08-12 00:43:1611848 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]eb6234e2012-01-19 01:50:0211849 EXPECT_EQ("hello world", response_data);
11850}
11851
bncd16676a2016-07-20 16:23:0111852TEST_F(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]2ff8b312010-04-26 22:20:5411853 HttpRequestInfo request;
11854 request.method = "GET";
bncb26024382016-06-29 02:39:4511855 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011856 request.traffic_annotation =
11857 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2ff8b312010-04-26 22:20:5411858
11859 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211860 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311861 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211862 MockRead("\r\n"),
11863 MockRead("hello world"),
11864 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11865 MockRead(ASYNC, OK)};
[email protected]2ff8b312010-04-26 22:20:5411866
Ryan Sleevib8d7ea02018-05-07 20:01:0111867 StaticSocketDataProvider first_transaction(data_reads,
11868 base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711869 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4511870 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611871 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511872 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5411873
bnc032658ba2016-09-26 18:17:1511874 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5411875
Ryan Hamilton0239aac2018-05-19 00:03:1311876 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4511877 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4111878 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5411879
Ryan Hamilton0239aac2018-05-19 00:03:1311880 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
11881 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5411882 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111883 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5411884 };
11885
Ryan Sleevib8d7ea02018-05-07 20:01:0111886 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0711887 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5411888
[email protected]d973e99a2012-02-17 21:02:3611889 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0111890 StaticSocketDataProvider hanging_non_alternate_protocol_socket;
[email protected]2d6728692011-03-12 01:39:5511891 hanging_non_alternate_protocol_socket.set_connect_data(
11892 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0711893 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511894 &hanging_non_alternate_protocol_socket);
11895
[email protected]49639fa2011-12-20 23:22:4111896 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5411897
danakj1fd259a02016-04-16 03:17:0911898 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5811899 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1911900 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5411901
tfarina42834112016-09-22 13:38:2011902 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111903 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11904 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411905
11906 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211907 ASSERT_TRUE(response);
11908 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5411909 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11910
11911 std::string response_data;
robpercival214763f2016-07-01 23:27:0111912 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411913 EXPECT_EQ("hello world", response_data);
11914
bnc87dcefc2017-05-25 12:47:5811915 trans =
Jeremy Roman0579ed62017-08-29 15:56:1911916 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5411917
tfarina42834112016-09-22 13:38:2011918 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111919 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11920 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411921
11922 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211923 ASSERT_TRUE(response);
11924 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211925 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5311926 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211927 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5411928
robpercival214763f2016-07-01 23:27:0111929 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411930 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:5411931}
11932
bncd16676a2016-07-20 16:23:0111933TEST_F(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]2d6728692011-03-12 01:39:5511934 HttpRequestInfo request;
11935 request.method = "GET";
bncb26024382016-06-29 02:39:4511936 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011937 request.traffic_annotation =
11938 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d6728692011-03-12 01:39:5511939
bncb26024382016-06-29 02:39:4511940 // First transaction receives Alt-Svc header over HTTP/1.1.
[email protected]2d6728692011-03-12 01:39:5511941 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211942 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311943 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211944 MockRead("\r\n"),
11945 MockRead("hello world"),
11946 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11947 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5511948 };
11949
Ryan Sleevib8d7ea02018-05-07 20:01:0111950 StaticSocketDataProvider http11_data(data_reads, base::span<MockWrite>());
bncb26024382016-06-29 02:39:4511951 session_deps_.socket_factory->AddSocketDataProvider(&http11_data);
[email protected]2d6728692011-03-12 01:39:5511952
bncb26024382016-06-29 02:39:4511953 SSLSocketDataProvider ssl_http11(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911954 ssl_http11.ssl_info.cert =
11955 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11956 ASSERT_TRUE(ssl_http11.ssl_info.cert);
bncb26024382016-06-29 02:39:4511957 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
11958
11959 // Second transaction starts an alternative and a non-alternative Job.
11960 // Both sockets hang.
[email protected]d973e99a2012-02-17 21:02:3611961 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0111962 StaticSocketDataProvider hanging_socket1;
mmenkecc2298e2015-12-07 18:20:1811963 hanging_socket1.set_connect_data(never_finishing_connect);
mmenkecc2298e2015-12-07 18:20:1811964 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket1);
11965
Ryan Sleevib8d7ea02018-05-07 20:01:0111966 StaticSocketDataProvider hanging_socket2;
mmenkecc2298e2015-12-07 18:20:1811967 hanging_socket2.set_connect_data(never_finishing_connect);
11968 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket2);
[email protected]2d6728692011-03-12 01:39:5511969
bncb26024382016-06-29 02:39:4511970 // Third transaction starts an alternative and a non-alternative job.
11971 // The non-alternative job hangs, but the alternative one succeeds.
11972 // The second transaction, still pending, binds to this socket.
Ryan Hamilton0239aac2018-05-19 00:03:1311973 spdy::SpdySerializedFrame req1(
bncb26024382016-06-29 02:39:4511974 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1311975 spdy::SpdySerializedFrame req2(
bncb26024382016-06-29 02:39:4511976 spdy_util_.ConstructSpdyGet("https://www.example.org/", 3, LOWEST));
[email protected]2d6728692011-03-12 01:39:5511977 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4111978 CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
[email protected]2d6728692011-03-12 01:39:5511979 };
Ryan Hamilton0239aac2018-05-19 00:03:1311980 spdy::SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
11981 spdy::SpdySerializedFrame data1(spdy_util_.ConstructSpdyDataFrame(1, true));
11982 spdy::SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
11983 spdy::SpdySerializedFrame data2(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]2d6728692011-03-12 01:39:5511984 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111985 CreateMockRead(resp1, 2), CreateMockRead(data1, 3),
11986 CreateMockRead(resp2, 4), CreateMockRead(data2, 5),
rch8e6c6c42015-05-01 14:05:1311987 MockRead(ASYNC, 0, 6),
[email protected]2d6728692011-03-12 01:39:5511988 };
11989
Ryan Sleevib8d7ea02018-05-07 20:01:0111990 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0711991 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:5511992
bnc032658ba2016-09-26 18:17:1511993 AddSSLSocketData();
bncb26024382016-06-29 02:39:4511994
Ryan Sleevib8d7ea02018-05-07 20:01:0111995 StaticSocketDataProvider hanging_socket3;
mmenkecc2298e2015-12-07 18:20:1811996 hanging_socket3.set_connect_data(never_finishing_connect);
11997 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket3);
[email protected]2d6728692011-03-12 01:39:5511998
danakj1fd259a02016-04-16 03:17:0911999 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:4112000 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:5012001 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5512002
tfarina42834112016-09-22 13:38:2012003 int rv = trans1.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112004 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12005 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512006
12007 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5212008 ASSERT_TRUE(response);
12009 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5512010 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12011
12012 std::string response_data;
robpercival214763f2016-07-01 23:27:0112013 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512014 EXPECT_EQ("hello world", response_data);
12015
[email protected]49639fa2011-12-20 23:22:4112016 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:5012017 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2012018 rv = trans2.Start(&request, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112019 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5512020
[email protected]49639fa2011-12-20 23:22:4112021 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:5012022 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2012023 rv = trans3.Start(&request, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112024 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5512025
robpercival214763f2016-07-01 23:27:0112026 EXPECT_THAT(callback2.WaitForResult(), IsOk());
12027 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512028
12029 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5212030 ASSERT_TRUE(response);
12031 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212032 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5512033 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212034 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0112035 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512036 EXPECT_EQ("hello!", response_data);
12037
12038 response = trans3.GetResponseInfo();
wezca1070932016-05-26 20:30:5212039 ASSERT_TRUE(response);
12040 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212041 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5512042 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212043 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0112044 ASSERT_THAT(ReadTransaction(&trans3, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512045 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:5512046}
12047
bncd16676a2016-07-20 16:23:0112048TEST_F(HttpNetworkTransactionTest, StallAlternativeServiceForNpnSpdy) {
[email protected]2d6728692011-03-12 01:39:5512049 HttpRequestInfo request;
12050 request.method = "GET";
bncb26024382016-06-29 02:39:4512051 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1012052 request.traffic_annotation =
12053 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d6728692011-03-12 01:39:5512054
12055 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212056 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312057 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212058 MockRead("\r\n"),
12059 MockRead("hello world"),
12060 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
12061 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5512062 };
12063
Ryan Sleevib8d7ea02018-05-07 20:01:0112064 StaticSocketDataProvider first_transaction(data_reads,
12065 base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712066 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:5512067
[email protected]8ddf8322012-02-23 18:08:0612068 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4912069 ssl.ssl_info.cert =
12070 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
12071 ASSERT_TRUE(ssl.ssl_info.cert);
[email protected]bb88e1d32013-05-03 23:11:0712072 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5512073
[email protected]d973e99a2012-02-17 21:02:3612074 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0112075 StaticSocketDataProvider hanging_alternate_protocol_socket;
[email protected]2d6728692011-03-12 01:39:5512076 hanging_alternate_protocol_socket.set_connect_data(
12077 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0712078 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5512079 &hanging_alternate_protocol_socket);
12080
bncb26024382016-06-29 02:39:4512081 // 2nd request is just a copy of the first one, over HTTP/1.1 again.
Ryan Sleevib8d7ea02018-05-07 20:01:0112082 StaticSocketDataProvider second_transaction(data_reads,
12083 base::span<MockWrite>());
mmenkecc2298e2015-12-07 18:20:1812084 session_deps_.socket_factory->AddSocketDataProvider(&second_transaction);
bncb26024382016-06-29 02:39:4512085 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5512086
[email protected]49639fa2011-12-20 23:22:4112087 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:5512088
danakj1fd259a02016-04-16 03:17:0912089 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5812090 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1912091 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5512092
tfarina42834112016-09-22 13:38:2012093 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112094 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12095 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512096
12097 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212098 ASSERT_TRUE(response);
12099 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5512100 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12101
12102 std::string response_data;
robpercival214763f2016-07-01 23:27:0112103 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512104 EXPECT_EQ("hello world", response_data);
12105
bnc87dcefc2017-05-25 12:47:5812106 trans =
Jeremy Roman0579ed62017-08-29 15:56:1912107 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5512108
tfarina42834112016-09-22 13:38:2012109 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112110 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12111 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512112
12113 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212114 ASSERT_TRUE(response);
12115 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5512116 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12117 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212118 EXPECT_FALSE(response->was_alpn_negotiated);
[email protected]2d6728692011-03-12 01:39:5512119
robpercival214763f2016-07-01 23:27:0112120 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512121 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:5512122}
12123
[email protected]631f1322010-04-30 17:59:1112124class CapturingProxyResolver : public ProxyResolver {
12125 public:
Chris Watkins7a41d3552017-12-01 02:13:2712126 CapturingProxyResolver() = default;
12127 ~CapturingProxyResolver() override = default;
[email protected]631f1322010-04-30 17:59:1112128
dchengb03027d2014-10-21 12:00:2012129 int GetProxyForURL(const GURL& url,
12130 ProxyInfo* results,
Bence Békycc5b88a2018-05-25 20:24:1712131 CompletionOnceCallback callback,
maksim.sisov7e157262016-10-20 11:19:5512132 std::unique_ptr<Request>* request,
tfarina42834112016-09-22 13:38:2012133 const NetLogWithSource& net_log) override {
[email protected]fae7669f2010-08-02 21:49:4012134 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
12135 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:4212136 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:1112137 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:4212138 return OK;
[email protected]631f1322010-04-30 17:59:1112139 }
12140
[email protected]24476402010-07-20 20:55:1712141 const std::vector<GURL>& resolved() const { return resolved_; }
12142
12143 private:
[email protected]631f1322010-04-30 17:59:1112144 std::vector<GURL> resolved_;
12145
12146 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
12147};
12148
sammce64b2362015-04-29 03:50:2312149class CapturingProxyResolverFactory : public ProxyResolverFactory {
12150 public:
12151 explicit CapturingProxyResolverFactory(CapturingProxyResolver* resolver)
12152 : ProxyResolverFactory(false), resolver_(resolver) {}
12153
Lily Houghton99597862018-03-07 16:40:4212154 int CreateProxyResolver(const scoped_refptr<PacFileData>& pac_script,
12155 std::unique_ptr<ProxyResolver>* resolver,
Bence Békycc5b88a2018-05-25 20:24:1712156 CompletionOnceCallback callback,
Lily Houghton99597862018-03-07 16:40:4212157 std::unique_ptr<Request>* request) override {
Jeremy Roman0579ed62017-08-29 15:56:1912158 *resolver = std::make_unique<ForwardingProxyResolver>(resolver_);
sammce64b2362015-04-29 03:50:2312159 return OK;
12160 }
12161
12162 private:
12163 ProxyResolver* resolver_;
12164};
12165
bnc2e884782016-08-11 19:45:1912166// Test that proxy is resolved using the origin url,
12167// regardless of the alternative server.
12168TEST_F(HttpNetworkTransactionTest, UseOriginNotAlternativeForProxy) {
12169 // Configure proxy to bypass www.example.org, which is the origin URL.
12170 ProxyConfig proxy_config;
12171 proxy_config.proxy_rules().ParseFromString("myproxy:70");
12172 proxy_config.proxy_rules().bypass_rules.AddRuleFromString("www.example.org");
Ramin Halavatica8d5252018-03-12 05:33:4912173 auto proxy_config_service = std::make_unique<ProxyConfigServiceFixed>(
12174 ProxyConfigWithAnnotation(proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS));
bnc2e884782016-08-11 19:45:1912175
12176 CapturingProxyResolver capturing_proxy_resolver;
Jeremy Roman0579ed62017-08-29 15:56:1912177 auto proxy_resolver_factory = std::make_unique<CapturingProxyResolverFactory>(
bnc2e884782016-08-11 19:45:1912178 &capturing_proxy_resolver);
12179
12180 TestNetLog net_log;
12181
Bence Béky53a5aef2018-03-29 21:54:1212182 session_deps_.proxy_resolution_service =
12183 std::make_unique<ProxyResolutionService>(
12184 std::move(proxy_config_service), std::move(proxy_resolver_factory),
12185 &net_log);
bnc2e884782016-08-11 19:45:1912186
12187 session_deps_.net_log = &net_log;
12188
12189 // Configure alternative service with a hostname that is not bypassed by the
12190 // proxy.
12191 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12192 HttpServerProperties* http_server_properties =
12193 session->http_server_properties();
12194 url::SchemeHostPort server("https", "www.example.org", 443);
12195 HostPortPair alternative("www.example.com", 443);
bnc3472afd2016-11-17 15:27:2112196 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc2e884782016-08-11 19:45:1912197 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112198 http_server_properties->SetHttp2AlternativeService(
12199 server, alternative_service, expiration);
bnc2e884782016-08-11 19:45:1912200
12201 // Non-alternative job should hang.
12202 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0112203 StaticSocketDataProvider hanging_alternate_protocol_socket;
bnc2e884782016-08-11 19:45:1912204 hanging_alternate_protocol_socket.set_connect_data(never_finishing_connect);
12205 session_deps_.socket_factory->AddSocketDataProvider(
12206 &hanging_alternate_protocol_socket);
12207
bnc032658ba2016-09-26 18:17:1512208 AddSSLSocketData();
bnc2e884782016-08-11 19:45:1912209
12210 HttpRequestInfo request;
12211 request.method = "GET";
12212 request.url = GURL("https://www.example.org/");
12213 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1012214 request.traffic_annotation =
12215 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc2e884782016-08-11 19:45:1912216
Ryan Hamilton0239aac2018-05-19 00:03:1312217 spdy::SpdySerializedFrame req(
bnc2e884782016-08-11 19:45:1912218 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
12219
12220 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
12221
Ryan Hamilton0239aac2018-05-19 00:03:1312222 spdy::SpdySerializedFrame resp(
12223 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
12224 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
bnc2e884782016-08-11 19:45:1912225 MockRead spdy_reads[] = {
12226 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
12227 };
12228
Ryan Sleevib8d7ea02018-05-07 20:01:0112229 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
bnc2e884782016-08-11 19:45:1912230 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
12231
12232 TestCompletionCallback callback;
12233
12234 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
12235
tfarina42834112016-09-22 13:38:2012236 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc2e884782016-08-11 19:45:1912237 EXPECT_THAT(callback.GetResult(rv), IsOk());
12238
12239 const HttpResponseInfo* response = trans.GetResponseInfo();
12240 ASSERT_TRUE(response);
12241 ASSERT_TRUE(response->headers);
12242 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
12243 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212244 EXPECT_TRUE(response->was_alpn_negotiated);
bnc2e884782016-08-11 19:45:1912245
12246 std::string response_data;
12247 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
12248 EXPECT_EQ("hello!", response_data);
12249
12250 // Origin host bypasses proxy, no resolution should have happened.
12251 ASSERT_TRUE(capturing_proxy_resolver.resolved().empty());
12252}
12253
bncd16676a2016-07-20 16:23:0112254TEST_F(HttpNetworkTransactionTest, UseAlternativeServiceForTunneledNpnSpdy) {
[email protected]631f1322010-04-30 17:59:1112255 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:4212256 proxy_config.set_auto_detect(true);
12257 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:1112258
sammc5dd160c2015-04-02 02:43:1312259 CapturingProxyResolver capturing_proxy_resolver;
Ramin Halavatica8d5252018-03-12 05:33:4912260 session_deps_.proxy_resolution_service =
12261 std::make_unique<ProxyResolutionService>(
12262 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
12263 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
12264 std::make_unique<CapturingProxyResolverFactory>(
12265 &capturing_proxy_resolver),
12266 nullptr);
vishal.b62985ca92015-04-17 08:45:5112267 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0712268 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:1112269
12270 HttpRequestInfo request;
12271 request.method = "GET";
bncb26024382016-06-29 02:39:4512272 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1012273 request.traffic_annotation =
12274 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]631f1322010-04-30 17:59:1112275
12276 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212277 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312278 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212279 MockRead("\r\n"),
12280 MockRead("hello world"),
12281 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
12282 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:1112283 };
12284
Ryan Sleevib8d7ea02018-05-07 20:01:0112285 StaticSocketDataProvider first_transaction(data_reads,
12286 base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712287 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4512288 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612289 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512290 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]631f1322010-04-30 17:59:1112291
bnc032658ba2016-09-26 18:17:1512292 AddSSLSocketData();
[email protected]631f1322010-04-30 17:59:1112293
Ryan Hamilton0239aac2018-05-19 00:03:1312294 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4512295 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
[email protected]631f1322010-04-30 17:59:1112296 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1312297 MockWrite(ASYNC, 0,
bnc8bef8da22016-05-30 01:28:2512298 "CONNECT www.example.org:443 HTTP/1.1\r\n"
12299 "Host: www.example.org:443\r\n"
rch8e6c6c42015-05-01 14:05:1312300 "Proxy-Connection: keep-alive\r\n\r\n"),
bncdf80d44fd2016-07-15 20:27:4112301 CreateMockWrite(req, 2),
[email protected]631f1322010-04-30 17:59:1112302 };
12303
[email protected]d911f1b2010-05-05 22:39:4212304 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
12305
Ryan Hamilton0239aac2018-05-19 00:03:1312306 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
12307 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]631f1322010-04-30 17:59:1112308 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4112309 MockRead(ASYNC, 1, kCONNECTResponse), CreateMockRead(resp, 3),
12310 CreateMockRead(data, 4), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5),
[email protected]631f1322010-04-30 17:59:1112311 };
12312
Ryan Sleevib8d7ea02018-05-07 20:01:0112313 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0712314 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:1112315
[email protected]d973e99a2012-02-17 21:02:3612316 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0112317 StaticSocketDataProvider hanging_non_alternate_protocol_socket;
[email protected]2d6728692011-03-12 01:39:5512318 hanging_non_alternate_protocol_socket.set_connect_data(
12319 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0712320 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5512321 &hanging_non_alternate_protocol_socket);
12322
[email protected]49639fa2011-12-20 23:22:4112323 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:1112324
danakj1fd259a02016-04-16 03:17:0912325 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5812326 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1912327 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1112328
tfarina42834112016-09-22 13:38:2012329 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea2dcd3bf2016-08-16 21:49:4112330 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12331 EXPECT_THAT(callback.WaitForResult(), IsOk());
12332
12333 const HttpResponseInfo* response = trans->GetResponseInfo();
12334 ASSERT_TRUE(response);
12335 ASSERT_TRUE(response->headers);
12336 EXPECT_EQ("HTTP/0.9 200 OK", response->headers->GetStatusLine());
12337 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212338 EXPECT_TRUE(response->was_alpn_negotiated);
mmenkea2dcd3bf2016-08-16 21:49:4112339
12340 std::string response_data;
12341 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
12342 EXPECT_EQ("hello world", response_data);
[email protected]631f1322010-04-30 17:59:1112343
bnc87dcefc2017-05-25 12:47:5812344 trans =
Jeremy Roman0579ed62017-08-29 15:56:1912345 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1112346
tfarina42834112016-09-22 13:38:2012347 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112348 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12349 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]631f1322010-04-30 17:59:1112350
mmenkea2dcd3bf2016-08-16 21:49:4112351 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212352 ASSERT_TRUE(response);
12353 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212354 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5312355 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212356 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]631f1322010-04-30 17:59:1112357
robpercival214763f2016-07-01 23:27:0112358 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]631f1322010-04-30 17:59:1112359 EXPECT_EQ("hello!", response_data);
bncb26024382016-06-29 02:39:4512360 ASSERT_EQ(2u, capturing_proxy_resolver.resolved().size());
12361 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1312362 capturing_proxy_resolver.resolved()[0].spec());
bncce36dca22015-04-21 22:11:2312363 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1312364 capturing_proxy_resolver.resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:1112365
[email protected]029c83b62013-01-24 05:28:2012366 LoadTimingInfo load_timing_info;
12367 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
12368 TestLoadTimingNotReusedWithPac(load_timing_info,
12369 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:1112370}
[email protected]631f1322010-04-30 17:59:1112371
bncd16676a2016-07-20 16:23:0112372TEST_F(HttpNetworkTransactionTest,
bnc1c196c6e2016-05-28 13:51:4812373 UseAlternativeServiceForNpnSpdyWithExistingSpdySession) {
[email protected]2ff8b312010-04-26 22:20:5412374 HttpRequestInfo request;
12375 request.method = "GET";
bncb26024382016-06-29 02:39:4512376 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1012377 request.traffic_annotation =
12378 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2ff8b312010-04-26 22:20:5412379
12380 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212381 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312382 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212383 MockRead("\r\n"),
12384 MockRead("hello world"),
12385 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:5412386 };
12387
Ryan Sleevib8d7ea02018-05-07 20:01:0112388 StaticSocketDataProvider first_transaction(data_reads,
12389 base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712390 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4512391 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612392 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512393 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5412394
bnc032658ba2016-09-26 18:17:1512395 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5412396
Ryan Hamilton0239aac2018-05-19 00:03:1312397 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4512398 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4112399 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5412400
Ryan Hamilton0239aac2018-05-19 00:03:1312401 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
12402 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5412403 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4112404 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5412405 };
12406
Ryan Sleevib8d7ea02018-05-07 20:01:0112407 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0712408 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5412409
[email protected]83039bb2011-12-09 18:43:5512410 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5412411
danakj1fd259a02016-04-16 03:17:0912412 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:5412413
bnc87dcefc2017-05-25 12:47:5812414 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1912415 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5412416
tfarina42834112016-09-22 13:38:2012417 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112418 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12419 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412420
12421 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212422 ASSERT_TRUE(response);
12423 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5412424 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12425
12426 std::string response_data;
robpercival214763f2016-07-01 23:27:0112427 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412428 EXPECT_EQ("hello world", response_data);
12429
12430 // Set up an initial SpdySession in the pool to reuse.
bnc8bef8da22016-05-30 01:28:2512431 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4012432 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
Paul Jensena457017a2018-01-19 23:52:0412433 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]795cbf82013-07-22 09:37:2712434 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:5212435 CreateSpdySession(session.get(), key, NetLogWithSource());
[email protected]02b0c342010-09-25 21:09:3812436
bnc87dcefc2017-05-25 12:47:5812437 trans =
Jeremy Roman0579ed62017-08-29 15:56:1912438 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5412439
tfarina42834112016-09-22 13:38:2012440 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112441 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12442 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412443
12444 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212445 ASSERT_TRUE(response);
12446 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212447 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5312448 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212449 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5412450
robpercival214763f2016-07-01 23:27:0112451 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412452 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:4212453}
12454
[email protected]044de0642010-06-17 10:42:1512455// GenerateAuthToken is a mighty big test.
12456// It tests all permutation of GenerateAuthToken behavior:
12457// - Synchronous and Asynchronous completion.
12458// - OK or error on completion.
12459// - Direct connection, non-authenticating proxy, and authenticating proxy.
12460// - HTTP or HTTPS backend (to include proxy tunneling).
12461// - Non-authenticating and authenticating backend.
12462//
[email protected]fe3b7dc2012-02-03 19:52:0912463// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:1512464// problems generating an auth token for an authenticating proxy, we don't
12465// need to test all permutations of the backend server).
12466//
12467// The test proceeds by going over each of the configuration cases, and
12468// potentially running up to three rounds in each of the tests. The TestConfig
12469// specifies both the configuration for the test as well as the expectations
12470// for the results.
bncd16676a2016-07-20 16:23:0112471TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:5012472 static const char kServer[] = "http://www.example.com";
12473 static const char kSecureServer[] = "https://www.example.com";
12474 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:1512475
12476 enum AuthTiming {
12477 AUTH_NONE,
12478 AUTH_SYNC,
12479 AUTH_ASYNC,
12480 };
12481
12482 const MockWrite kGet(
12483 "GET / HTTP/1.1\r\n"
12484 "Host: www.example.com\r\n"
12485 "Connection: keep-alive\r\n\r\n");
12486 const MockWrite kGetProxy(
12487 "GET http://www.example.com/ HTTP/1.1\r\n"
12488 "Host: www.example.com\r\n"
12489 "Proxy-Connection: keep-alive\r\n\r\n");
12490 const MockWrite kGetAuth(
12491 "GET / HTTP/1.1\r\n"
12492 "Host: www.example.com\r\n"
12493 "Connection: keep-alive\r\n"
12494 "Authorization: auth_token\r\n\r\n");
12495 const MockWrite kGetProxyAuth(
12496 "GET http://www.example.com/ HTTP/1.1\r\n"
12497 "Host: www.example.com\r\n"
12498 "Proxy-Connection: keep-alive\r\n"
12499 "Proxy-Authorization: auth_token\r\n\r\n");
12500 const MockWrite kGetAuthThroughProxy(
12501 "GET http://www.example.com/ HTTP/1.1\r\n"
12502 "Host: www.example.com\r\n"
12503 "Proxy-Connection: keep-alive\r\n"
12504 "Authorization: auth_token\r\n\r\n");
12505 const MockWrite kGetAuthWithProxyAuth(
12506 "GET http://www.example.com/ HTTP/1.1\r\n"
12507 "Host: www.example.com\r\n"
12508 "Proxy-Connection: keep-alive\r\n"
12509 "Proxy-Authorization: auth_token\r\n"
12510 "Authorization: auth_token\r\n\r\n");
12511 const MockWrite kConnect(
12512 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1712513 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1512514 "Proxy-Connection: keep-alive\r\n\r\n");
12515 const MockWrite kConnectProxyAuth(
12516 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1712517 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1512518 "Proxy-Connection: keep-alive\r\n"
12519 "Proxy-Authorization: auth_token\r\n\r\n");
12520
12521 const MockRead kSuccess(
12522 "HTTP/1.1 200 OK\r\n"
12523 "Content-Type: text/html; charset=iso-8859-1\r\n"
12524 "Content-Length: 3\r\n\r\n"
12525 "Yes");
12526 const MockRead kFailure(
12527 "Should not be called.");
12528 const MockRead kServerChallenge(
12529 "HTTP/1.1 401 Unauthorized\r\n"
12530 "WWW-Authenticate: Mock realm=server\r\n"
12531 "Content-Type: text/html; charset=iso-8859-1\r\n"
12532 "Content-Length: 14\r\n\r\n"
12533 "Unauthorized\r\n");
12534 const MockRead kProxyChallenge(
12535 "HTTP/1.1 407 Unauthorized\r\n"
12536 "Proxy-Authenticate: Mock realm=proxy\r\n"
12537 "Proxy-Connection: close\r\n"
12538 "Content-Type: text/html; charset=iso-8859-1\r\n"
12539 "Content-Length: 14\r\n\r\n"
12540 "Unauthorized\r\n");
12541 const MockRead kProxyConnected(
12542 "HTTP/1.1 200 Connection Established\r\n\r\n");
12543
12544 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
12545 // no constructors, but the C++ compiler on Windows warns about
12546 // unspecified data in compound literals. So, moved to using constructors,
12547 // and TestRound's created with the default constructor should not be used.
12548 struct TestRound {
12549 TestRound()
12550 : expected_rv(ERR_UNEXPECTED),
12551 extra_write(NULL),
12552 extra_read(NULL) {
12553 }
12554 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
12555 int expected_rv_arg)
12556 : write(write_arg),
12557 read(read_arg),
12558 expected_rv(expected_rv_arg),
12559 extra_write(NULL),
12560 extra_read(NULL) {
12561 }
12562 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
12563 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:0112564 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:1512565 : write(write_arg),
12566 read(read_arg),
12567 expected_rv(expected_rv_arg),
12568 extra_write(extra_write_arg),
12569 extra_read(extra_read_arg) {
12570 }
12571 MockWrite write;
12572 MockRead read;
12573 int expected_rv;
12574 const MockWrite* extra_write;
12575 const MockRead* extra_read;
12576 };
12577
12578 static const int kNoSSL = 500;
12579
12580 struct TestConfig {
asanka463ca4262016-11-16 02:34:3112581 int line_number;
thestig9d3bb0c2015-01-24 00:49:5112582 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:1512583 AuthTiming proxy_auth_timing;
asanka463ca4262016-11-16 02:34:3112584 int first_generate_proxy_token_rv;
thestig9d3bb0c2015-01-24 00:49:5112585 const char* const server_url;
[email protected]044de0642010-06-17 10:42:1512586 AuthTiming server_auth_timing;
asanka463ca4262016-11-16 02:34:3112587 int first_generate_server_token_rv;
[email protected]044de0642010-06-17 10:42:1512588 int num_auth_rounds;
12589 int first_ssl_round;
asankae2257db2016-10-11 22:03:1612590 TestRound rounds[4];
[email protected]044de0642010-06-17 10:42:1512591 } test_configs[] = {
asankac93076192016-10-03 15:46:0212592 // Non-authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3112593 {__LINE__,
12594 nullptr,
asankac93076192016-10-03 15:46:0212595 AUTH_NONE,
12596 OK,
12597 kServer,
12598 AUTH_NONE,
12599 OK,
12600 1,
12601 kNoSSL,
12602 {TestRound(kGet, kSuccess, OK)}},
12603 // Authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3112604 {__LINE__,
12605 nullptr,
asankac93076192016-10-03 15:46:0212606 AUTH_NONE,
12607 OK,
12608 kServer,
12609 AUTH_SYNC,
12610 OK,
12611 2,
12612 kNoSSL,
12613 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512614 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112615 {__LINE__,
12616 nullptr,
asankac93076192016-10-03 15:46:0212617 AUTH_NONE,
12618 OK,
12619 kServer,
12620 AUTH_SYNC,
12621 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1612622 3,
12623 kNoSSL,
12624 {TestRound(kGet, kServerChallenge, OK),
12625 TestRound(kGet, kServerChallenge, OK),
12626 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112627 {__LINE__,
12628 nullptr,
asankae2257db2016-10-11 22:03:1612629 AUTH_NONE,
12630 OK,
12631 kServer,
12632 AUTH_SYNC,
12633 ERR_UNSUPPORTED_AUTH_SCHEME,
12634 2,
12635 kNoSSL,
12636 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112637 {__LINE__,
12638 nullptr,
asankae2257db2016-10-11 22:03:1612639 AUTH_NONE,
12640 OK,
12641 kServer,
12642 AUTH_SYNC,
12643 ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS,
12644 2,
12645 kNoSSL,
12646 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112647 {__LINE__,
12648 kProxy,
asankae2257db2016-10-11 22:03:1612649 AUTH_SYNC,
12650 ERR_FAILED,
12651 kServer,
12652 AUTH_NONE,
12653 OK,
12654 2,
12655 kNoSSL,
12656 {TestRound(kGetProxy, kProxyChallenge, OK),
12657 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112658 {__LINE__,
12659 kProxy,
asankae2257db2016-10-11 22:03:1612660 AUTH_ASYNC,
12661 ERR_FAILED,
12662 kServer,
12663 AUTH_NONE,
12664 OK,
12665 2,
12666 kNoSSL,
12667 {TestRound(kGetProxy, kProxyChallenge, OK),
12668 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112669 {__LINE__,
12670 nullptr,
asankae2257db2016-10-11 22:03:1612671 AUTH_NONE,
12672 OK,
12673 kServer,
12674 AUTH_SYNC,
12675 ERR_FAILED,
asankac93076192016-10-03 15:46:0212676 2,
12677 kNoSSL,
12678 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612679 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112680 {__LINE__,
12681 nullptr,
asankae2257db2016-10-11 22:03:1612682 AUTH_NONE,
12683 OK,
12684 kServer,
12685 AUTH_ASYNC,
12686 ERR_FAILED,
12687 2,
12688 kNoSSL,
12689 {TestRound(kGet, kServerChallenge, OK),
12690 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112691 {__LINE__,
12692 nullptr,
asankac93076192016-10-03 15:46:0212693 AUTH_NONE,
12694 OK,
12695 kServer,
12696 AUTH_ASYNC,
12697 OK,
12698 2,
12699 kNoSSL,
12700 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512701 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112702 {__LINE__,
12703 nullptr,
asankac93076192016-10-03 15:46:0212704 AUTH_NONE,
12705 OK,
12706 kServer,
12707 AUTH_ASYNC,
12708 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1612709 3,
asankac93076192016-10-03 15:46:0212710 kNoSSL,
12711 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612712 // The second round uses a HttpAuthHandlerMock that always succeeds.
12713 TestRound(kGet, kServerChallenge, OK),
12714 TestRound(kGetAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212715 // Non-authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3112716 {__LINE__,
12717 kProxy,
asankac93076192016-10-03 15:46:0212718 AUTH_NONE,
12719 OK,
12720 kServer,
12721 AUTH_NONE,
12722 OK,
12723 1,
12724 kNoSSL,
12725 {TestRound(kGetProxy, kSuccess, OK)}},
12726 // Authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3112727 {__LINE__,
12728 kProxy,
asankac93076192016-10-03 15:46:0212729 AUTH_NONE,
12730 OK,
12731 kServer,
12732 AUTH_SYNC,
12733 OK,
12734 2,
12735 kNoSSL,
12736 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512737 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112738 {__LINE__,
12739 kProxy,
asankac93076192016-10-03 15:46:0212740 AUTH_NONE,
12741 OK,
12742 kServer,
12743 AUTH_SYNC,
12744 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1612745 3,
asankac93076192016-10-03 15:46:0212746 kNoSSL,
12747 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612748 TestRound(kGetProxy, kServerChallenge, OK),
12749 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112750 {__LINE__,
12751 kProxy,
asankac93076192016-10-03 15:46:0212752 AUTH_NONE,
12753 OK,
12754 kServer,
12755 AUTH_ASYNC,
12756 OK,
12757 2,
12758 kNoSSL,
12759 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512760 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112761 {__LINE__,
12762 kProxy,
asankac93076192016-10-03 15:46:0212763 AUTH_NONE,
12764 OK,
12765 kServer,
12766 AUTH_ASYNC,
12767 ERR_INVALID_AUTH_CREDENTIALS,
12768 2,
12769 kNoSSL,
12770 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612771 TestRound(kGetProxy, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212772 // Non-authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112773 {__LINE__,
12774 kProxy,
asankac93076192016-10-03 15:46:0212775 AUTH_SYNC,
12776 OK,
12777 kServer,
12778 AUTH_NONE,
12779 OK,
12780 2,
12781 kNoSSL,
12782 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512783 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112784 {__LINE__,
12785 kProxy,
asankac93076192016-10-03 15:46:0212786 AUTH_SYNC,
12787 ERR_INVALID_AUTH_CREDENTIALS,
12788 kServer,
12789 AUTH_NONE,
12790 OK,
12791 2,
12792 kNoSSL,
12793 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612794 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112795 {__LINE__,
12796 kProxy,
asankac93076192016-10-03 15:46:0212797 AUTH_ASYNC,
12798 OK,
12799 kServer,
12800 AUTH_NONE,
12801 OK,
12802 2,
12803 kNoSSL,
12804 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512805 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112806 {__LINE__,
12807 kProxy,
asankac93076192016-10-03 15:46:0212808 AUTH_ASYNC,
12809 ERR_INVALID_AUTH_CREDENTIALS,
12810 kServer,
12811 AUTH_NONE,
12812 OK,
12813 2,
12814 kNoSSL,
12815 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612816 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112817 {__LINE__,
12818 kProxy,
12819 AUTH_ASYNC,
12820 ERR_INVALID_AUTH_CREDENTIALS,
12821 kServer,
12822 AUTH_NONE,
12823 OK,
12824 3,
12825 kNoSSL,
12826 {TestRound(kGetProxy, kProxyChallenge, OK),
12827 TestRound(kGetProxy, kProxyChallenge, OK),
12828 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212829 // Authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112830 {__LINE__,
12831 kProxy,
asankac93076192016-10-03 15:46:0212832 AUTH_SYNC,
12833 OK,
12834 kServer,
12835 AUTH_SYNC,
12836 OK,
12837 3,
12838 kNoSSL,
12839 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512840 TestRound(kGetProxyAuth, kServerChallenge, OK),
12841 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112842 {__LINE__,
12843 kProxy,
asankac93076192016-10-03 15:46:0212844 AUTH_SYNC,
12845 OK,
12846 kServer,
12847 AUTH_SYNC,
12848 ERR_INVALID_AUTH_CREDENTIALS,
12849 3,
12850 kNoSSL,
12851 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512852 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612853 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112854 {__LINE__,
12855 kProxy,
asankac93076192016-10-03 15:46:0212856 AUTH_ASYNC,
12857 OK,
12858 kServer,
12859 AUTH_SYNC,
12860 OK,
12861 3,
12862 kNoSSL,
12863 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512864 TestRound(kGetProxyAuth, kServerChallenge, OK),
12865 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112866 {__LINE__,
12867 kProxy,
asankac93076192016-10-03 15:46:0212868 AUTH_ASYNC,
12869 OK,
12870 kServer,
12871 AUTH_SYNC,
12872 ERR_INVALID_AUTH_CREDENTIALS,
12873 3,
12874 kNoSSL,
12875 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512876 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612877 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112878 {__LINE__,
12879 kProxy,
asankac93076192016-10-03 15:46:0212880 AUTH_SYNC,
12881 OK,
12882 kServer,
12883 AUTH_ASYNC,
12884 OK,
12885 3,
12886 kNoSSL,
12887 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512888 TestRound(kGetProxyAuth, kServerChallenge, OK),
12889 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112890 {__LINE__,
12891 kProxy,
12892 AUTH_SYNC,
12893 ERR_INVALID_AUTH_CREDENTIALS,
12894 kServer,
12895 AUTH_ASYNC,
12896 OK,
12897 4,
12898 kNoSSL,
12899 {TestRound(kGetProxy, kProxyChallenge, OK),
12900 TestRound(kGetProxy, kProxyChallenge, OK),
12901 TestRound(kGetProxyAuth, kServerChallenge, OK),
12902 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
12903 {__LINE__,
12904 kProxy,
asankac93076192016-10-03 15:46:0212905 AUTH_SYNC,
12906 OK,
12907 kServer,
12908 AUTH_ASYNC,
12909 ERR_INVALID_AUTH_CREDENTIALS,
12910 3,
12911 kNoSSL,
12912 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512913 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612914 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112915 {__LINE__,
12916 kProxy,
asankac93076192016-10-03 15:46:0212917 AUTH_ASYNC,
12918 OK,
12919 kServer,
12920 AUTH_ASYNC,
12921 OK,
12922 3,
12923 kNoSSL,
12924 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512925 TestRound(kGetProxyAuth, kServerChallenge, OK),
12926 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112927 {__LINE__,
12928 kProxy,
asankac93076192016-10-03 15:46:0212929 AUTH_ASYNC,
12930 OK,
12931 kServer,
12932 AUTH_ASYNC,
12933 ERR_INVALID_AUTH_CREDENTIALS,
12934 3,
12935 kNoSSL,
12936 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512937 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612938 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112939 {__LINE__,
12940 kProxy,
12941 AUTH_ASYNC,
12942 ERR_INVALID_AUTH_CREDENTIALS,
12943 kServer,
12944 AUTH_ASYNC,
12945 ERR_INVALID_AUTH_CREDENTIALS,
12946 4,
12947 kNoSSL,
12948 {TestRound(kGetProxy, kProxyChallenge, OK),
12949 TestRound(kGetProxy, kProxyChallenge, OK),
12950 TestRound(kGetProxyAuth, kServerChallenge, OK),
12951 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212952 // Non-authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3112953 {__LINE__,
12954 nullptr,
asankac93076192016-10-03 15:46:0212955 AUTH_NONE,
12956 OK,
12957 kSecureServer,
12958 AUTH_NONE,
12959 OK,
12960 1,
12961 0,
12962 {TestRound(kGet, kSuccess, OK)}},
12963 // Authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3112964 {__LINE__,
12965 nullptr,
asankac93076192016-10-03 15:46:0212966 AUTH_NONE,
12967 OK,
12968 kSecureServer,
12969 AUTH_SYNC,
12970 OK,
12971 2,
12972 0,
12973 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512974 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112975 {__LINE__,
12976 nullptr,
asankac93076192016-10-03 15:46:0212977 AUTH_NONE,
12978 OK,
12979 kSecureServer,
12980 AUTH_SYNC,
12981 ERR_INVALID_AUTH_CREDENTIALS,
12982 2,
12983 0,
asankae2257db2016-10-11 22:03:1612984 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112985 {__LINE__,
12986 nullptr,
asankac93076192016-10-03 15:46:0212987 AUTH_NONE,
12988 OK,
12989 kSecureServer,
12990 AUTH_ASYNC,
12991 OK,
12992 2,
12993 0,
12994 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512995 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112996 {__LINE__,
12997 nullptr,
asankac93076192016-10-03 15:46:0212998 AUTH_NONE,
12999 OK,
13000 kSecureServer,
13001 AUTH_ASYNC,
13002 ERR_INVALID_AUTH_CREDENTIALS,
13003 2,
13004 0,
asankae2257db2016-10-11 22:03:1613005 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213006 // Non-authenticating HTTPS server with a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3113007 {__LINE__,
13008 kProxy,
asankac93076192016-10-03 15:46:0213009 AUTH_NONE,
13010 OK,
13011 kSecureServer,
13012 AUTH_NONE,
13013 OK,
13014 1,
13015 0,
13016 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
13017 // Authenticating HTTPS server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3113018 {__LINE__,
13019 kProxy,
asankac93076192016-10-03 15:46:0213020 AUTH_NONE,
13021 OK,
13022 kSecureServer,
13023 AUTH_SYNC,
13024 OK,
13025 2,
13026 0,
13027 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513028 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113029 {__LINE__,
13030 kProxy,
asankac93076192016-10-03 15:46:0213031 AUTH_NONE,
13032 OK,
13033 kSecureServer,
13034 AUTH_SYNC,
13035 ERR_INVALID_AUTH_CREDENTIALS,
13036 2,
13037 0,
13038 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1613039 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113040 {__LINE__,
13041 kProxy,
asankac93076192016-10-03 15:46:0213042 AUTH_NONE,
13043 OK,
13044 kSecureServer,
13045 AUTH_ASYNC,
13046 OK,
13047 2,
13048 0,
13049 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513050 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113051 {__LINE__,
13052 kProxy,
asankac93076192016-10-03 15:46:0213053 AUTH_NONE,
13054 OK,
13055 kSecureServer,
13056 AUTH_ASYNC,
13057 ERR_INVALID_AUTH_CREDENTIALS,
13058 2,
13059 0,
13060 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1613061 TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213062 // Non-Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3113063 {__LINE__,
13064 kProxy,
asankac93076192016-10-03 15:46:0213065 AUTH_SYNC,
13066 OK,
13067 kSecureServer,
13068 AUTH_NONE,
13069 OK,
13070 2,
13071 1,
13072 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513073 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113074 {__LINE__,
13075 kProxy,
asankac93076192016-10-03 15:46:0213076 AUTH_SYNC,
13077 ERR_INVALID_AUTH_CREDENTIALS,
13078 kSecureServer,
13079 AUTH_NONE,
13080 OK,
13081 2,
13082 kNoSSL,
13083 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1613084 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113085 {__LINE__,
13086 kProxy,
asankae2257db2016-10-11 22:03:1613087 AUTH_SYNC,
13088 ERR_UNSUPPORTED_AUTH_SCHEME,
13089 kSecureServer,
13090 AUTH_NONE,
13091 OK,
13092 2,
13093 kNoSSL,
13094 {TestRound(kConnect, kProxyChallenge, OK),
13095 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113096 {__LINE__,
13097 kProxy,
asankae2257db2016-10-11 22:03:1613098 AUTH_SYNC,
13099 ERR_UNEXPECTED,
13100 kSecureServer,
13101 AUTH_NONE,
13102 OK,
13103 2,
13104 kNoSSL,
13105 {TestRound(kConnect, kProxyChallenge, OK),
13106 TestRound(kConnect, kProxyConnected, ERR_UNEXPECTED)}},
asanka463ca4262016-11-16 02:34:3113107 {__LINE__,
13108 kProxy,
asankac93076192016-10-03 15:46:0213109 AUTH_ASYNC,
13110 OK,
13111 kSecureServer,
13112 AUTH_NONE,
13113 OK,
13114 2,
13115 1,
13116 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513117 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113118 {__LINE__,
13119 kProxy,
asankac93076192016-10-03 15:46:0213120 AUTH_ASYNC,
13121 ERR_INVALID_AUTH_CREDENTIALS,
13122 kSecureServer,
13123 AUTH_NONE,
13124 OK,
13125 2,
13126 kNoSSL,
13127 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1613128 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asankac93076192016-10-03 15:46:0213129 // Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3113130 {__LINE__,
13131 kProxy,
asankac93076192016-10-03 15:46:0213132 AUTH_SYNC,
13133 OK,
13134 kSecureServer,
13135 AUTH_SYNC,
13136 OK,
13137 3,
13138 1,
13139 {TestRound(kConnect, kProxyChallenge, OK),
13140 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13141 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513142 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113143 {__LINE__,
13144 kProxy,
asankac93076192016-10-03 15:46:0213145 AUTH_SYNC,
13146 OK,
13147 kSecureServer,
13148 AUTH_SYNC,
13149 ERR_INVALID_AUTH_CREDENTIALS,
13150 3,
13151 1,
13152 {TestRound(kConnect, kProxyChallenge, OK),
13153 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13154 &kServerChallenge),
asankae2257db2016-10-11 22:03:1613155 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113156 {__LINE__,
13157 kProxy,
asankac93076192016-10-03 15:46:0213158 AUTH_ASYNC,
13159 OK,
13160 kSecureServer,
13161 AUTH_SYNC,
13162 OK,
13163 3,
13164 1,
13165 {TestRound(kConnect, kProxyChallenge, OK),
13166 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13167 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513168 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113169 {__LINE__,
13170 kProxy,
asankac93076192016-10-03 15:46:0213171 AUTH_ASYNC,
13172 OK,
13173 kSecureServer,
13174 AUTH_SYNC,
13175 ERR_INVALID_AUTH_CREDENTIALS,
13176 3,
13177 1,
13178 {TestRound(kConnect, kProxyChallenge, OK),
13179 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13180 &kServerChallenge),
asankae2257db2016-10-11 22:03:1613181 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113182 {__LINE__,
13183 kProxy,
asankac93076192016-10-03 15:46:0213184 AUTH_SYNC,
13185 OK,
13186 kSecureServer,
13187 AUTH_ASYNC,
13188 OK,
13189 3,
13190 1,
13191 {TestRound(kConnect, kProxyChallenge, OK),
13192 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13193 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513194 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113195 {__LINE__,
13196 kProxy,
asankac93076192016-10-03 15:46:0213197 AUTH_SYNC,
13198 OK,
13199 kSecureServer,
13200 AUTH_ASYNC,
13201 ERR_INVALID_AUTH_CREDENTIALS,
13202 3,
13203 1,
13204 {TestRound(kConnect, kProxyChallenge, OK),
13205 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13206 &kServerChallenge),
asankae2257db2016-10-11 22:03:1613207 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113208 {__LINE__,
13209 kProxy,
asankac93076192016-10-03 15:46:0213210 AUTH_ASYNC,
13211 OK,
13212 kSecureServer,
13213 AUTH_ASYNC,
13214 OK,
13215 3,
13216 1,
13217 {TestRound(kConnect, kProxyChallenge, OK),
13218 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13219 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513220 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113221 {__LINE__,
13222 kProxy,
asankac93076192016-10-03 15:46:0213223 AUTH_ASYNC,
13224 OK,
13225 kSecureServer,
13226 AUTH_ASYNC,
13227 ERR_INVALID_AUTH_CREDENTIALS,
13228 3,
13229 1,
13230 {TestRound(kConnect, kProxyChallenge, OK),
13231 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13232 &kServerChallenge),
asankae2257db2016-10-11 22:03:1613233 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113234 {__LINE__,
13235 kProxy,
13236 AUTH_ASYNC,
13237 ERR_INVALID_AUTH_CREDENTIALS,
13238 kSecureServer,
13239 AUTH_ASYNC,
13240 ERR_INVALID_AUTH_CREDENTIALS,
13241 4,
13242 2,
13243 {TestRound(kConnect, kProxyChallenge, OK),
13244 TestRound(kConnect, kProxyChallenge, OK),
13245 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13246 &kServerChallenge),
13247 TestRound(kGet, kSuccess, OK)}},
[email protected]044de0642010-06-17 10:42:1513248 };
13249
asanka463ca4262016-11-16 02:34:3113250 for (const auto& test_config : test_configs) {
13251 SCOPED_TRACE(::testing::Message() << "Test config at "
13252 << test_config.line_number);
[email protected]2d01c262011-08-11 23:07:0813253 HttpAuthHandlerMock::Factory* auth_factory(
13254 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0713255 session_deps_.http_auth_handler_factory.reset(auth_factory);
asanka5ffd5d72016-03-23 16:20:4913256 SSLInfo empty_ssl_info;
[email protected]65d34382010-07-01 18:12:2613257
13258 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:1513259 if (test_config.proxy_auth_timing != AUTH_NONE) {
asanka463ca4262016-11-16 02:34:3113260 for (int n = 0; n < 3; n++) {
[email protected]2d01c262011-08-11 23:07:0813261 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
13262 std::string auth_challenge = "Mock realm=proxy";
13263 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:2413264 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
13265 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:0813266 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
tfarina42834112016-09-22 13:38:2013267 empty_ssl_info, origin,
13268 NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0813269 auth_handler->SetGenerateExpectation(
13270 test_config.proxy_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3113271 n == 0 ? test_config.first_generate_proxy_token_rv : OK);
[email protected]2d01c262011-08-11 23:07:0813272 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
13273 }
[email protected]044de0642010-06-17 10:42:1513274 }
13275 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:0013276 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:1513277 std::string auth_challenge = "Mock realm=server";
13278 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:2413279 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
13280 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:1513281 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2013282 empty_ssl_info, origin,
13283 NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1513284 auth_handler->SetGenerateExpectation(
13285 test_config.server_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3113286 test_config.first_generate_server_token_rv);
[email protected]2d01c262011-08-11 23:07:0813287 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
asankae2257db2016-10-11 22:03:1613288
13289 // The second handler always succeeds. It should only be used where there
13290 // are multiple auth sessions for server auth in the same network
13291 // transaction using the same auth scheme.
13292 std::unique_ptr<HttpAuthHandlerMock> second_handler =
Jeremy Roman0579ed62017-08-29 15:56:1913293 std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:1613294 second_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
13295 empty_ssl_info, origin,
13296 NetLogWithSource());
13297 second_handler->SetGenerateExpectation(true, OK);
13298 auth_factory->AddMockHandler(second_handler.release(),
13299 HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:1513300 }
13301 if (test_config.proxy_url) {
Lily Houghton8c2f97d2018-01-22 05:06:5913302 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4913303 ProxyResolutionService::CreateFixed(test_config.proxy_url,
13304 TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]044de0642010-06-17 10:42:1513305 } else {
Bence Béky53a5aef2018-03-29 21:54:1213306 session_deps_.proxy_resolution_service =
13307 ProxyResolutionService::CreateDirect();
[email protected]044de0642010-06-17 10:42:1513308 }
13309
13310 HttpRequestInfo request;
13311 request.method = "GET";
13312 request.url = GURL(test_config.server_url);
Ramin Halavatib5e433e62018-02-07 07:41:1013313 request.traffic_annotation =
13314 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]044de0642010-06-17 10:42:1513315
danakj1fd259a02016-04-16 03:17:0913316 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]044de0642010-06-17 10:42:1513317
rchcb68dc62015-05-21 04:45:3613318 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
13319
13320 std::vector<std::vector<MockRead>> mock_reads(1);
13321 std::vector<std::vector<MockWrite>> mock_writes(1);
[email protected]044de0642010-06-17 10:42:1513322 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2213323 SCOPED_TRACE(round);
[email protected]044de0642010-06-17 10:42:1513324 const TestRound& read_write_round = test_config.rounds[round];
13325
13326 // Set up expected reads and writes.
rchcb68dc62015-05-21 04:45:3613327 mock_reads.back().push_back(read_write_round.read);
13328 mock_writes.back().push_back(read_write_round.write);
13329
13330 // kProxyChallenge uses Proxy-Connection: close which means that the
13331 // socket is closed and a new one will be created for the next request.
mmenkee71e15332015-10-07 16:39:5413332 if (read_write_round.read.data == kProxyChallenge.data) {
rchcb68dc62015-05-21 04:45:3613333 mock_reads.push_back(std::vector<MockRead>());
13334 mock_writes.push_back(std::vector<MockWrite>());
[email protected]044de0642010-06-17 10:42:1513335 }
13336
rchcb68dc62015-05-21 04:45:3613337 if (read_write_round.extra_read) {
13338 mock_reads.back().push_back(*read_write_round.extra_read);
[email protected]044de0642010-06-17 10:42:1513339 }
rchcb68dc62015-05-21 04:45:3613340 if (read_write_round.extra_write) {
13341 mock_writes.back().push_back(*read_write_round.extra_write);
13342 }
[email protected]044de0642010-06-17 10:42:1513343
13344 // Add an SSL sequence if necessary.
[email protected]044de0642010-06-17 10:42:1513345 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0713346 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1513347 &ssl_socket_data_provider);
rchcb68dc62015-05-21 04:45:3613348 }
[email protected]044de0642010-06-17 10:42:1513349
danakj1fd259a02016-04-16 03:17:0913350 std::vector<std::unique_ptr<StaticSocketDataProvider>> data_providers;
rchcb68dc62015-05-21 04:45:3613351 for (size_t i = 0; i < mock_reads.size(); ++i) {
Jeremy Roman0579ed62017-08-29 15:56:1913352 data_providers.push_back(std::make_unique<StaticSocketDataProvider>(
Ryan Sleevib8d7ea02018-05-07 20:01:0113353 mock_reads[i], mock_writes[i]));
rchcb68dc62015-05-21 04:45:3613354 session_deps_.socket_factory->AddSocketDataProvider(
olli.raula525048c2015-12-10 07:38:3213355 data_providers.back().get());
rchcb68dc62015-05-21 04:45:3613356 }
13357
mmenkecc2298e2015-12-07 18:20:1813358 // Transaction must be created after DataProviders, so it's destroyed before
13359 // they are as well.
13360 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
13361
rchcb68dc62015-05-21 04:45:3613362 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2213363 SCOPED_TRACE(round);
rchcb68dc62015-05-21 04:45:3613364 const TestRound& read_write_round = test_config.rounds[round];
[email protected]044de0642010-06-17 10:42:1513365 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4113366 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1513367 int rv;
13368 if (round == 0) {
tfarina42834112016-09-22 13:38:2013369 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1513370 } else {
[email protected]49639fa2011-12-20 23:22:4113371 rv = trans.RestartWithAuth(
13372 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1513373 }
13374 if (rv == ERR_IO_PENDING)
13375 rv = callback.WaitForResult();
13376
13377 // Compare results with expected data.
asankae2257db2016-10-11 22:03:1613378 EXPECT_THAT(rv, IsError(read_write_round.expected_rv));
[email protected]0b0bf032010-09-21 18:08:5013379 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttlec0c828492015-05-15 01:25:5513380 if (read_write_round.expected_rv != OK) {
[email protected]044de0642010-06-17 10:42:1513381 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
13382 continue;
13383 }
13384 if (round + 1 < test_config.num_auth_rounds) {
wezca1070932016-05-26 20:30:5213385 EXPECT_TRUE(response->auth_challenge);
[email protected]044de0642010-06-17 10:42:1513386 } else {
wezca1070932016-05-26 20:30:5213387 EXPECT_FALSE(response->auth_challenge);
asankae2257db2016-10-11 22:03:1613388 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]044de0642010-06-17 10:42:1513389 }
13390 }
[email protected]e5ae96a2010-04-14 20:12:4513391 }
13392}
13393
bncd16676a2016-07-20 16:23:0113394TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1413395 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1413396 HttpAuthHandlerMock::Factory* auth_factory(
13397 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0713398 session_deps_.http_auth_handler_factory.reset(auth_factory);
Bence Béky53a5aef2018-03-29 21:54:1213399 session_deps_.proxy_resolution_service =
13400 ProxyResolutionService::CreateDirect();
[email protected]bb88e1d32013-05-03 23:11:0713401 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
13402 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:1413403
13404 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
13405 auth_handler->set_connection_based(true);
13406 std::string auth_challenge = "Mock realm=server";
13407 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2413408 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
13409 auth_challenge.end());
asanka5ffd5d72016-03-23 16:20:4913410 SSLInfo empty_ssl_info;
[email protected]c871bce92010-07-15 21:51:1413411 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2013412 empty_ssl_info, origin, NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0813413 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1413414
[email protected]c871bce92010-07-15 21:51:1413415 int rv = OK;
13416 const HttpResponseInfo* response = NULL;
13417 HttpRequestInfo request;
13418 request.method = "GET";
13419 request.url = origin;
Ramin Halavatib5e433e62018-02-07 07:41:1013420 request.traffic_annotation =
13421 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2713422
danakj1fd259a02016-04-16 03:17:0913423 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1013424
13425 // Use a TCP Socket Pool with only one connection per group. This is used
13426 // to validate that the TCP socket is not released to the pool between
13427 // each round of multi-round authentication.
mmenkee65e7af2015-10-13 17:16:4213428 HttpNetworkSessionPeer session_peer(session.get());
[email protected]ab739042011-04-07 15:22:2813429 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:1013430 50, // Max sockets for pool
13431 1, // Max sockets per group
tbansal7b403bcc2016-04-13 22:33:2113432 session_deps_.host_resolver.get(), session_deps_.socket_factory.get(),
13433 NULL, session_deps_.net_log);
Jeremy Roman0579ed62017-08-29 15:56:1913434 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
[email protected]a42dbd142011-11-17 16:42:0213435 mock_pool_manager->SetTransportSocketPool(transport_pool);
dchengc7eeda422015-12-26 03:56:4813436 session_peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]7ef4cbbb2011-02-06 11:19:1013437
bnc691fda62016-08-12 00:43:1613438 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4113439 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1413440
13441 const MockWrite kGet(
13442 "GET / HTTP/1.1\r\n"
13443 "Host: www.example.com\r\n"
13444 "Connection: keep-alive\r\n\r\n");
13445 const MockWrite kGetAuth(
13446 "GET / HTTP/1.1\r\n"
13447 "Host: www.example.com\r\n"
13448 "Connection: keep-alive\r\n"
13449 "Authorization: auth_token\r\n\r\n");
13450
13451 const MockRead kServerChallenge(
13452 "HTTP/1.1 401 Unauthorized\r\n"
13453 "WWW-Authenticate: Mock realm=server\r\n"
13454 "Content-Type: text/html; charset=iso-8859-1\r\n"
13455 "Content-Length: 14\r\n\r\n"
13456 "Unauthorized\r\n");
13457 const MockRead kSuccess(
13458 "HTTP/1.1 200 OK\r\n"
13459 "Content-Type: text/html; charset=iso-8859-1\r\n"
13460 "Content-Length: 3\r\n\r\n"
13461 "Yes");
13462
13463 MockWrite writes[] = {
13464 // First round
13465 kGet,
13466 // Second round
13467 kGetAuth,
13468 // Third round
13469 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3013470 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1013471 kGetAuth,
13472 // Competing request
13473 kGet,
[email protected]c871bce92010-07-15 21:51:1413474 };
13475 MockRead reads[] = {
13476 // First round
13477 kServerChallenge,
13478 // Second round
13479 kServerChallenge,
13480 // Third round
[email protected]eca50e122010-09-11 14:03:3013481 kServerChallenge,
13482 // Fourth round
[email protected]c871bce92010-07-15 21:51:1413483 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1013484 // Competing response
13485 kSuccess,
[email protected]c871bce92010-07-15 21:51:1413486 };
Ryan Sleevib8d7ea02018-05-07 20:01:0113487 StaticSocketDataProvider data_provider(reads, writes);
[email protected]bb88e1d32013-05-03 23:11:0713488 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1413489
thestig9d3bb0c2015-01-24 00:49:5113490 const char kSocketGroup[] = "www.example.com:80";
[email protected]7ef4cbbb2011-02-06 11:19:1013491
13492 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1413493 auth_handler->SetGenerateExpectation(false, OK);
tfarina42834112016-09-22 13:38:2013494 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]c871bce92010-07-15 21:51:1413495 if (rv == ERR_IO_PENDING)
13496 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113497 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613498 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213499 ASSERT_TRUE(response);
13500 EXPECT_TRUE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813501 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3113502 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
13503 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1413504
[email protected]7ef4cbbb2011-02-06 11:19:1013505 // In between rounds, another request comes in for the same domain.
13506 // It should not be able to grab the TCP socket that trans has already
13507 // claimed.
bnc691fda62016-08-12 00:43:1613508 HttpNetworkTransaction trans_compete(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4113509 TestCompletionCallback callback_compete;
tfarina42834112016-09-22 13:38:2013510 rv = trans_compete.Start(&request, callback_compete.callback(),
13511 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113512 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7ef4cbbb2011-02-06 11:19:1013513 // callback_compete.WaitForResult at this point would stall forever,
13514 // since the HttpNetworkTransaction does not release the request back to
13515 // the pool until after authentication completes.
13516
13517 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1413518 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1613519 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1413520 if (rv == ERR_IO_PENDING)
13521 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113522 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613523 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213524 ASSERT_TRUE(response);
13525 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813526 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3113527 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
13528 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1413529
[email protected]7ef4cbbb2011-02-06 11:19:1013530 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1413531 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1613532 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1413533 if (rv == ERR_IO_PENDING)
13534 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113535 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613536 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213537 ASSERT_TRUE(response);
13538 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813539 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3113540 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
13541 auth_handler->state());
[email protected]eca50e122010-09-11 14:03:3013542
[email protected]7ef4cbbb2011-02-06 11:19:1013543 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3013544 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1613545 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3013546 if (rv == ERR_IO_PENDING)
13547 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113548 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613549 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213550 ASSERT_TRUE(response);
13551 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813552 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1013553
asanka463ca4262016-11-16 02:34:3113554 // In WAIT_FOR_CHALLENGE, although in reality the auth handler is done. A real
13555 // auth handler should transition to a DONE state in concert with the remote
13556 // server. But that's not something we can test here with a mock handler.
13557 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_CHALLENGE,
13558 auth_handler->state());
13559
[email protected]7ef4cbbb2011-02-06 11:19:1013560 // Read the body since the fourth round was successful. This will also
13561 // release the socket back to the pool.
13562 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
bnc691fda62016-08-12 00:43:1613563 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1013564 if (rv == ERR_IO_PENDING)
13565 rv = callback.WaitForResult();
13566 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1613567 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1013568 EXPECT_EQ(0, rv);
13569 // There are still 0 idle sockets, since the trans_compete transaction
13570 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:2813571 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1013572
13573 // The competing request can now finish. Wait for the headers and then
13574 // read the body.
13575 rv = callback_compete.WaitForResult();
robpercival214763f2016-07-01 23:27:0113576 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613577 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1013578 if (rv == ERR_IO_PENDING)
13579 rv = callback.WaitForResult();
13580 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1613581 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1013582 EXPECT_EQ(0, rv);
13583
13584 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:2813585 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1413586}
13587
[email protected]65041fa2010-05-21 06:56:5313588// This tests the case that a request is issued via http instead of spdy after
13589// npn is negotiated.
bncd16676a2016-07-20 16:23:0113590TEST_F(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]65041fa2010-05-21 06:56:5313591 HttpRequestInfo request;
13592 request.method = "GET";
bncce36dca22015-04-21 22:11:2313593 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1013594 request.traffic_annotation =
13595 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]65041fa2010-05-21 06:56:5313596
13597 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2313598 MockWrite(
13599 "GET / HTTP/1.1\r\n"
13600 "Host: www.example.org\r\n"
13601 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5313602 };
13603
13604 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5213605 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4313606 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5213607 MockRead("\r\n"),
13608 MockRead("hello world"),
13609 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5313610 };
13611
[email protected]8ddf8322012-02-23 18:08:0613612 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613613 ssl.next_proto = kProtoHTTP11;
[email protected]65041fa2010-05-21 06:56:5313614
[email protected]bb88e1d32013-05-03 23:11:0713615 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5313616
Ryan Sleevib8d7ea02018-05-07 20:01:0113617 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0713618 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5313619
[email protected]49639fa2011-12-20 23:22:4113620 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5313621
danakj1fd259a02016-04-16 03:17:0913622 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613623 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]65041fa2010-05-21 06:56:5313624
tfarina42834112016-09-22 13:38:2013625 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]65041fa2010-05-21 06:56:5313626
robpercival214763f2016-07-01 23:27:0113627 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13628 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]65041fa2010-05-21 06:56:5313629
bnc691fda62016-08-12 00:43:1613630 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213631 ASSERT_TRUE(response);
13632 ASSERT_TRUE(response->headers);
[email protected]65041fa2010-05-21 06:56:5313633 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13634
13635 std::string response_data;
bnc691fda62016-08-12 00:43:1613636 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]65041fa2010-05-21 06:56:5313637 EXPECT_EQ("hello world", response_data);
13638
13639 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213640 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]65041fa2010-05-21 06:56:5313641}
[email protected]26ef6582010-06-24 02:30:4713642
bnc55ff9da2015-08-19 18:42:3513643// Simulate the SSL handshake completing with an NPN negotiation followed by an
13644// immediate server closing of the socket.
13645// Regression test for https://crbug.com/46369.
bncd16676a2016-07-20 16:23:0113646TEST_F(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:4713647 HttpRequestInfo request;
13648 request.method = "GET";
bncce36dca22015-04-21 22:11:2313649 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1013650 request.traffic_annotation =
13651 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]26ef6582010-06-24 02:30:4713652
[email protected]8ddf8322012-02-23 18:08:0613653 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613654 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0713655 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4713656
Ryan Hamilton0239aac2018-05-19 00:03:1313657 spdy::SpdySerializedFrame req(
13658 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4113659 MockWrite spdy_writes[] = {CreateMockWrite(req, 1)};
[email protected]26ef6582010-06-24 02:30:4713660
13661 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0613662 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4713663 };
13664
Ryan Sleevib8d7ea02018-05-07 20:01:0113665 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0713666 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4713667
[email protected]49639fa2011-12-20 23:22:4113668 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4713669
danakj1fd259a02016-04-16 03:17:0913670 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613671 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]26ef6582010-06-24 02:30:4713672
tfarina42834112016-09-22 13:38:2013673 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113674 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13675 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]26ef6582010-06-24 02:30:4713676}
[email protected]65d34382010-07-01 18:12:2613677
[email protected]795cbf82013-07-22 09:37:2713678// A subclass of HttpAuthHandlerMock that records the request URL when
13679// it gets it. This is needed since the auth handler may get destroyed
13680// before we get a chance to query it.
13681class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
13682 public:
13683 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
13684
Chris Watkins7a41d3552017-12-01 02:13:2713685 ~UrlRecordingHttpAuthHandlerMock() override = default;
[email protected]795cbf82013-07-22 09:37:2713686
13687 protected:
dchengb03027d2014-10-21 12:00:2013688 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
13689 const HttpRequestInfo* request,
13690 const CompletionCallback& callback,
13691 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2713692 *url_ = request->url;
13693 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
13694 credentials, request, callback, auth_token);
13695 }
13696
13697 private:
13698 GURL* url_;
13699};
13700
[email protected]8e6441ca2010-08-19 05:56:3813701// Test that if we cancel the transaction as the connection is completing, that
13702// everything tears down correctly.
bncd16676a2016-07-20 16:23:0113703TEST_F(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3813704 // Setup everything about the connection to complete synchronously, so that
13705 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
13706 // for is the callback from the HttpStreamRequest.
13707 // Then cancel the transaction.
13708 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3613709 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3813710 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0613711 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
13712 MockRead(SYNCHRONOUS, "hello world"),
13713 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3813714 };
13715
[email protected]8e6441ca2010-08-19 05:56:3813716 HttpRequestInfo request;
13717 request.method = "GET";
bncce36dca22015-04-21 22:11:2313718 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1013719 request.traffic_annotation =
13720 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8e6441ca2010-08-19 05:56:3813721
[email protected]bb88e1d32013-05-03 23:11:0713722 session_deps_.host_resolver->set_synchronous_mode(true);
danakj1fd259a02016-04-16 03:17:0913723 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5813724 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1913725 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2713726
Ryan Sleevib8d7ea02018-05-07 20:01:0113727 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]8e6441ca2010-08-19 05:56:3813728 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0713729 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3813730
[email protected]49639fa2011-12-20 23:22:4113731 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3813732
vishal.b62985ca92015-04-17 08:45:5113733 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4113734 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113735 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8e6441ca2010-08-19 05:56:3813736 trans.reset(); // Cancel the transaction here.
13737
fdoray92e35a72016-06-10 15:54:5513738 base::RunLoop().RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3013739}
13740
[email protected]ecab6e052014-05-16 14:58:1213741// Test that if a transaction is cancelled after receiving the headers, the
13742// stream is drained properly and added back to the socket pool. The main
13743// purpose of this test is to make sure that an HttpStreamParser can be read
13744// from after the HttpNetworkTransaction and the objects it owns have been
13745// deleted.
13746// See http://crbug.com/368418
bncd16676a2016-07-20 16:23:0113747TEST_F(HttpNetworkTransactionTest, CancelAfterHeaders) {
[email protected]ecab6e052014-05-16 14:58:1213748 MockRead data_reads[] = {
13749 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
13750 MockRead(ASYNC, "Content-Length: 2\r\n"),
13751 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
13752 MockRead(ASYNC, "1"),
13753 // 2 async reads are necessary to trigger a ReadResponseBody call after the
13754 // HttpNetworkTransaction has been deleted.
13755 MockRead(ASYNC, "2"),
13756 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
13757 };
Ryan Sleevib8d7ea02018-05-07 20:01:0113758 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]ecab6e052014-05-16 14:58:1213759 session_deps_.socket_factory->AddSocketDataProvider(&data);
13760
danakj1fd259a02016-04-16 03:17:0913761 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]ecab6e052014-05-16 14:58:1213762
13763 {
13764 HttpRequestInfo request;
13765 request.method = "GET";
bncce36dca22015-04-21 22:11:2313766 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1013767 request.traffic_annotation =
13768 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ecab6e052014-05-16 14:58:1213769
dcheng48459ac22014-08-26 00:46:4113770 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1213771 TestCompletionCallback callback;
13772
tfarina42834112016-09-22 13:38:2013773 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113774 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ecab6e052014-05-16 14:58:1213775 callback.WaitForResult();
13776
13777 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213778 ASSERT_TRUE(response);
13779 EXPECT_TRUE(response->headers);
[email protected]ecab6e052014-05-16 14:58:1213780 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13781
13782 // The transaction and HttpRequestInfo are deleted.
13783 }
13784
13785 // Let the HttpResponseBodyDrainer drain the socket.
fdoray92e35a72016-06-10 15:54:5513786 base::RunLoop().RunUntilIdle();
[email protected]ecab6e052014-05-16 14:58:1213787
13788 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4113789 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1213790}
13791
[email protected]76a505b2010-08-25 06:23:0013792// Test a basic GET request through a proxy.
bncd16676a2016-07-20 16:23:0113793TEST_F(HttpNetworkTransactionTest, ProxyGet) {
Lily Houghton8c2f97d2018-01-22 05:06:5913794 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4913795 ProxyResolutionService::CreateFixedFromPacResult(
13796 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5113797 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713798 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913799 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0013800
[email protected]76a505b2010-08-25 06:23:0013801 HttpRequestInfo request;
13802 request.method = "GET";
bncce36dca22015-04-21 22:11:2313803 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1013804 request.traffic_annotation =
13805 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0013806
13807 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2313808 MockWrite(
13809 "GET http://www.example.org/ HTTP/1.1\r\n"
13810 "Host: www.example.org\r\n"
13811 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013812 };
13813
13814 MockRead data_reads1[] = {
13815 MockRead("HTTP/1.1 200 OK\r\n"),
13816 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
13817 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0613818 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0013819 };
13820
Ryan Sleevib8d7ea02018-05-07 20:01:0113821 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:0713822 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0013823
[email protected]49639fa2011-12-20 23:22:4113824 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0013825
bnc691fda62016-08-12 00:43:1613826 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0913827 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1613828 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0913829 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
13830 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5013831
bnc691fda62016-08-12 00:43:1613832 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113833 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0013834
13835 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113836 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:0013837
bnc691fda62016-08-12 00:43:1613838 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213839 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0013840
13841 EXPECT_TRUE(response->headers->IsKeepAlive());
13842 EXPECT_EQ(200, response->headers->response_code());
13843 EXPECT_EQ(100, response->headers->GetContentLength());
13844 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4713845 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
13846 HostPortPair::FromString("myproxy:70")),
13847 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0913848 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
13849 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
13850 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0013851 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2013852
13853 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1613854 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2013855 TestLoadTimingNotReusedWithPac(load_timing_info,
13856 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0013857}
13858
13859// Test a basic HTTPS GET request through a proxy.
bncd16676a2016-07-20 16:23:0113860TEST_F(HttpNetworkTransactionTest, ProxyTunnelGet) {
Lily Houghton8c2f97d2018-01-22 05:06:5913861 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4913862 ProxyResolutionService::CreateFixedFromPacResult(
13863 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5113864 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713865 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913866 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0013867
[email protected]76a505b2010-08-25 06:23:0013868 HttpRequestInfo request;
13869 request.method = "GET";
bncce36dca22015-04-21 22:11:2313870 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1013871 request.traffic_annotation =
13872 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0013873
13874 // Since we have proxy, should try to establish tunnel.
13875 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1713876 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
13877 "Host: www.example.org:443\r\n"
13878 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013879
rsleevidb16bb02015-11-12 23:47:1713880 MockWrite("GET / HTTP/1.1\r\n"
13881 "Host: www.example.org\r\n"
13882 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013883 };
13884
13885 MockRead data_reads1[] = {
13886 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
13887
13888 MockRead("HTTP/1.1 200 OK\r\n"),
13889 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
13890 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0613891 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0013892 };
13893
Ryan Sleevib8d7ea02018-05-07 20:01:0113894 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:0713895 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0613896 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0713897 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0013898
[email protected]49639fa2011-12-20 23:22:4113899 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0013900
bnc691fda62016-08-12 00:43:1613901 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0913902 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1613903 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0913904 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
13905 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5013906
bnc691fda62016-08-12 00:43:1613907 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113908 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0013909
13910 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113911 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:4613912 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4013913 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0013914 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0013915 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
13916 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013917 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4013918 entries, pos,
mikecirone8b85c432016-09-08 19:11:0013919 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
13920 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013921
bnc691fda62016-08-12 00:43:1613922 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213923 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0013924
13925 EXPECT_TRUE(response->headers->IsKeepAlive());
13926 EXPECT_EQ(200, response->headers->response_code());
13927 EXPECT_EQ(100, response->headers->GetContentLength());
13928 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
13929 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4713930 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
13931 HostPortPair::FromString("myproxy:70")),
13932 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0913933 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
13934 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
13935 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]029c83b62013-01-24 05:28:2013936
13937 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1613938 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2013939 TestLoadTimingNotReusedWithPac(load_timing_info,
13940 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0013941}
13942
rsleevidb16bb02015-11-12 23:47:1713943// Test a basic HTTPS GET request through a proxy, connecting to an IPv6
13944// literal host.
bncd16676a2016-07-20 16:23:0113945TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetIPv6) {
Lily Houghton8c2f97d2018-01-22 05:06:5913946 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4913947 ProxyResolutionService::CreateFixedFromPacResult(
13948 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
rsleevidb16bb02015-11-12 23:47:1713949 BoundTestNetLog log;
13950 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913951 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
rsleevidb16bb02015-11-12 23:47:1713952
13953 HttpRequestInfo request;
13954 request.method = "GET";
13955 request.url = GURL("https://[::1]:443/");
Ramin Halavatib5e433e62018-02-07 07:41:1013956 request.traffic_annotation =
13957 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rsleevidb16bb02015-11-12 23:47:1713958
13959 // Since we have proxy, should try to establish tunnel.
13960 MockWrite data_writes1[] = {
13961 MockWrite("CONNECT [::1]:443 HTTP/1.1\r\n"
13962 "Host: [::1]:443\r\n"
13963 "Proxy-Connection: keep-alive\r\n\r\n"),
13964
13965 MockWrite("GET / HTTP/1.1\r\n"
13966 "Host: [::1]\r\n"
13967 "Connection: keep-alive\r\n\r\n"),
13968 };
13969
13970 MockRead data_reads1[] = {
13971 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
13972
13973 MockRead("HTTP/1.1 200 OK\r\n"),
13974 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
13975 MockRead("Content-Length: 100\r\n\r\n"),
13976 MockRead(SYNCHRONOUS, OK),
13977 };
13978
Ryan Sleevib8d7ea02018-05-07 20:01:0113979 StaticSocketDataProvider data1(data_reads1, data_writes1);
rsleevidb16bb02015-11-12 23:47:1713980 session_deps_.socket_factory->AddSocketDataProvider(&data1);
13981 SSLSocketDataProvider ssl(ASYNC, OK);
13982 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13983
13984 TestCompletionCallback callback1;
13985
bnc691fda62016-08-12 00:43:1613986 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
rsleevidb16bb02015-11-12 23:47:1713987
bnc691fda62016-08-12 00:43:1613988 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113989 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rsleevidb16bb02015-11-12 23:47:1713990
13991 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113992 EXPECT_THAT(rv, IsOk());
rsleevidb16bb02015-11-12 23:47:1713993 TestNetLogEntry::List entries;
13994 log.GetEntries(&entries);
13995 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0013996 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
13997 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1713998 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0013999 entries, pos,
14000 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
14001 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1714002
bnc691fda62016-08-12 00:43:1614003 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214004 ASSERT_TRUE(response);
rsleevidb16bb02015-11-12 23:47:1714005
14006 EXPECT_TRUE(response->headers->IsKeepAlive());
14007 EXPECT_EQ(200, response->headers->response_code());
14008 EXPECT_EQ(100, response->headers->GetContentLength());
14009 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
14010 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4714011 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
14012 HostPortPair::FromString("myproxy:70")),
14013 response->proxy_server);
rsleevidb16bb02015-11-12 23:47:1714014
14015 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1614016 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
rsleevidb16bb02015-11-12 23:47:1714017 TestLoadTimingNotReusedWithPac(load_timing_info,
14018 CONNECT_TIMING_HAS_SSL_TIMES);
14019}
14020
[email protected]76a505b2010-08-25 06:23:0014021// Test a basic HTTPS GET request through a proxy, but the server hangs up
14022// while establishing the tunnel.
bncd16676a2016-07-20 16:23:0114023TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
Ramin Halavatica8d5252018-03-12 05:33:4914024 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
14025 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5114026 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714027 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0914028 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0014029
[email protected]76a505b2010-08-25 06:23:0014030 HttpRequestInfo request;
14031 request.method = "GET";
bncce36dca22015-04-21 22:11:2314032 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1014033 request.traffic_annotation =
14034 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0014035
14036 // Since we have proxy, should try to establish tunnel.
14037 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1714038 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
14039 "Host: www.example.org:443\r\n"
14040 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014041
rsleevidb16bb02015-11-12 23:47:1714042 MockWrite("GET / HTTP/1.1\r\n"
14043 "Host: www.example.org\r\n"
14044 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014045 };
14046
14047 MockRead data_reads1[] = {
[email protected]76a505b2010-08-25 06:23:0014048 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0614049 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0014050 };
14051
Ryan Sleevib8d7ea02018-05-07 20:01:0114052 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:0714053 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0614054 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0714055 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0014056
[email protected]49639fa2011-12-20 23:22:4114057 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0014058
bnc691fda62016-08-12 00:43:1614059 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5014060
bnc691fda62016-08-12 00:43:1614061 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114062 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0014063
14064 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0114065 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
mmenke43758e62015-05-04 21:09:4614066 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4014067 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0014068 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014069 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
14070 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0014071 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4014072 entries, pos,
mikecirone8b85c432016-09-08 19:11:0014073 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
14074 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0014075}
14076
[email protected]749eefa82010-09-13 22:14:0314077// Test for crbug.com/55424.
bncd16676a2016-07-20 16:23:0114078TEST_F(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
Ryan Hamilton0239aac2018-05-19 00:03:1314079 spdy::SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4914080 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4114081 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]749eefa82010-09-13 22:14:0314082
Ryan Hamilton0239aac2018-05-19 00:03:1314083 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
14084 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0314085 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114086 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0314087 };
14088
Ryan Sleevib8d7ea02018-05-07 20:01:0114089 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0714090 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0314091
[email protected]8ddf8322012-02-23 18:08:0614092 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614093 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0714094 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0314095
danakj1fd259a02016-04-16 03:17:0914096 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0314097
14098 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2314099 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4014100 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
Paul Jensena457017a2018-01-19 23:52:0414101 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]795cbf82013-07-22 09:37:2714102 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:5214103 CreateSpdySession(session.get(), key, NetLogWithSource());
[email protected]749eefa82010-09-13 22:14:0314104
14105 HttpRequestInfo request;
14106 request.method = "GET";
bncce36dca22015-04-21 22:11:2314107 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1014108 request.traffic_annotation =
14109 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]749eefa82010-09-13 22:14:0314110
bnc691fda62016-08-12 00:43:1614111 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]749eefa82010-09-13 22:14:0314112
[email protected]41d64e82013-07-03 22:44:2614113 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014114 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114115 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14116 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]749eefa82010-09-13 22:14:0314117}
14118
[email protected]73b8dd222010-11-11 19:55:2414119// Given a net error, cause that error to be returned from the first Write()
bnc691fda62016-08-12 00:43:1614120// call and verify that the HttpNetworkTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0214121void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0714122 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2914123 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2714124 request_info.url = GURL("https://www.example.com/");
14125 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914126 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:1014127 request_info.traffic_annotation =
14128 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2714129
[email protected]8ddf8322012-02-23 18:08:0614130 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2914131 MockWrite data_writes[] = {
14132 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2414133 };
Ryan Sleevib8d7ea02018-05-07 20:01:0114134 StaticSocketDataProvider data(base::span<MockRead>(), data_writes);
[email protected]bb88e1d32013-05-03 23:11:0714135 session_deps_.socket_factory->AddSocketDataProvider(&data);
14136 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2414137
danakj1fd259a02016-04-16 03:17:0914138 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614139 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]73b8dd222010-11-11 19:55:2414140
[email protected]49639fa2011-12-20 23:22:4114141 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014142 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
ttuttle859dc7a2015-04-23 19:42:2914143 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2414144 rv = callback.WaitForResult();
14145 ASSERT_EQ(error, rv);
14146}
14147
bncd16676a2016-07-20 16:23:0114148TEST_F(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2414149 // Just check a grab bag of cert errors.
14150 static const int kErrors[] = {
14151 ERR_CERT_COMMON_NAME_INVALID,
14152 ERR_CERT_AUTHORITY_INVALID,
14153 ERR_CERT_DATE_INVALID,
14154 };
14155 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0614156 CheckErrorIsPassedBack(kErrors[i], ASYNC);
14157 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2414158 }
14159}
14160
[email protected]bd0b6772011-01-11 19:59:3014161// Ensure that a client certificate is removed from the SSL client auth
14162// cache when:
14163// 1) No proxy is involved.
14164// 2) TLS False Start is disabled.
14165// 3) The initial TLS handshake requests a client certificate.
14166// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0114167TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_NoFalseStart) {
ttuttle859dc7a2015-04-23 19:42:2914168 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2714169 request_info.url = GURL("https://www.example.com/");
14170 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914171 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:1014172 request_info.traffic_annotation =
14173 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2714174
[email protected]bd0b6772011-01-11 19:59:3014175 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4114176 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3014177
14178 // [ssl_]data1 contains the data for the first SSL handshake. When a
14179 // CertificateRequest is received for the first time, the handshake will
14180 // be aborted to allow the caller to provide a certificate.
ttuttle859dc7a2015-04-23 19:42:2914181 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3014182 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714183 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
Ryan Sleevib8d7ea02018-05-07 20:01:0114184 StaticSocketDataProvider data1;
[email protected]bb88e1d32013-05-03 23:11:0714185 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3014186
14187 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
14188 // False Start is not being used, the result of the SSL handshake will be
14189 // returned as part of the SSLClientSocket::Connect() call. This test
14190 // matches the result of a server sending a handshake_failure alert,
14191 // rather than a Finished message, because it requires a client
14192 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2914193 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3014194 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714195 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
Ryan Sleevib8d7ea02018-05-07 20:01:0114196 StaticSocketDataProvider data2;
[email protected]bb88e1d32013-05-03 23:11:0714197 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3014198
14199 // [ssl_]data3 contains the data for the third SSL handshake. When a
14200 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4214201 // HttpNetworkTransaction will attempt to fallback to TLSv1.1 if the previous
14202 // connection was attempted with TLSv1.2. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3014203 // of the HttpNetworkTransaction. Because this test failure is due to
14204 // requiring a client certificate, this fallback handshake should also
14205 // fail.
ttuttle859dc7a2015-04-23 19:42:2914206 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3014207 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714208 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
Ryan Sleevib8d7ea02018-05-07 20:01:0114209 StaticSocketDataProvider data3;
[email protected]bb88e1d32013-05-03 23:11:0714210 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3014211
[email protected]80c75f682012-05-26 16:22:1714212 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
14213 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4214214 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
14215 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]80c75f682012-05-26 16:22:1714216 // of the HttpNetworkTransaction. Because this test failure is due to
14217 // requiring a client certificate, this fallback handshake should also
14218 // fail.
ttuttle859dc7a2015-04-23 19:42:2914219 SSLSocketDataProvider ssl_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1714220 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714221 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
Ryan Sleevib8d7ea02018-05-07 20:01:0114222 StaticSocketDataProvider data4;
[email protected]bb88e1d32013-05-03 23:11:0714223 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1714224
danakj1fd259a02016-04-16 03:17:0914225 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614226 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3014227
[email protected]bd0b6772011-01-11 19:59:3014228 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4114229 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014230 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114231 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3014232
14233 // Complete the SSL handshake, which should abort due to requiring a
14234 // client certificate.
14235 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114236 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3014237
14238 // Indicate that no certificate should be supplied. From the perspective
14239 // of SSLClientCertCache, NULL is just as meaningful as a real
14240 // certificate, so this is the same as supply a
14241 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1614242 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0114243 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3014244
14245 // Ensure the certificate was added to the client auth cache before
14246 // allowing the connection to continue restarting.
14247 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5414248 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4114249 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414250 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5214251 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3014252
14253 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1714254 // then consume ssl_data3 and ssl_data4, both of which should also fail.
14255 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3014256 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114257 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3014258
14259 // Ensure that the client certificate is removed from the cache on a
14260 // handshake failure.
[email protected]791879c2013-12-17 07:22:4114261 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414262 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3014263}
14264
14265// Ensure that a client certificate is removed from the SSL client auth
14266// cache when:
14267// 1) No proxy is involved.
14268// 2) TLS False Start is enabled.
14269// 3) The initial TLS handshake requests a client certificate.
14270// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0114271TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2914272 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2714273 request_info.url = GURL("https://www.example.com/");
14274 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914275 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:1014276 request_info.traffic_annotation =
14277 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2714278
[email protected]bd0b6772011-01-11 19:59:3014279 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4114280 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3014281
14282 // When TLS False Start is used, SSLClientSocket::Connect() calls will
14283 // return successfully after reading up to the peer's Certificate message.
14284 // This is to allow the caller to call SSLClientSocket::Write(), which can
14285 // enqueue application data to be sent in the same packet as the
14286 // ChangeCipherSpec and Finished messages.
14287 // The actual handshake will be finished when SSLClientSocket::Read() is
14288 // called, which expects to process the peer's ChangeCipherSpec and
14289 // Finished messages. If there was an error negotiating with the peer,
14290 // such as due to the peer requiring a client certificate when none was
14291 // supplied, the alert sent by the peer won't be processed until Read() is
14292 // called.
14293
14294 // Like the non-False Start case, when a client certificate is requested by
14295 // the peer, the handshake is aborted during the Connect() call.
14296 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2914297 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3014298 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714299 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
Ryan Sleevib8d7ea02018-05-07 20:01:0114300 StaticSocketDataProvider data1;
[email protected]bb88e1d32013-05-03 23:11:0714301 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3014302
14303 // When a client certificate is supplied, Connect() will not be aborted
14304 // when the peer requests the certificate. Instead, the handshake will
14305 // artificially succeed, allowing the caller to write the HTTP request to
14306 // the socket. The handshake messages are not processed until Read() is
14307 // called, which then detects that the handshake was aborted, due to the
14308 // peer sending a handshake_failure because it requires a client
14309 // certificate.
ttuttle859dc7a2015-04-23 19:42:2914310 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3014311 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714312 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2914313 MockRead data2_reads[] = {
14314 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3014315 };
Ryan Sleevib8d7ea02018-05-07 20:01:0114316 StaticSocketDataProvider data2(data2_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0714317 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3014318
14319 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1714320 // the data for the SSL handshake once the TLSv1.1 connection falls back to
14321 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2914322 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3014323 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714324 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
Ryan Sleevib8d7ea02018-05-07 20:01:0114325 StaticSocketDataProvider data3(data2_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0714326 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3014327
[email protected]80c75f682012-05-26 16:22:1714328 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
14329 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2914330 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1714331 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714332 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
Ryan Sleevib8d7ea02018-05-07 20:01:0114333 StaticSocketDataProvider data4(data2_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0714334 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1714335
[email protected]7799de12013-05-30 05:52:5114336 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2914337 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5114338 ssl_data5.cert_request_info = cert_request.get();
14339 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
Ryan Sleevib8d7ea02018-05-07 20:01:0114340 StaticSocketDataProvider data5(data2_reads, base::span<MockWrite>());
[email protected]7799de12013-05-30 05:52:5114341 session_deps_.socket_factory->AddSocketDataProvider(&data5);
14342
danakj1fd259a02016-04-16 03:17:0914343 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614344 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3014345
[email protected]bd0b6772011-01-11 19:59:3014346 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4114347 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014348 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114349 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3014350
14351 // Complete the SSL handshake, which should abort due to requiring a
14352 // client certificate.
14353 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114354 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3014355
14356 // Indicate that no certificate should be supplied. From the perspective
14357 // of SSLClientCertCache, NULL is just as meaningful as a real
14358 // certificate, so this is the same as supply a
14359 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1614360 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0114361 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3014362
14363 // Ensure the certificate was added to the client auth cache before
14364 // allowing the connection to continue restarting.
14365 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5414366 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4114367 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414368 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5214369 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3014370
[email protected]bd0b6772011-01-11 19:59:3014371 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1714372 // then consume ssl_data3 and ssl_data4, both of which should also fail.
14373 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3014374 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114375 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3014376
14377 // Ensure that the client certificate is removed from the cache on a
14378 // handshake failure.
[email protected]791879c2013-12-17 07:22:4114379 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414380 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3014381}
14382
[email protected]8c405132011-01-11 22:03:1814383// Ensure that a client certificate is removed from the SSL client auth
14384// cache when:
14385// 1) An HTTPS proxy is involved.
14386// 3) The HTTPS proxy requests a client certificate.
14387// 4) The client supplies an invalid/unacceptable certificate for the
14388// proxy.
14389// The test is repeated twice, first for connecting to an HTTPS endpoint,
14390// then for connecting to an HTTP endpoint.
bncd16676a2016-07-20 16:23:0114391TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
Ramin Halavatica8d5252018-03-12 05:33:4914392 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
14393 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5114394 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714395 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1814396
14397 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4114398 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1814399
14400 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
14401 // [ssl_]data[1-3]. Rather than represending the endpoint
14402 // (www.example.com:443), they represent failures with the HTTPS proxy
14403 // (proxy:70).
ttuttle859dc7a2015-04-23 19:42:2914404 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1814405 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714406 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
Ryan Sleevib8d7ea02018-05-07 20:01:0114407 StaticSocketDataProvider data1;
[email protected]bb88e1d32013-05-03 23:11:0714408 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1814409
ttuttle859dc7a2015-04-23 19:42:2914410 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1814411 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714412 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
Ryan Sleevib8d7ea02018-05-07 20:01:0114413 StaticSocketDataProvider data2;
[email protected]bb88e1d32013-05-03 23:11:0714414 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1814415
[email protected]80c75f682012-05-26 16:22:1714416 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
14417#if 0
ttuttle859dc7a2015-04-23 19:42:2914418 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1814419 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714420 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
Ryan Sleevib8d7ea02018-05-07 20:01:0114421 StaticSocketDataProvider data3;
[email protected]bb88e1d32013-05-03 23:11:0714422 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1714423#endif
[email protected]8c405132011-01-11 22:03:1814424
ttuttle859dc7a2015-04-23 19:42:2914425 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1814426 requests[0].url = GURL("https://www.example.com/");
14427 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914428 requests[0].load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:1014429 requests[0].traffic_annotation =
14430 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c405132011-01-11 22:03:1814431
14432 requests[1].url = GURL("http://www.example.com/");
14433 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914434 requests[1].load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:1014435 requests[1].traffic_annotation =
14436 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c405132011-01-11 22:03:1814437
14438 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0714439 session_deps_.socket_factory->ResetNextMockIndexes();
danakj1fd259a02016-04-16 03:17:0914440 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614441 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]8c405132011-01-11 22:03:1814442
14443 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4114444 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014445 int rv = trans.Start(&requests[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114446 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1814447
14448 // Complete the SSL handshake, which should abort due to requiring a
14449 // client certificate.
14450 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114451 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]8c405132011-01-11 22:03:1814452
14453 // Indicate that no certificate should be supplied. From the perspective
14454 // of SSLClientCertCache, NULL is just as meaningful as a real
14455 // certificate, so this is the same as supply a
14456 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1614457 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0114458 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1814459
14460 // Ensure the certificate was added to the client auth cache before
14461 // allowing the connection to continue restarting.
14462 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5414463 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4114464 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414465 HostPortPair("proxy", 70), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5214466 ASSERT_FALSE(client_cert);
[email protected]8c405132011-01-11 22:03:1814467 // Ensure the certificate was NOT cached for the endpoint. This only
14468 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4114469 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414470 HostPortPair("www.example.com", 443), &client_cert,
14471 &client_private_key));
[email protected]8c405132011-01-11 22:03:1814472
14473 // Restart the handshake. This will consume ssl_data2, which fails, and
14474 // then consume ssl_data3, which should also fail. The result code is
14475 // checked against what ssl_data3 should return.
14476 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114477 ASSERT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]8c405132011-01-11 22:03:1814478
14479 // Now that the new handshake has failed, ensure that the client
14480 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4114481 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414482 HostPortPair("proxy", 70), &client_cert, &client_private_key));
[email protected]791879c2013-12-17 07:22:4114483 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414484 HostPortPair("www.example.com", 443), &client_cert,
14485 &client_private_key));
[email protected]8c405132011-01-11 22:03:1814486 }
14487}
14488
bncd16676a2016-07-20 16:23:0114489TEST_F(HttpNetworkTransactionTest, UseIPConnectionPooling) {
[email protected]e3ceb682011-06-28 23:55:4614490 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1914491 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0914492 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4614493
bnc032658ba2016-09-26 18:17:1514494 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4614495
Ryan Hamilton0239aac2018-05-19 00:03:1314496 spdy::SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4914497 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3814498 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1314499 spdy::SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3714500 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4614501 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114502 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4614503 };
Ryan Hamilton0239aac2018-05-19 00:03:1314504 spdy::SpdySerializedFrame host1_resp(
14505 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
14506 spdy::SpdySerializedFrame host1_resp_body(
bncdf80d44fd2016-07-15 20:27:4114507 spdy_util_.ConstructSpdyDataFrame(1, true));
Ryan Hamilton0239aac2018-05-19 00:03:1314508 spdy::SpdySerializedFrame host2_resp(
14509 spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
14510 spdy::SpdySerializedFrame host2_resp_body(
bncdf80d44fd2016-07-15 20:27:4114511 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4614512 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114513 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
14514 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1314515 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4614516 };
14517
eroman36d84e54432016-03-17 03:23:0214518 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0214519 MockConnect connect(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0114520 SequencedSocketData spdy_data(connect, spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0714521 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4614522
[email protected]aa22b242011-11-16 18:58:2914523 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4614524 HttpRequestInfo request1;
14525 request1.method = "GET";
bncce36dca22015-04-21 22:11:2314526 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4614527 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1014528 request1.traffic_annotation =
14529 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5014530 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4614531
tfarina42834112016-09-22 13:38:2014532 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114533 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14534 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614535
14536 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5214537 ASSERT_TRUE(response);
14538 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214539 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4614540
14541 std::string response_data;
robpercival214763f2016-07-01 23:27:0114542 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614543 EXPECT_EQ("hello!", response_data);
14544
bnca4d611d2016-09-22 19:55:3714545 // Preload mail.example.com into HostCache.
14546 HostPortPair host_port("mail.example.com", 443);
[email protected]5109c1952013-08-20 18:44:1014547 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4614548 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1014549 std::unique_ptr<HostResolver::Request> request;
14550 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
14551 &ignored, callback.callback(),
tfarina42834112016-09-22 13:38:2014552 &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114553 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4714554 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114555 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4614556
14557 HttpRequestInfo request2;
14558 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3714559 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4614560 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1014561 request2.traffic_annotation =
14562 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5014563 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4614564
tfarina42834112016-09-22 13:38:2014565 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114566 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14567 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614568
14569 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5214570 ASSERT_TRUE(response);
14571 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214572 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4614573 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214574 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114575 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614576 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4614577}
14578
bncd16676a2016-07-20 16:23:0114579TEST_F(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d2b5f092012-06-08 23:55:0214580 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1914581 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0914582 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0214583
bnc032658ba2016-09-26 18:17:1514584 AddSSLSocketData();
[email protected]d2b5f092012-06-08 23:55:0214585
Ryan Hamilton0239aac2018-05-19 00:03:1314586 spdy::SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4914587 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3814588 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1314589 spdy::SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3714590 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0214591 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114592 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0214593 };
Ryan Hamilton0239aac2018-05-19 00:03:1314594 spdy::SpdySerializedFrame host1_resp(
14595 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
14596 spdy::SpdySerializedFrame host1_resp_body(
bncdf80d44fd2016-07-15 20:27:4114597 spdy_util_.ConstructSpdyDataFrame(1, true));
Ryan Hamilton0239aac2018-05-19 00:03:1314598 spdy::SpdySerializedFrame host2_resp(
14599 spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
14600 spdy::SpdySerializedFrame host2_resp_body(
bncdf80d44fd2016-07-15 20:27:4114601 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0214602 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114603 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
14604 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1314605 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0214606 };
14607
eroman36d84e54432016-03-17 03:23:0214608 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0214609 MockConnect connect(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0114610 SequencedSocketData spdy_data(connect, spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0714611 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0214612
14613 TestCompletionCallback callback;
14614 HttpRequestInfo request1;
14615 request1.method = "GET";
bncce36dca22015-04-21 22:11:2314616 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0214617 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1014618 request1.traffic_annotation =
14619 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5014620 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0214621
tfarina42834112016-09-22 13:38:2014622 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114623 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14624 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214625
14626 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5214627 ASSERT_TRUE(response);
14628 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214629 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0214630
14631 std::string response_data;
robpercival214763f2016-07-01 23:27:0114632 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214633 EXPECT_EQ("hello!", response_data);
14634
14635 HttpRequestInfo request2;
14636 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3714637 request2.url = GURL("https://mail.example.com/");
[email protected]d2b5f092012-06-08 23:55:0214638 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1014639 request2.traffic_annotation =
14640 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5014641 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0214642
tfarina42834112016-09-22 13:38:2014643 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114644 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14645 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214646
14647 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5214648 ASSERT_TRUE(response);
14649 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214650 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0214651 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214652 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114653 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214654 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0214655}
14656
bnc8016c1f2017-03-31 02:11:2914657// Regression test for https://crbug.com/546991.
14658// The server might not be able to serve an IP pooled request, and might send a
14659// 421 Misdirected Request response status to indicate this.
14660// HttpNetworkTransaction should reset the request and retry without IP pooling.
14661TEST_F(HttpNetworkTransactionTest, RetryWithoutConnectionPooling) {
14662 // Two hosts resolve to the same IP address.
14663 const std::string ip_addr = "1.2.3.4";
14664 IPAddress ip;
14665 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
14666 IPEndPoint peer_addr = IPEndPoint(ip, 443);
14667
Jeremy Roman0579ed62017-08-29 15:56:1914668 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
bnc8016c1f2017-03-31 02:11:2914669 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
14670 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
14671
14672 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14673
14674 // Two requests on the first connection.
Ryan Hamilton0239aac2018-05-19 00:03:1314675 spdy::SpdySerializedFrame req1(
bnc8016c1f2017-03-31 02:11:2914676 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
14677 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1314678 spdy::SpdySerializedFrame req2(
bnc8016c1f2017-03-31 02:11:2914679 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1314680 spdy::SpdySerializedFrame rst(
14681 spdy_util_.ConstructSpdyRstStream(3, spdy::ERROR_CODE_CANCEL));
bnc8016c1f2017-03-31 02:11:2914682 MockWrite writes1[] = {
14683 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
14684 CreateMockWrite(rst, 6),
14685 };
14686
14687 // The first one succeeds, the second gets error 421 Misdirected Request.
Ryan Hamilton0239aac2018-05-19 00:03:1314688 spdy::SpdySerializedFrame resp1(
14689 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
14690 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
14691 spdy::SpdyHeaderBlock response_headers;
14692 response_headers[spdy::kHttp2StatusHeader] = "421";
14693 spdy::SpdySerializedFrame resp2(
bnc8016c1f2017-03-31 02:11:2914694 spdy_util_.ConstructSpdyReply(3, std::move(response_headers)));
14695 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
14696 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
14697
14698 MockConnect connect1(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0114699 SequencedSocketData data1(connect1, reads1, writes1);
bnc8016c1f2017-03-31 02:11:2914700 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14701
14702 AddSSLSocketData();
14703
14704 // Retry the second request on a second connection.
14705 SpdyTestUtil spdy_util2;
Ryan Hamilton0239aac2018-05-19 00:03:1314706 spdy::SpdySerializedFrame req3(
bnc8016c1f2017-03-31 02:11:2914707 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
14708 MockWrite writes2[] = {
14709 CreateMockWrite(req3, 0),
14710 };
14711
Ryan Hamilton0239aac2018-05-19 00:03:1314712 spdy::SpdySerializedFrame resp3(
14713 spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
14714 spdy::SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
bnc8016c1f2017-03-31 02:11:2914715 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
14716 MockRead(ASYNC, 0, 3)};
14717
14718 MockConnect connect2(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0114719 SequencedSocketData data2(connect2, reads2, writes2);
bnc8016c1f2017-03-31 02:11:2914720 session_deps_.socket_factory->AddSocketDataProvider(&data2);
14721
14722 AddSSLSocketData();
14723
14724 // Preload mail.example.org into HostCache.
14725 HostPortPair host_port("mail.example.org", 443);
14726 HostResolver::RequestInfo resolve_info(host_port);
14727 AddressList ignored;
14728 std::unique_ptr<HostResolver::Request> request;
14729 TestCompletionCallback callback;
14730 int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
14731 &ignored, callback.callback(),
14732 &request, NetLogWithSource());
14733 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14734 rv = callback.WaitForResult();
14735 EXPECT_THAT(rv, IsOk());
14736
14737 HttpRequestInfo request1;
14738 request1.method = "GET";
14739 request1.url = GURL("https://www.example.org/");
14740 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1014741 request1.traffic_annotation =
14742 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8016c1f2017-03-31 02:11:2914743 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
14744
14745 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
14746 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14747 rv = callback.WaitForResult();
14748 EXPECT_THAT(rv, IsOk());
14749
14750 const HttpResponseInfo* response = trans1.GetResponseInfo();
14751 ASSERT_TRUE(response);
14752 ASSERT_TRUE(response->headers);
14753 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
14754 EXPECT_TRUE(response->was_fetched_via_spdy);
14755 EXPECT_TRUE(response->was_alpn_negotiated);
14756 std::string response_data;
14757 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
14758 EXPECT_EQ("hello!", response_data);
14759
14760 HttpRequestInfo request2;
14761 request2.method = "GET";
14762 request2.url = GURL("https://mail.example.org/");
14763 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1014764 request2.traffic_annotation =
14765 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8016c1f2017-03-31 02:11:2914766 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
14767
14768 BoundTestNetLog log;
14769 rv = trans2.Start(&request2, callback.callback(), log.bound());
14770 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14771 rv = callback.WaitForResult();
14772 EXPECT_THAT(rv, IsOk());
14773
14774 response = trans2.GetResponseInfo();
14775 ASSERT_TRUE(response);
14776 ASSERT_TRUE(response->headers);
14777 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
14778 EXPECT_TRUE(response->was_fetched_via_spdy);
14779 EXPECT_TRUE(response->was_alpn_negotiated);
14780 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
14781 EXPECT_EQ("hello!", response_data);
14782
14783 TestNetLogEntry::List entries;
14784 log.GetEntries(&entries);
davidbence688ae2017-05-04 15:12:5914785 ExpectLogContainsSomewhere(
14786 entries, 0, NetLogEventType::HTTP_TRANSACTION_RESTART_MISDIRECTED_REQUEST,
bnc8016c1f2017-03-31 02:11:2914787 NetLogEventPhase::NONE);
davidbence688ae2017-05-04 15:12:5914788}
14789
14790// Test that HTTP 421 responses are properly returned to the caller if received
14791// on the retry as well. HttpNetworkTransaction should not infinite loop or lose
14792// portions of the response.
14793TEST_F(HttpNetworkTransactionTest, ReturnHTTP421OnRetry) {
14794 // Two hosts resolve to the same IP address.
14795 const std::string ip_addr = "1.2.3.4";
14796 IPAddress ip;
14797 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
14798 IPEndPoint peer_addr = IPEndPoint(ip, 443);
14799
Jeremy Roman0579ed62017-08-29 15:56:1914800 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
davidbence688ae2017-05-04 15:12:5914801 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
14802 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
14803
14804 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14805
14806 // Two requests on the first connection.
Ryan Hamilton0239aac2018-05-19 00:03:1314807 spdy::SpdySerializedFrame req1(
davidbence688ae2017-05-04 15:12:5914808 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
14809 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1314810 spdy::SpdySerializedFrame req2(
davidbence688ae2017-05-04 15:12:5914811 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1314812 spdy::SpdySerializedFrame rst(
14813 spdy_util_.ConstructSpdyRstStream(3, spdy::ERROR_CODE_CANCEL));
davidbence688ae2017-05-04 15:12:5914814 MockWrite writes1[] = {
14815 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
14816 CreateMockWrite(rst, 6),
14817 };
14818
14819 // The first one succeeds, the second gets error 421 Misdirected Request.
Ryan Hamilton0239aac2018-05-19 00:03:1314820 spdy::SpdySerializedFrame resp1(
14821 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
14822 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
14823 spdy::SpdyHeaderBlock response_headers;
14824 response_headers[spdy::kHttp2StatusHeader] = "421";
14825 spdy::SpdySerializedFrame resp2(
davidbence688ae2017-05-04 15:12:5914826 spdy_util_.ConstructSpdyReply(3, response_headers.Clone()));
14827 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
14828 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
14829
14830 MockConnect connect1(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0114831 SequencedSocketData data1(connect1, reads1, writes1);
davidbence688ae2017-05-04 15:12:5914832 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14833
14834 AddSSLSocketData();
14835
14836 // Retry the second request on a second connection. It returns 421 Misdirected
14837 // Retry again.
14838 SpdyTestUtil spdy_util2;
Ryan Hamilton0239aac2018-05-19 00:03:1314839 spdy::SpdySerializedFrame req3(
davidbence688ae2017-05-04 15:12:5914840 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
14841 MockWrite writes2[] = {
14842 CreateMockWrite(req3, 0),
14843 };
14844
Ryan Hamilton0239aac2018-05-19 00:03:1314845 spdy::SpdySerializedFrame resp3(
davidbence688ae2017-05-04 15:12:5914846 spdy_util2.ConstructSpdyReply(1, std::move(response_headers)));
Ryan Hamilton0239aac2018-05-19 00:03:1314847 spdy::SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
davidbence688ae2017-05-04 15:12:5914848 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
14849 MockRead(ASYNC, 0, 3)};
14850
14851 MockConnect connect2(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0114852 SequencedSocketData data2(connect2, reads2, writes2);
davidbence688ae2017-05-04 15:12:5914853 session_deps_.socket_factory->AddSocketDataProvider(&data2);
14854
14855 AddSSLSocketData();
14856
14857 // Preload mail.example.org into HostCache.
14858 HostPortPair host_port("mail.example.org", 443);
14859 HostResolver::RequestInfo resolve_info(host_port);
14860 AddressList ignored;
14861 std::unique_ptr<HostResolver::Request> request;
14862 TestCompletionCallback callback;
14863 int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
14864 &ignored, callback.callback(),
14865 &request, NetLogWithSource());
14866 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14867 rv = callback.WaitForResult();
14868 EXPECT_THAT(rv, IsOk());
14869
14870 HttpRequestInfo request1;
14871 request1.method = "GET";
14872 request1.url = GURL("https://www.example.org/");
14873 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1014874 request1.traffic_annotation =
14875 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
davidbence688ae2017-05-04 15:12:5914876 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
14877
14878 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
14879 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14880 rv = callback.WaitForResult();
14881 EXPECT_THAT(rv, IsOk());
14882
14883 const HttpResponseInfo* response = trans1.GetResponseInfo();
14884 ASSERT_TRUE(response);
14885 ASSERT_TRUE(response->headers);
14886 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
14887 EXPECT_TRUE(response->was_fetched_via_spdy);
14888 EXPECT_TRUE(response->was_alpn_negotiated);
14889 std::string response_data;
14890 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
14891 EXPECT_EQ("hello!", response_data);
14892
14893 HttpRequestInfo request2;
14894 request2.method = "GET";
14895 request2.url = GURL("https://mail.example.org/");
14896 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1014897 request2.traffic_annotation =
14898 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
davidbence688ae2017-05-04 15:12:5914899 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
14900
14901 BoundTestNetLog log;
14902 rv = trans2.Start(&request2, callback.callback(), log.bound());
14903 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14904 rv = callback.WaitForResult();
14905 EXPECT_THAT(rv, IsOk());
14906
14907 // After a retry, the 421 Misdirected Request is reported back up to the
14908 // caller.
14909 response = trans2.GetResponseInfo();
14910 ASSERT_TRUE(response);
14911 ASSERT_TRUE(response->headers);
14912 EXPECT_EQ("HTTP/1.1 421", response->headers->GetStatusLine());
14913 EXPECT_TRUE(response->was_fetched_via_spdy);
14914 EXPECT_TRUE(response->was_alpn_negotiated);
14915 EXPECT_TRUE(response->ssl_info.cert);
14916 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
14917 EXPECT_EQ("hello!", response_data);
bnc8016c1f2017-03-31 02:11:2914918}
14919
bnc6dcd8192017-05-25 20:11:5014920class OneTimeCachingHostResolver : public MockHostResolverBase {
[email protected]e3ceb682011-06-28 23:55:4614921 public:
14922 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
bnc6dcd8192017-05-25 20:11:5014923 : MockHostResolverBase(/* use_caching = */ true), host_port_(host_port) {}
Chris Watkins7a41d3552017-12-01 02:13:2714924 ~OneTimeCachingHostResolver() override = default;
[email protected]e3ceb682011-06-28 23:55:4614925
dchengb03027d2014-10-21 12:00:2014926 int ResolveFromCache(const RequestInfo& info,
14927 AddressList* addresses,
tfarina42834112016-09-22 13:38:2014928 const NetLogWithSource& net_log) override {
bnc6dcd8192017-05-25 20:11:5014929 int rv = MockHostResolverBase::ResolveFromCache(info, addresses, net_log);
[email protected]95a214c2011-08-04 21:50:4014930 if (rv == OK && info.host_port_pair().Equals(host_port_))
bnc6dcd8192017-05-25 20:11:5014931 GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4614932 return rv;
14933 }
14934
[email protected]e3ceb682011-06-28 23:55:4614935 private:
[email protected]e3ceb682011-06-28 23:55:4614936 const HostPortPair host_port_;
14937};
14938
bncd16676a2016-07-20 16:23:0114939TEST_F(HttpNetworkTransactionTest,
mmenke5c642132015-06-02 16:05:1314940 UseIPConnectionPoolingWithHostCacheExpiration) {
[email protected]e3ceb682011-06-28 23:55:4614941 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1914942 session_deps_.host_resolver = std::make_unique<OneTimeCachingHostResolver>(
bnca4d611d2016-09-22 19:55:3714943 HostPortPair("mail.example.com", 443));
danakj1fd259a02016-04-16 03:17:0914944 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4614945
bnc032658ba2016-09-26 18:17:1514946 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4614947
Ryan Hamilton0239aac2018-05-19 00:03:1314948 spdy::SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4914949 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3814950 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1314951 spdy::SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3714952 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4614953 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114954 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4614955 };
Ryan Hamilton0239aac2018-05-19 00:03:1314956 spdy::SpdySerializedFrame host1_resp(
14957 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
14958 spdy::SpdySerializedFrame host1_resp_body(
bncdf80d44fd2016-07-15 20:27:4114959 spdy_util_.ConstructSpdyDataFrame(1, true));
Ryan Hamilton0239aac2018-05-19 00:03:1314960 spdy::SpdySerializedFrame host2_resp(
14961 spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
14962 spdy::SpdySerializedFrame host2_resp_body(
bncdf80d44fd2016-07-15 20:27:4114963 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4614964 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114965 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
14966 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1314967 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4614968 };
14969
eroman36d84e54432016-03-17 03:23:0214970 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0214971 MockConnect connect(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0114972 SequencedSocketData spdy_data(connect, spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0714973 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4614974
[email protected]aa22b242011-11-16 18:58:2914975 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4614976 HttpRequestInfo request1;
14977 request1.method = "GET";
bncce36dca22015-04-21 22:11:2314978 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4614979 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1014980 request1.traffic_annotation =
14981 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5014982 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4614983
tfarina42834112016-09-22 13:38:2014984 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114985 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14986 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614987
14988 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5214989 ASSERT_TRUE(response);
14990 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214991 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4614992
14993 std::string response_data;
robpercival214763f2016-07-01 23:27:0114994 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614995 EXPECT_EQ("hello!", response_data);
14996
14997 // Preload cache entries into HostCache.
bnca4d611d2016-09-22 19:55:3714998 HostResolver::RequestInfo resolve_info(HostPortPair("mail.example.com", 443));
[email protected]e3ceb682011-06-28 23:55:4614999 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1015000 std::unique_ptr<HostResolver::Request> request;
bnc6dcd8192017-05-25 20:11:5015001 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
15002 &ignored, callback.callback(),
15003 &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115004 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4715005 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115006 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4615007
15008 HttpRequestInfo request2;
15009 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3715010 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4615011 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015012 request2.traffic_annotation =
15013 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015014 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4615015
tfarina42834112016-09-22 13:38:2015016 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115017 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15018 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615019
15020 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215021 ASSERT_TRUE(response);
15022 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215023 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4615024 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215025 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115026 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615027 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4615028}
15029
bncd16676a2016-07-20 16:23:0115030TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2315031 const std::string https_url = "https://www.example.org:8080/";
15032 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0415033
15034 // SPDY GET for HTTPS URL
Ryan Hamilton0239aac2018-05-19 00:03:1315035 spdy::SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4915036 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0415037
15038 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4115039 CreateMockWrite(req1, 0),
[email protected]8450d722012-07-02 19:14:0415040 };
15041
Ryan Hamilton0239aac2018-05-19 00:03:1315042 spdy::SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
15043 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
bncdf80d44fd2016-07-15 20:27:4115044 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
mmenkee24011922015-12-17 22:12:5915045 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)};
[email protected]8450d722012-07-02 19:14:0415046
Ryan Sleevib8d7ea02018-05-07 20:01:0115047 SequencedSocketData data1(reads1, writes1);
[email protected]8450d722012-07-02 19:14:0415048 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5715049 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0415050
15051 // HTTP GET for the HTTP URL
15052 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1315053 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3415054 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2315055 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3415056 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0415057 };
15058
15059 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1315060 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
15061 MockRead(ASYNC, 2, "hello"),
15062 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0415063 };
15064
Ryan Sleevib8d7ea02018-05-07 20:01:0115065 SequencedSocketData data2(reads2, writes2);
[email protected]8450d722012-07-02 19:14:0415066
[email protected]8450d722012-07-02 19:14:0415067 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615068 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0715069 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15070 session_deps_.socket_factory->AddSocketDataProvider(&data1);
15071 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0415072
danakj1fd259a02016-04-16 03:17:0915073 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0415074
15075 // Start the first transaction to set up the SpdySession
15076 HttpRequestInfo request1;
15077 request1.method = "GET";
15078 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0415079 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015080 request1.traffic_annotation =
15081 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015082 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0415083 TestCompletionCallback callback1;
15084 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015085 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5515086 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0415087
robpercival214763f2016-07-01 23:27:0115088 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0415089 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
15090
15091 // Now, start the HTTP request
15092 HttpRequestInfo request2;
15093 request2.method = "GET";
15094 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0415095 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015096 request2.traffic_annotation =
15097 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015098 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0415099 TestCompletionCallback callback2;
15100 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015101 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5515102 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0415103
robpercival214763f2016-07-01 23:27:0115104 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0415105 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
15106}
15107
bnc5452e2a2015-05-08 16:27:4215108// Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
15109// with the alternative server. That connection should not be used.
bncd16676a2016-07-20 16:23:0115110TEST_F(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
bnc8bef8da22016-05-30 01:28:2515111 url::SchemeHostPort server("https", "www.example.org", 443);
15112 HostPortPair alternative("www.example.org", 444);
bnc5452e2a2015-05-08 16:27:4215113
bnc8bef8da22016-05-30 01:28:2515114 // Negotiate HTTP/1.1 with alternative.
bnc5452e2a2015-05-08 16:27:4215115 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615116 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4215117 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15118
15119 // No data should be read from the alternative, because HTTP/1.1 is
15120 // negotiated.
15121 StaticSocketDataProvider data;
15122 session_deps_.socket_factory->AddSocketDataProvider(&data);
15123
15124 // This test documents that an alternate Job should not be used if HTTP/1.1 is
zhongyi3d4a55e72016-04-22 20:36:4615125 // negotiated. In order to test this, a failed connection to the server is
bnc5452e2a2015-05-08 16:27:4215126 // mocked. This way the request relies on the alternate Job.
15127 StaticSocketDataProvider data_refused;
15128 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
15129 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
15130
zhongyi3d4a55e72016-04-22 20:36:4615131 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0915132 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4015133 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4215134 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2115135 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1215136 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2115137 http_server_properties->SetHttp2AlternativeService(
15138 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4215139
bnc5452e2a2015-05-08 16:27:4215140 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4615141 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4215142 request.method = "GET";
bnc8bef8da22016-05-30 01:28:2515143 request.url = GURL("https://www.example.org:443");
Ramin Halavatib5e433e62018-02-07 07:41:1015144 request.traffic_annotation =
15145 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4215146 TestCompletionCallback callback;
15147
15148 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
bnc94c92842016-09-21 15:22:5215149 // negotiated, the alternate Job should fail with ERR_ALPN_NEGOTIATION_FAILED.
tfarina42834112016-09-22 13:38:2015150 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc94c92842016-09-21 15:22:5215151 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_ALPN_NEGOTIATION_FAILED));
bnc5452e2a2015-05-08 16:27:4215152}
15153
bnc40448a532015-05-11 19:13:1415154// A request to a server with an alternative service fires two Jobs: one to the
zhongyi3d4a55e72016-04-22 20:36:4615155// server, and an alternate one to the alternative server. If the former
bnc40448a532015-05-11 19:13:1415156// succeeds, the request should succeed, even if the latter fails because
15157// HTTP/1.1 is negotiated which is insufficient for alternative service.
bncd16676a2016-07-20 16:23:0115158TEST_F(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
bnc8bef8da22016-05-30 01:28:2515159 url::SchemeHostPort server("https", "www.example.org", 443);
15160 HostPortPair alternative("www.example.org", 444);
bnc40448a532015-05-11 19:13:1415161
15162 // Negotiate HTTP/1.1 with alternative.
15163 SSLSocketDataProvider alternative_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615164 alternative_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1415165 session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
15166
15167 // No data should be read from the alternative, because HTTP/1.1 is
15168 // negotiated.
15169 StaticSocketDataProvider data;
15170 session_deps_.socket_factory->AddSocketDataProvider(&data);
15171
zhongyi3d4a55e72016-04-22 20:36:4615172 // Negotiate HTTP/1.1 with server.
bnc40448a532015-05-11 19:13:1415173 SSLSocketDataProvider origin_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615174 origin_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1415175 session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
15176
15177 MockWrite http_writes[] = {
bnc8bef8da22016-05-30 01:28:2515178 MockWrite("GET / HTTP/1.1\r\n"
15179 "Host: www.example.org\r\n"
15180 "Connection: keep-alive\r\n\r\n"),
15181 MockWrite("GET /second HTTP/1.1\r\n"
15182 "Host: www.example.org\r\n"
15183 "Connection: keep-alive\r\n\r\n"),
bnc40448a532015-05-11 19:13:1415184 };
15185
15186 MockRead http_reads[] = {
15187 MockRead("HTTP/1.1 200 OK\r\n"),
15188 MockRead("Content-Type: text/html\r\n"),
15189 MockRead("Content-Length: 6\r\n\r\n"),
15190 MockRead("foobar"),
15191 MockRead("HTTP/1.1 200 OK\r\n"),
15192 MockRead("Content-Type: text/html\r\n"),
15193 MockRead("Content-Length: 7\r\n\r\n"),
15194 MockRead("another"),
15195 };
Ryan Sleevib8d7ea02018-05-07 20:01:0115196 StaticSocketDataProvider http_data(http_reads, http_writes);
bnc40448a532015-05-11 19:13:1415197 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15198
zhongyi3d4a55e72016-04-22 20:36:4615199 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0915200 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4015201 HttpServerProperties* http_server_properties =
bnc40448a532015-05-11 19:13:1415202 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2115203 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1215204 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2115205 http_server_properties->SetHttp2AlternativeService(
15206 server, alternative_service, expiration);
bnc40448a532015-05-11 19:13:1415207
15208 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
15209 HttpRequestInfo request1;
15210 request1.method = "GET";
bnc8bef8da22016-05-30 01:28:2515211 request1.url = GURL("https://www.example.org:443");
bnc40448a532015-05-11 19:13:1415212 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015213 request1.traffic_annotation =
15214 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc40448a532015-05-11 19:13:1415215 TestCompletionCallback callback1;
15216
tfarina42834112016-09-22 13:38:2015217 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1415218 rv = callback1.GetResult(rv);
robpercival214763f2016-07-01 23:27:0115219 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1415220
15221 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5215222 ASSERT_TRUE(response1);
15223 ASSERT_TRUE(response1->headers);
bnc40448a532015-05-11 19:13:1415224 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
15225
15226 std::string response_data1;
robpercival214763f2016-07-01 23:27:0115227 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc40448a532015-05-11 19:13:1415228 EXPECT_EQ("foobar", response_data1);
15229
15230 // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
15231 // for alternative service.
15232 EXPECT_TRUE(
15233 http_server_properties->IsAlternativeServiceBroken(alternative_service));
15234
zhongyi3d4a55e72016-04-22 20:36:4615235 // Since |alternative_service| is broken, a second transaction to server
bnc40448a532015-05-11 19:13:1415236 // should not start an alternate Job. It should pool to existing connection
zhongyi3d4a55e72016-04-22 20:36:4615237 // to server.
bnc40448a532015-05-11 19:13:1415238 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
15239 HttpRequestInfo request2;
15240 request2.method = "GET";
bnc8bef8da22016-05-30 01:28:2515241 request2.url = GURL("https://www.example.org:443/second");
bnc40448a532015-05-11 19:13:1415242 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015243 request2.traffic_annotation =
15244 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc40448a532015-05-11 19:13:1415245 TestCompletionCallback callback2;
15246
tfarina42834112016-09-22 13:38:2015247 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1415248 rv = callback2.GetResult(rv);
robpercival214763f2016-07-01 23:27:0115249 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1415250
15251 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215252 ASSERT_TRUE(response2);
15253 ASSERT_TRUE(response2->headers);
bnc40448a532015-05-11 19:13:1415254 EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
15255
15256 std::string response_data2;
robpercival214763f2016-07-01 23:27:0115257 ASSERT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
bnc40448a532015-05-11 19:13:1415258 EXPECT_EQ("another", response_data2);
15259}
15260
bnc5452e2a2015-05-08 16:27:4215261// Alternative service requires HTTP/2 (or SPDY), but there is already a
15262// HTTP/1.1 socket open to the alternative server. That socket should not be
15263// used.
bncd16676a2016-07-20 16:23:0115264TEST_F(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
zhongyi3d4a55e72016-04-22 20:36:4615265 url::SchemeHostPort server("https", "origin.example.org", 443);
bnc5452e2a2015-05-08 16:27:4215266 HostPortPair alternative("alternative.example.org", 443);
15267 std::string origin_url = "https://origin.example.org:443";
15268 std::string alternative_url = "https://alternative.example.org:443";
15269
15270 // Negotiate HTTP/1.1 with alternative.example.org.
15271 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615272 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4215273 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15274
15275 // HTTP/1.1 data for |request1| and |request2|.
15276 MockWrite http_writes[] = {
15277 MockWrite(
15278 "GET / HTTP/1.1\r\n"
15279 "Host: alternative.example.org\r\n"
15280 "Connection: keep-alive\r\n\r\n"),
15281 MockWrite(
15282 "GET / HTTP/1.1\r\n"
15283 "Host: alternative.example.org\r\n"
15284 "Connection: keep-alive\r\n\r\n"),
15285 };
15286
15287 MockRead http_reads[] = {
15288 MockRead(
15289 "HTTP/1.1 200 OK\r\n"
15290 "Content-Type: text/html; charset=iso-8859-1\r\n"
15291 "Content-Length: 40\r\n\r\n"
15292 "first HTTP/1.1 response from alternative"),
15293 MockRead(
15294 "HTTP/1.1 200 OK\r\n"
15295 "Content-Type: text/html; charset=iso-8859-1\r\n"
15296 "Content-Length: 41\r\n\r\n"
15297 "second HTTP/1.1 response from alternative"),
15298 };
Ryan Sleevib8d7ea02018-05-07 20:01:0115299 StaticSocketDataProvider http_data(http_reads, http_writes);
bnc5452e2a2015-05-08 16:27:4215300 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15301
15302 // This test documents that an alternate Job should not pool to an already
15303 // existing HTTP/1.1 connection. In order to test this, a failed connection
zhongyi3d4a55e72016-04-22 20:36:4615304 // to the server is mocked. This way |request2| relies on the alternate Job.
bnc5452e2a2015-05-08 16:27:4215305 StaticSocketDataProvider data_refused;
15306 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
15307 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
15308
zhongyi3d4a55e72016-04-22 20:36:4615309 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0915310 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4015311 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4215312 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2115313 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1215314 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2115315 http_server_properties->SetHttp2AlternativeService(
15316 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4215317
15318 // First transaction to alternative to open an HTTP/1.1 socket.
bnc5452e2a2015-05-08 16:27:4215319 HttpRequestInfo request1;
krasinc06a72a2016-12-21 03:42:4615320 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4215321 request1.method = "GET";
15322 request1.url = GURL(alternative_url);
15323 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015324 request1.traffic_annotation =
15325 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4215326 TestCompletionCallback callback1;
15327
tfarina42834112016-09-22 13:38:2015328 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115329 EXPECT_THAT(callback1.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1615330 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4215331 ASSERT_TRUE(response1);
wezca1070932016-05-26 20:30:5215332 ASSERT_TRUE(response1->headers);
bnc5452e2a2015-05-08 16:27:4215333 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5215334 EXPECT_TRUE(response1->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4215335 EXPECT_FALSE(response1->was_fetched_via_spdy);
15336 std::string response_data1;
bnc691fda62016-08-12 00:43:1615337 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc5452e2a2015-05-08 16:27:4215338 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
15339
15340 // Request for origin.example.org, which has an alternative service. This
15341 // will start two Jobs: the alternative looks for connections to pool to,
15342 // finds one which is HTTP/1.1, and should ignore it, and should not try to
zhongyi3d4a55e72016-04-22 20:36:4615343 // open other connections to alternative server. The Job to server fails, so
bnc5452e2a2015-05-08 16:27:4215344 // this request fails.
bnc5452e2a2015-05-08 16:27:4215345 HttpRequestInfo request2;
krasinc06a72a2016-12-21 03:42:4615346 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4215347 request2.method = "GET";
15348 request2.url = GURL(origin_url);
15349 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015350 request2.traffic_annotation =
15351 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4215352 TestCompletionCallback callback2;
15353
tfarina42834112016-09-22 13:38:2015354 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115355 EXPECT_THAT(callback2.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc5452e2a2015-05-08 16:27:4215356
15357 // Another transaction to alternative. This is to test that the HTTP/1.1
15358 // socket is still open and in the pool.
bnc5452e2a2015-05-08 16:27:4215359 HttpRequestInfo request3;
krasinc06a72a2016-12-21 03:42:4615360 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4215361 request3.method = "GET";
15362 request3.url = GURL(alternative_url);
15363 request3.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015364 request3.traffic_annotation =
15365 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4215366 TestCompletionCallback callback3;
15367
tfarina42834112016-09-22 13:38:2015368 rv = trans3.Start(&request3, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115369 EXPECT_THAT(callback3.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1615370 const HttpResponseInfo* response3 = trans3.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4215371 ASSERT_TRUE(response3);
wezca1070932016-05-26 20:30:5215372 ASSERT_TRUE(response3->headers);
bnc5452e2a2015-05-08 16:27:4215373 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5215374 EXPECT_TRUE(response3->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4215375 EXPECT_FALSE(response3->was_fetched_via_spdy);
15376 std::string response_data3;
bnc691fda62016-08-12 00:43:1615377 ASSERT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
bnc5452e2a2015-05-08 16:27:4215378 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
15379}
15380
bncd16676a2016-07-20 16:23:0115381TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2315382 const std::string https_url = "https://www.example.org:8080/";
15383 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0415384
rdsmithebb50aa2015-11-12 03:44:3815385 // Separate SPDY util instance for naked and wrapped requests.
bncd16676a2016-07-20 16:23:0115386 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:3815387
[email protected]8450d722012-07-02 19:14:0415388 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2315389 const HostPortPair host_port_pair("www.example.org", 8080);
Ryan Hamilton0239aac2018-05-19 00:03:1315390 spdy::SpdySerializedFrame connect(
lgarrona91df87f2014-12-05 00:51:3415391 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
Ryan Hamilton0239aac2018-05-19 00:03:1315392 spdy::SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4915393 spdy_util_wrapped.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1315394 spdy::SpdySerializedFrame wrapped_req1(
[email protected]23e482282013-06-14 16:08:0215395 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3915396
15397 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
Ryan Hamilton0239aac2018-05-19 00:03:1315398 spdy::SpdyHeaderBlock req2_block;
15399 req2_block[spdy::kHttp2MethodHeader] = "GET";
15400 req2_block[spdy::kHttp2AuthorityHeader] = "www.example.org:8080";
15401 req2_block[spdy::kHttp2SchemeHeader] = "http";
15402 req2_block[spdy::kHttp2PathHeader] = "/";
15403 spdy::SpdySerializedFrame req2(
bnc42331402016-07-25 13:36:1515404 spdy_util_.ConstructSpdyHeaders(3, std::move(req2_block), MEDIUM, true));
[email protected]8450d722012-07-02 19:14:0415405
15406 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4115407 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_req1, 2),
15408 CreateMockWrite(req2, 6),
[email protected]8450d722012-07-02 19:14:0415409 };
15410
Ryan Hamilton0239aac2018-05-19 00:03:1315411 spdy::SpdySerializedFrame conn_resp(
bnc42331402016-07-25 13:36:1515412 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1315413 spdy::SpdySerializedFrame resp1(
bnc42331402016-07-25 13:36:1515414 spdy_util_wrapped.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1315415 spdy::SpdySerializedFrame body1(
15416 spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
15417 spdy::SpdySerializedFrame wrapped_resp1(
rdsmithebb50aa2015-11-12 03:44:3815418 spdy_util_wrapped.ConstructWrappedSpdyFrame(resp1, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1315419 spdy::SpdySerializedFrame wrapped_body1(
rdsmithebb50aa2015-11-12 03:44:3815420 spdy_util_wrapped.ConstructWrappedSpdyFrame(body1, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1315421 spdy::SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
15422 spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
mmenke666a6fea2015-12-19 04:16:3315423 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4115424 CreateMockRead(conn_resp, 1),
mmenke666a6fea2015-12-19 04:16:3315425 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:4115426 CreateMockRead(wrapped_resp1, 4),
15427 CreateMockRead(wrapped_body1, 5),
mmenke666a6fea2015-12-19 04:16:3315428 MockRead(ASYNC, ERR_IO_PENDING, 7),
bncdf80d44fd2016-07-15 20:27:4115429 CreateMockRead(resp2, 8),
15430 CreateMockRead(body2, 9),
mmenke666a6fea2015-12-19 04:16:3315431 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 10),
15432 };
[email protected]8450d722012-07-02 19:14:0415433
Ryan Sleevib8d7ea02018-05-07 20:01:0115434 SequencedSocketData data1(reads1, writes1);
[email protected]8450d722012-07-02 19:14:0415435 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5715436 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0415437
Lily Houghton8c2f97d2018-01-22 05:06:5915438 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4915439 ProxyResolutionService::CreateFixedFromPacResult(
15440 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5115441 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0715442 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0415443 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3615444 ssl1.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3315445 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0415446 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3615447 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3315448 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15449 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0415450
danakj1fd259a02016-04-16 03:17:0915451 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]8450d722012-07-02 19:14:0415452
15453 // Start the first transaction to set up the SpdySession
15454 HttpRequestInfo request1;
15455 request1.method = "GET";
15456 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0415457 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015458 request1.traffic_annotation =
15459 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015460 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0415461 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:2015462 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0415463
mmenke666a6fea2015-12-19 04:16:3315464 // This pause is a hack to avoid running into https://crbug.com/497228.
15465 data1.RunUntilPaused();
15466 base::RunLoop().RunUntilIdle();
15467 data1.Resume();
robpercival214763f2016-07-01 23:27:0115468 EXPECT_THAT(callback1.GetResult(rv), IsOk());
[email protected]8450d722012-07-02 19:14:0415469 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
15470
[email protected]f6c63db52013-02-02 00:35:2215471 LoadTimingInfo load_timing_info1;
15472 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
15473 TestLoadTimingNotReusedWithPac(load_timing_info1,
15474 CONNECT_TIMING_HAS_SSL_TIMES);
15475
mmenke666a6fea2015-12-19 04:16:3315476 // Now, start the HTTP request.
[email protected]8450d722012-07-02 19:14:0415477 HttpRequestInfo request2;
15478 request2.method = "GET";
15479 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0415480 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015481 request2.traffic_annotation =
15482 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015483 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0415484 TestCompletionCallback callback2;
tfarina42834112016-09-22 13:38:2015485 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0415486
mmenke666a6fea2015-12-19 04:16:3315487 // This pause is a hack to avoid running into https://crbug.com/497228.
15488 data1.RunUntilPaused();
15489 base::RunLoop().RunUntilIdle();
15490 data1.Resume();
robpercival214763f2016-07-01 23:27:0115491 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenke666a6fea2015-12-19 04:16:3315492
[email protected]8450d722012-07-02 19:14:0415493 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2215494
15495 LoadTimingInfo load_timing_info2;
15496 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
15497 // The established SPDY sessions is considered reused by the HTTP request.
15498 TestLoadTimingReusedWithPac(load_timing_info2);
15499 // HTTP requests over a SPDY session should have a different connection
15500 // socket_log_id than requests over a tunnel.
15501 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0415502}
15503
[email protected]2d88e7d2012-07-19 17:55:1715504// Test that in the case where we have a SPDY session to a SPDY proxy
15505// that we do not pool other origins that resolve to the same IP when
15506// the certificate does not match the new origin.
15507// http://crbug.com/134690
bncd16676a2016-07-20 16:23:0115508TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2315509 const std::string url1 = "http://www.example.org/";
15510 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1715511 const std::string ip_addr = "1.2.3.4";
15512
rdsmithebb50aa2015-11-12 03:44:3815513 // Second SpdyTestUtil instance for the second socket.
bncd16676a2016-07-20 16:23:0115514 SpdyTestUtil spdy_util_secure;
rdsmithebb50aa2015-11-12 03:44:3815515
[email protected]2d88e7d2012-07-19 17:55:1715516 // SPDY GET for HTTP URL (through SPDY proxy)
Ryan Hamilton0239aac2018-05-19 00:03:1315517 spdy::SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:2315518 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
Ryan Hamilton0239aac2018-05-19 00:03:1315519 spdy::SpdySerializedFrame req1(
bnc42331402016-07-25 13:36:1515520 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
[email protected]2d88e7d2012-07-19 17:55:1715521
15522 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4115523 CreateMockWrite(req1, 0),
[email protected]2d88e7d2012-07-19 17:55:1715524 };
15525
Ryan Hamilton0239aac2018-05-19 00:03:1315526 spdy::SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
15527 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1715528 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4115529 MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(resp1, 2),
15530 CreateMockRead(body1, 3), MockRead(ASYNC, OK, 4), // EOF
[email protected]2d88e7d2012-07-19 17:55:1715531 };
15532
Ryan Sleevib8d7ea02018-05-07 20:01:0115533 SequencedSocketData data1(reads1, writes1);
martijnfe9636e2016-02-06 14:33:3215534 IPAddress ip;
martijn654c8c42016-02-10 22:10:5915535 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
[email protected]2d88e7d2012-07-19 17:55:1715536 IPEndPoint peer_addr = IPEndPoint(ip, 443);
15537 MockConnect connect_data1(ASYNC, OK, peer_addr);
mmenke666a6fea2015-12-19 04:16:3315538 data1.set_connect_data(connect_data1);
[email protected]2d88e7d2012-07-19 17:55:1715539
15540 // SPDY GET for HTTPS URL (direct)
Ryan Hamilton0239aac2018-05-19 00:03:1315541 spdy::SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4915542 spdy_util_secure.ConstructSpdyGet(url2.c_str(), 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1715543
15544 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4115545 CreateMockWrite(req2, 0),
[email protected]2d88e7d2012-07-19 17:55:1715546 };
15547
Ryan Hamilton0239aac2018-05-19 00:03:1315548 spdy::SpdySerializedFrame resp2(
15549 spdy_util_secure.ConstructSpdyGetReply(NULL, 0, 1));
15550 spdy::SpdySerializedFrame body2(
15551 spdy_util_secure.ConstructSpdyDataFrame(1, true));
bncdf80d44fd2016-07-15 20:27:4115552 MockRead reads2[] = {CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
mmenke666a6fea2015-12-19 04:16:3315553 MockRead(ASYNC, OK, 3)};
[email protected]2d88e7d2012-07-19 17:55:1715554
Ryan Sleevib8d7ea02018-05-07 20:01:0115555 SequencedSocketData data2(reads2, writes2);
[email protected]2d88e7d2012-07-19 17:55:1715556 MockConnect connect_data2(ASYNC, OK);
mmenke666a6fea2015-12-19 04:16:3315557 data2.set_connect_data(connect_data2);
[email protected]2d88e7d2012-07-19 17:55:1715558
15559 // Set up a proxy config that sends HTTP requests to a proxy, and
15560 // all others direct.
15561 ProxyConfig proxy_config;
15562 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
Ramin Halavatica8d5252018-03-12 05:33:4915563 session_deps_.proxy_resolution_service =
15564 std::make_unique<ProxyResolutionService>(
15565 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
15566 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
15567 nullptr, nullptr);
[email protected]2d88e7d2012-07-19 17:55:1715568
bncce36dca22015-04-21 22:11:2315569 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3615570 ssl1.next_proto = kProtoHTTP2;
[email protected]2d88e7d2012-07-19 17:55:1715571 // Load a valid cert. Note, that this does not need to
15572 // be valid for proxy because the MockSSLClientSocket does
15573 // not actually verify it. But SpdySession will use this
15574 // to see if it is valid for the new origin
Ryan Sleevi4f832092017-11-21 23:25:4915575 ssl1.ssl_info.cert =
15576 ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
15577 ASSERT_TRUE(ssl1.ssl_info.cert);
mmenke666a6fea2015-12-19 04:16:3315578 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
15579 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d88e7d2012-07-19 17:55:1715580
15581 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3615582 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3315583 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15584 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d88e7d2012-07-19 17:55:1715585
Jeremy Roman0579ed62017-08-29 15:56:1915586 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
bncce36dca22015-04-21 22:11:2315587 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0715588 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1715589
danakj1fd259a02016-04-16 03:17:0915590 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]2d88e7d2012-07-19 17:55:1715591
15592 // Start the first transaction to set up the SpdySession
15593 HttpRequestInfo request1;
15594 request1.method = "GET";
15595 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1715596 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015597 request1.traffic_annotation =
15598 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015599 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1715600 TestCompletionCallback callback1;
15601 ASSERT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015602 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
mmenke666a6fea2015-12-19 04:16:3315603 // This pause is a hack to avoid running into https://crbug.com/497228.
15604 data1.RunUntilPaused();
15605 base::RunLoop().RunUntilIdle();
15606 data1.Resume();
[email protected]2d88e7d2012-07-19 17:55:1715607
robpercival214763f2016-07-01 23:27:0115608 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1715609 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
15610
15611 // Now, start the HTTP request
15612 HttpRequestInfo request2;
15613 request2.method = "GET";
15614 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1715615 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015616 request2.traffic_annotation =
15617 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015618 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1715619 TestCompletionCallback callback2;
15620 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015621 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5515622 base::RunLoop().RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1715623
15624 ASSERT_TRUE(callback2.have_result());
robpercival214763f2016-07-01 23:27:0115625 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1715626 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
15627}
15628
[email protected]85f97342013-04-17 06:12:2415629// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
15630// error) in SPDY session, removes the socket from pool and closes the SPDY
15631// session. Verify that new url's from the same HttpNetworkSession (and a new
15632// SpdySession) do work. http://crbug.com/224701
bncd16676a2016-07-20 16:23:0115633TEST_F(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2315634 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2415635
15636 MockRead reads1[] = {
15637 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
15638 };
15639
Ryan Sleevib8d7ea02018-05-07 20:01:0115640 SequencedSocketData data1(reads1, base::span<MockWrite>());
[email protected]85f97342013-04-17 06:12:2415641
Ryan Hamilton0239aac2018-05-19 00:03:1315642 spdy::SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4915643 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2415644 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4115645 CreateMockWrite(req2, 0),
[email protected]85f97342013-04-17 06:12:2415646 };
15647
Ryan Hamilton0239aac2018-05-19 00:03:1315648 spdy::SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
15649 spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]85f97342013-04-17 06:12:2415650 MockRead reads2[] = {
bncdf80d44fd2016-07-15 20:27:4115651 CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
15652 MockRead(ASYNC, OK, 3) // EOF
[email protected]85f97342013-04-17 06:12:2415653 };
15654
Ryan Sleevib8d7ea02018-05-07 20:01:0115655 SequencedSocketData data2(reads2, writes2);
[email protected]85f97342013-04-17 06:12:2415656
[email protected]85f97342013-04-17 06:12:2415657 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615658 ssl1.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5015659 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
15660 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]85f97342013-04-17 06:12:2415661
15662 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615663 ssl2.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5015664 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15665 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]85f97342013-04-17 06:12:2415666
danakj1fd259a02016-04-16 03:17:0915667 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:5015668 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]85f97342013-04-17 06:12:2415669
15670 // Start the first transaction to set up the SpdySession and verify that
15671 // connection was closed.
15672 HttpRequestInfo request1;
15673 request1.method = "GET";
15674 request1.url = GURL(https_url);
15675 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015676 request1.traffic_annotation =
15677 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015678 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2415679 TestCompletionCallback callback1;
15680 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015681 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0115682 EXPECT_THAT(callback1.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]85f97342013-04-17 06:12:2415683
15684 // Now, start the second request and make sure it succeeds.
15685 HttpRequestInfo request2;
15686 request2.method = "GET";
15687 request2.url = GURL(https_url);
15688 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015689 request2.traffic_annotation =
15690 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015691 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2415692 TestCompletionCallback callback2;
15693 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015694 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
[email protected]85f97342013-04-17 06:12:2415695
robpercival214763f2016-07-01 23:27:0115696 ASSERT_THAT(callback2.WaitForResult(), IsOk());
[email protected]85f97342013-04-17 06:12:2415697 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
15698}
15699
bncd16676a2016-07-20 16:23:0115700TEST_F(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]483fa202013-05-14 01:07:0315701 ClientSocketPoolManager::set_max_sockets_per_group(
15702 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15703 ClientSocketPoolManager::set_max_sockets_per_pool(
15704 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15705
15706 // Use two different hosts with different IPs so they don't get pooled.
15707 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
15708 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
danakj1fd259a02016-04-16 03:17:0915709 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]483fa202013-05-14 01:07:0315710
15711 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615712 ssl1.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0315713 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615714 ssl2.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0315715 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
15716 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15717
Ryan Hamilton0239aac2018-05-19 00:03:1315718 spdy::SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4915719 spdy_util_.ConstructSpdyGet("https://www.a.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0315720 MockWrite spdy1_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115721 CreateMockWrite(host1_req, 0),
[email protected]483fa202013-05-14 01:07:0315722 };
Ryan Hamilton0239aac2018-05-19 00:03:1315723 spdy::SpdySerializedFrame host1_resp(
15724 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
15725 spdy::SpdySerializedFrame host1_resp_body(
bncdf80d44fd2016-07-15 20:27:4115726 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0315727 MockRead spdy1_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115728 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
mmenkee24011922015-12-17 22:12:5915729 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0315730 };
15731
rdsmithebb50aa2015-11-12 03:44:3815732 // Use a separate test instance for the separate SpdySession that will be
15733 // created.
bncd16676a2016-07-20 16:23:0115734 SpdyTestUtil spdy_util_2;
Ryan Sleevib8d7ea02018-05-07 20:01:0115735 SequencedSocketData spdy1_data(spdy1_reads, spdy1_writes);
Bence Béky53a5aef2018-03-29 21:54:1215736 session_deps_.socket_factory->AddSocketDataProvider(&spdy1_data);
[email protected]483fa202013-05-14 01:07:0315737
Ryan Hamilton0239aac2018-05-19 00:03:1315738 spdy::SpdySerializedFrame host2_req(
bnc38dcd392016-02-09 23:19:4915739 spdy_util_2.ConstructSpdyGet("https://www.b.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0315740 MockWrite spdy2_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115741 CreateMockWrite(host2_req, 0),
[email protected]483fa202013-05-14 01:07:0315742 };
Ryan Hamilton0239aac2018-05-19 00:03:1315743 spdy::SpdySerializedFrame host2_resp(
15744 spdy_util_2.ConstructSpdyGetReply(NULL, 0, 1));
15745 spdy::SpdySerializedFrame host2_resp_body(
bncdf80d44fd2016-07-15 20:27:4115746 spdy_util_2.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0315747 MockRead spdy2_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115748 CreateMockRead(host2_resp, 1), CreateMockRead(host2_resp_body, 2),
mmenkee24011922015-12-17 22:12:5915749 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0315750 };
15751
Ryan Sleevib8d7ea02018-05-07 20:01:0115752 SequencedSocketData spdy2_data(spdy2_reads, spdy2_writes);
Bence Béky53a5aef2018-03-29 21:54:1215753 session_deps_.socket_factory->AddSocketDataProvider(&spdy2_data);
[email protected]483fa202013-05-14 01:07:0315754
15755 MockWrite http_write[] = {
15756 MockWrite("GET / HTTP/1.1\r\n"
15757 "Host: www.a.com\r\n"
15758 "Connection: keep-alive\r\n\r\n"),
15759 };
15760
15761 MockRead http_read[] = {
15762 MockRead("HTTP/1.1 200 OK\r\n"),
15763 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
15764 MockRead("Content-Length: 6\r\n\r\n"),
15765 MockRead("hello!"),
15766 };
Ryan Sleevib8d7ea02018-05-07 20:01:0115767 StaticSocketDataProvider http_data(http_read, http_write);
[email protected]483fa202013-05-14 01:07:0315768 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15769
15770 HostPortPair host_port_pair_a("www.a.com", 443);
Paul Jensena457017a2018-01-19 23:52:0415771 SpdySessionKey spdy_session_key_a(host_port_pair_a, ProxyServer::Direct(),
15772 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]483fa202013-05-14 01:07:0315773 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615774 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315775
15776 TestCompletionCallback callback;
15777 HttpRequestInfo request1;
15778 request1.method = "GET";
15779 request1.url = GURL("https://www.a.com/");
15780 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015781 request1.traffic_annotation =
15782 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5815783 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1915784 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0315785
tfarina42834112016-09-22 13:38:2015786 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115787 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15788 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0315789
15790 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215791 ASSERT_TRUE(response);
15792 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215793 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0315794 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215795 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]483fa202013-05-14 01:07:0315796
15797 std::string response_data;
robpercival214763f2016-07-01 23:27:0115798 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0315799 EXPECT_EQ("hello!", response_data);
15800 trans.reset();
15801 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2615802 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315803
15804 HostPortPair host_port_pair_b("www.b.com", 443);
Paul Jensena457017a2018-01-19 23:52:0415805 SpdySessionKey spdy_session_key_b(host_port_pair_b, ProxyServer::Direct(),
15806 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]483fa202013-05-14 01:07:0315807 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615808 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0315809 HttpRequestInfo request2;
15810 request2.method = "GET";
15811 request2.url = GURL("https://www.b.com/");
15812 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015813 request2.traffic_annotation =
15814 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5815815 trans =
Jeremy Roman0579ed62017-08-29 15:56:1915816 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0315817
tfarina42834112016-09-22 13:38:2015818 rv = trans->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115819 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15820 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0315821
15822 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215823 ASSERT_TRUE(response);
15824 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215825 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0315826 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215827 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115828 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0315829 EXPECT_EQ("hello!", response_data);
15830 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615831 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315832 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2615833 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0315834
15835 HostPortPair host_port_pair_a1("www.a.com", 80);
Paul Jensena457017a2018-01-19 23:52:0415836 SpdySessionKey spdy_session_key_a1(host_port_pair_a1, ProxyServer::Direct(),
15837 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]483fa202013-05-14 01:07:0315838 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615839 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0315840 HttpRequestInfo request3;
15841 request3.method = "GET";
15842 request3.url = GURL("http://www.a.com/");
15843 request3.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015844 request3.traffic_annotation =
15845 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5815846 trans =
Jeremy Roman0579ed62017-08-29 15:56:1915847 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0315848
tfarina42834112016-09-22 13:38:2015849 rv = trans->Start(&request3, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115850 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15851 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0315852
15853 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215854 ASSERT_TRUE(response);
15855 ASSERT_TRUE(response->headers);
[email protected]483fa202013-05-14 01:07:0315856 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
15857 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215858 EXPECT_FALSE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115859 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0315860 EXPECT_EQ("hello!", response_data);
15861 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615862 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315863 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615864 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0315865}
15866
bncd16676a2016-07-20 16:23:0115867TEST_F(HttpNetworkTransactionTest, HttpSyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0415868 HttpRequestInfo request;
15869 request.method = "GET";
bncce36dca22015-04-21 22:11:2315870 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1015871 request.traffic_annotation =
15872 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0415873
danakj1fd259a02016-04-16 03:17:0915874 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615875 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415876
ttuttled9dbc652015-09-29 20:00:5915877 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0415878 StaticSocketDataProvider data;
15879 data.set_connect_data(mock_connect);
15880 session_deps_.socket_factory->AddSocketDataProvider(&data);
15881
15882 TestCompletionCallback callback;
15883
tfarina42834112016-09-22 13:38:2015884 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115885 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415886
15887 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115888 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0415889
[email protected]79e1fd62013-06-20 06:50:0415890 // We don't care whether this succeeds or fails, but it shouldn't crash.
15891 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615892 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4715893
15894 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1615895 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4715896 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0115897 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5915898
15899 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1615900 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5915901 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0415902}
15903
bncd16676a2016-07-20 16:23:0115904TEST_F(HttpNetworkTransactionTest, HttpAsyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0415905 HttpRequestInfo request;
15906 request.method = "GET";
bncce36dca22015-04-21 22:11:2315907 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1015908 request.traffic_annotation =
15909 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0415910
danakj1fd259a02016-04-16 03:17:0915911 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615912 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415913
ttuttled9dbc652015-09-29 20:00:5915914 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0415915 StaticSocketDataProvider data;
15916 data.set_connect_data(mock_connect);
15917 session_deps_.socket_factory->AddSocketDataProvider(&data);
15918
15919 TestCompletionCallback callback;
15920
tfarina42834112016-09-22 13:38:2015921 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115922 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415923
15924 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115925 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0415926
[email protected]79e1fd62013-06-20 06:50:0415927 // We don't care whether this succeeds or fails, but it shouldn't crash.
15928 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615929 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4715930
15931 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1615932 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4715933 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0115934 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5915935
15936 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1615937 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5915938 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0415939}
15940
bncd16676a2016-07-20 16:23:0115941TEST_F(HttpNetworkTransactionTest, HttpSyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0415942 HttpRequestInfo request;
15943 request.method = "GET";
bncce36dca22015-04-21 22:11:2315944 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1015945 request.traffic_annotation =
15946 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0415947
danakj1fd259a02016-04-16 03:17:0915948 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615949 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415950
15951 MockWrite data_writes[] = {
15952 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15953 };
15954 MockRead data_reads[] = {
15955 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
15956 };
15957
Ryan Sleevib8d7ea02018-05-07 20:01:0115958 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0415959 session_deps_.socket_factory->AddSocketDataProvider(&data);
15960
15961 TestCompletionCallback callback;
15962
tfarina42834112016-09-22 13:38:2015963 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115964 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415965
15966 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115967 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0415968
[email protected]79e1fd62013-06-20 06:50:0415969 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615970 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0415971 EXPECT_TRUE(request_headers.HasHeader("Host"));
15972}
15973
bncd16676a2016-07-20 16:23:0115974TEST_F(HttpNetworkTransactionTest, HttpAsyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0415975 HttpRequestInfo request;
15976 request.method = "GET";
bncce36dca22015-04-21 22:11:2315977 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1015978 request.traffic_annotation =
15979 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0415980
danakj1fd259a02016-04-16 03:17:0915981 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615982 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415983
15984 MockWrite data_writes[] = {
15985 MockWrite(ASYNC, ERR_CONNECTION_RESET),
15986 };
15987 MockRead data_reads[] = {
15988 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
15989 };
15990
Ryan Sleevib8d7ea02018-05-07 20:01:0115991 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0415992 session_deps_.socket_factory->AddSocketDataProvider(&data);
15993
15994 TestCompletionCallback callback;
15995
tfarina42834112016-09-22 13:38:2015996 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115997 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415998
15999 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116000 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416001
[email protected]79e1fd62013-06-20 06:50:0416002 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616003 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416004 EXPECT_TRUE(request_headers.HasHeader("Host"));
16005}
16006
bncd16676a2016-07-20 16:23:0116007TEST_F(HttpNetworkTransactionTest, HttpSyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0416008 HttpRequestInfo request;
16009 request.method = "GET";
bncce36dca22015-04-21 22:11:2316010 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016011 request.traffic_annotation =
16012 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416013
danakj1fd259a02016-04-16 03:17:0916014 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616015 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416016
16017 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2316018 MockWrite(
16019 "GET / HTTP/1.1\r\n"
16020 "Host: www.example.org\r\n"
16021 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0416022 };
16023 MockRead data_reads[] = {
16024 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
16025 };
16026
Ryan Sleevib8d7ea02018-05-07 20:01:0116027 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0416028 session_deps_.socket_factory->AddSocketDataProvider(&data);
16029
16030 TestCompletionCallback callback;
16031
tfarina42834112016-09-22 13:38:2016032 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116033 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416034
16035 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116036 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416037
[email protected]79e1fd62013-06-20 06:50:0416038 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616039 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416040 EXPECT_TRUE(request_headers.HasHeader("Host"));
16041}
16042
bncd16676a2016-07-20 16:23:0116043TEST_F(HttpNetworkTransactionTest, HttpAsyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0416044 HttpRequestInfo request;
16045 request.method = "GET";
bncce36dca22015-04-21 22:11:2316046 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016047 request.traffic_annotation =
16048 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416049
danakj1fd259a02016-04-16 03:17:0916050 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616051 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416052
16053 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2316054 MockWrite(
16055 "GET / HTTP/1.1\r\n"
16056 "Host: www.example.org\r\n"
16057 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0416058 };
16059 MockRead data_reads[] = {
16060 MockRead(ASYNC, ERR_CONNECTION_RESET),
16061 };
16062
Ryan Sleevib8d7ea02018-05-07 20:01:0116063 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0416064 session_deps_.socket_factory->AddSocketDataProvider(&data);
16065
16066 TestCompletionCallback callback;
16067
tfarina42834112016-09-22 13:38:2016068 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116069 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416070
16071 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116072 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416073
[email protected]79e1fd62013-06-20 06:50:0416074 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616075 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416076 EXPECT_TRUE(request_headers.HasHeader("Host"));
16077}
16078
bncd16676a2016-07-20 16:23:0116079TEST_F(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
[email protected]79e1fd62013-06-20 06:50:0416080 HttpRequestInfo request;
16081 request.method = "GET";
bncce36dca22015-04-21 22:11:2316082 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0416083 request.extra_headers.SetHeader("X-Foo", "bar");
Ramin Halavatib5e433e62018-02-07 07:41:1016084 request.traffic_annotation =
16085 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416086
danakj1fd259a02016-04-16 03:17:0916087 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616088 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416089
16090 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2316091 MockWrite(
16092 "GET / HTTP/1.1\r\n"
16093 "Host: www.example.org\r\n"
16094 "Connection: keep-alive\r\n"
16095 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0416096 };
16097 MockRead data_reads[] = {
16098 MockRead("HTTP/1.1 200 OK\r\n"
16099 "Content-Length: 5\r\n\r\n"
16100 "hello"),
16101 MockRead(ASYNC, ERR_UNEXPECTED),
16102 };
16103
Ryan Sleevib8d7ea02018-05-07 20:01:0116104 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0416105 session_deps_.socket_factory->AddSocketDataProvider(&data);
16106
16107 TestCompletionCallback callback;
16108
tfarina42834112016-09-22 13:38:2016109 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116110 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416111
16112 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116113 EXPECT_THAT(rv, IsOk());
[email protected]79e1fd62013-06-20 06:50:0416114
16115 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616116 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416117 std::string foo;
16118 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
16119 EXPECT_EQ("bar", foo);
16120}
16121
[email protected]043b68c82013-08-22 23:41:5216122// Tests that when a used socket is returned to the SSL socket pool, it's closed
16123// if the transport socket pool is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0116124TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
[email protected]043b68c82013-08-22 23:41:5216125 ClientSocketPoolManager::set_max_sockets_per_group(
16126 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16127 ClientSocketPoolManager::set_max_sockets_per_pool(
16128 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16129
16130 // Set up SSL request.
16131
16132 HttpRequestInfo ssl_request;
16133 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2316134 ssl_request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016135 ssl_request.traffic_annotation =
16136 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5216137
16138 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2316139 MockWrite(
16140 "GET / HTTP/1.1\r\n"
16141 "Host: www.example.org\r\n"
16142 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5216143 };
16144 MockRead ssl_reads[] = {
16145 MockRead("HTTP/1.1 200 OK\r\n"),
16146 MockRead("Content-Length: 11\r\n\r\n"),
16147 MockRead("hello world"),
16148 MockRead(SYNCHRONOUS, OK),
16149 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116150 StaticSocketDataProvider ssl_data(ssl_reads, ssl_writes);
[email protected]043b68c82013-08-22 23:41:5216151 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
16152
16153 SSLSocketDataProvider ssl(ASYNC, OK);
16154 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16155
16156 // Set up HTTP request.
16157
16158 HttpRequestInfo http_request;
16159 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2316160 http_request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016161 http_request.traffic_annotation =
16162 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5216163
16164 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2316165 MockWrite(
16166 "GET / HTTP/1.1\r\n"
16167 "Host: www.example.org\r\n"
16168 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5216169 };
16170 MockRead http_reads[] = {
16171 MockRead("HTTP/1.1 200 OK\r\n"),
16172 MockRead("Content-Length: 7\r\n\r\n"),
16173 MockRead("falafel"),
16174 MockRead(SYNCHRONOUS, OK),
16175 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116176 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]043b68c82013-08-22 23:41:5216177 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16178
danakj1fd259a02016-04-16 03:17:0916179 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5216180
16181 // Start the SSL request.
16182 TestCompletionCallback ssl_callback;
bnc691fda62016-08-12 00:43:1616183 HttpNetworkTransaction ssl_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016184 ASSERT_EQ(ERR_IO_PENDING,
16185 ssl_trans.Start(&ssl_request, ssl_callback.callback(),
16186 NetLogWithSource()));
[email protected]043b68c82013-08-22 23:41:5216187
16188 // Start the HTTP request. Pool should stall.
16189 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1616190 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016191 ASSERT_EQ(ERR_IO_PENDING,
16192 http_trans.Start(&http_request, http_callback.callback(),
16193 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4116194 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5216195
16196 // Wait for response from SSL request.
robpercival214763f2016-07-01 23:27:0116197 ASSERT_THAT(ssl_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5216198 std::string response_data;
bnc691fda62016-08-12 00:43:1616199 ASSERT_THAT(ReadTransaction(&ssl_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5216200 EXPECT_EQ("hello world", response_data);
16201
16202 // The SSL socket should automatically be closed, so the HTTP request can
16203 // start.
dcheng48459ac22014-08-26 00:46:4116204 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
16205 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5216206
16207 // The HTTP request can now complete.
robpercival214763f2016-07-01 23:27:0116208 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
bnc691fda62016-08-12 00:43:1616209 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5216210 EXPECT_EQ("falafel", response_data);
16211
dcheng48459ac22014-08-26 00:46:4116212 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5216213}
16214
16215// Tests that when a SSL connection is established but there's no corresponding
16216// request that needs it, the new socket is closed if the transport socket pool
16217// is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0116218TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
[email protected]043b68c82013-08-22 23:41:5216219 ClientSocketPoolManager::set_max_sockets_per_group(
16220 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16221 ClientSocketPoolManager::set_max_sockets_per_pool(
16222 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16223
16224 // Set up an ssl request.
16225
16226 HttpRequestInfo ssl_request;
16227 ssl_request.method = "GET";
16228 ssl_request.url = GURL("https://www.foopy.com/");
Ramin Halavatib5e433e62018-02-07 07:41:1016229 ssl_request.traffic_annotation =
16230 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5216231
16232 // No data will be sent on the SSL socket.
16233 StaticSocketDataProvider ssl_data;
16234 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
16235
16236 SSLSocketDataProvider ssl(ASYNC, OK);
16237 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16238
16239 // Set up HTTP request.
16240
16241 HttpRequestInfo http_request;
16242 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2316243 http_request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016244 http_request.traffic_annotation =
16245 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5216246
16247 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2316248 MockWrite(
16249 "GET / HTTP/1.1\r\n"
16250 "Host: www.example.org\r\n"
16251 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5216252 };
16253 MockRead http_reads[] = {
16254 MockRead("HTTP/1.1 200 OK\r\n"),
16255 MockRead("Content-Length: 7\r\n\r\n"),
16256 MockRead("falafel"),
16257 MockRead(SYNCHRONOUS, OK),
16258 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116259 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]043b68c82013-08-22 23:41:5216260 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16261
danakj1fd259a02016-04-16 03:17:0916262 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5216263
16264 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
16265 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2916266 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
nharper8cdb0fb2016-04-22 21:34:5916267 http_stream_factory->PreconnectStreams(1, ssl_request);
dcheng48459ac22014-08-26 00:46:4116268 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5216269
16270 // Start the HTTP request. Pool should stall.
16271 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1616272 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016273 ASSERT_EQ(ERR_IO_PENDING,
16274 http_trans.Start(&http_request, http_callback.callback(),
16275 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4116276 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5216277
16278 // The SSL connection will automatically be closed once the connection is
16279 // established, to let the HTTP request start.
robpercival214763f2016-07-01 23:27:0116280 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5216281 std::string response_data;
bnc691fda62016-08-12 00:43:1616282 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5216283 EXPECT_EQ("falafel", response_data);
16284
dcheng48459ac22014-08-26 00:46:4116285 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5216286}
16287
bncd16676a2016-07-20 16:23:0116288TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0916289 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216290 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916291 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216292 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416293
16294 HttpRequestInfo request;
16295 request.method = "POST";
16296 request.url = GURL("http://www.foo.com/");
16297 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1016298 request.traffic_annotation =
16299 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416300
danakj1fd259a02016-04-16 03:17:0916301 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616302 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416303 // Send headers successfully, but get an error while sending the body.
16304 MockWrite data_writes[] = {
16305 MockWrite("POST / HTTP/1.1\r\n"
16306 "Host: www.foo.com\r\n"
16307 "Connection: keep-alive\r\n"
16308 "Content-Length: 3\r\n\r\n"),
16309 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16310 };
16311
16312 MockRead data_reads[] = {
16313 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16314 MockRead("hello world"),
16315 MockRead(SYNCHRONOUS, OK),
16316 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116317 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5416318 session_deps_.socket_factory->AddSocketDataProvider(&data);
16319
16320 TestCompletionCallback callback;
16321
tfarina42834112016-09-22 13:38:2016322 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116323 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416324
16325 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116326 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416327
bnc691fda62016-08-12 00:43:1616328 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216329 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416330
wezca1070932016-05-26 20:30:5216331 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416332 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16333
16334 std::string response_data;
bnc691fda62016-08-12 00:43:1616335 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116336 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416337 EXPECT_EQ("hello world", response_data);
16338}
16339
16340// This test makes sure the retry logic doesn't trigger when reading an error
16341// response from a server that rejected a POST with a CONNECTION_RESET.
bncd16676a2016-07-20 16:23:0116342TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5416343 PostReadsErrorResponseAfterResetOnReusedSocket) {
danakj1fd259a02016-04-16 03:17:0916344 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5416345 MockWrite data_writes[] = {
16346 MockWrite("GET / HTTP/1.1\r\n"
16347 "Host: www.foo.com\r\n"
16348 "Connection: keep-alive\r\n\r\n"),
16349 MockWrite("POST / HTTP/1.1\r\n"
16350 "Host: www.foo.com\r\n"
16351 "Connection: keep-alive\r\n"
16352 "Content-Length: 3\r\n\r\n"),
16353 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16354 };
16355
16356 MockRead data_reads[] = {
16357 MockRead("HTTP/1.1 200 Peachy\r\n"
16358 "Content-Length: 14\r\n\r\n"),
16359 MockRead("first response"),
16360 MockRead("HTTP/1.1 400 Not OK\r\n"
16361 "Content-Length: 15\r\n\r\n"),
16362 MockRead("second response"),
16363 MockRead(SYNCHRONOUS, OK),
16364 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116365 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5416366 session_deps_.socket_factory->AddSocketDataProvider(&data);
16367
16368 TestCompletionCallback callback;
16369 HttpRequestInfo request1;
16370 request1.method = "GET";
16371 request1.url = GURL("http://www.foo.com/");
16372 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016373 request1.traffic_annotation =
16374 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416375
bnc87dcefc2017-05-25 12:47:5816376 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:1916377 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016378 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116379 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416380
16381 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116382 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416383
16384 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:5216385 ASSERT_TRUE(response1);
[email protected]02d74a02014-04-23 18:10:5416386
wezca1070932016-05-26 20:30:5216387 EXPECT_TRUE(response1->headers);
[email protected]02d74a02014-04-23 18:10:5416388 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
16389
16390 std::string response_data1;
16391 rv = ReadTransaction(trans1.get(), &response_data1);
robpercival214763f2016-07-01 23:27:0116392 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416393 EXPECT_EQ("first response", response_data1);
16394 // Delete the transaction to release the socket back into the socket pool.
16395 trans1.reset();
16396
danakj1fd259a02016-04-16 03:17:0916397 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216398 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916399 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216400 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416401
16402 HttpRequestInfo request2;
16403 request2.method = "POST";
16404 request2.url = GURL("http://www.foo.com/");
16405 request2.upload_data_stream = &upload_data_stream;
16406 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016407 request2.traffic_annotation =
16408 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416409
bnc691fda62016-08-12 00:43:1616410 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016411 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116412 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416413
16414 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116415 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416416
bnc691fda62016-08-12 00:43:1616417 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5216418 ASSERT_TRUE(response2);
[email protected]02d74a02014-04-23 18:10:5416419
wezca1070932016-05-26 20:30:5216420 EXPECT_TRUE(response2->headers);
[email protected]02d74a02014-04-23 18:10:5416421 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
16422
16423 std::string response_data2;
bnc691fda62016-08-12 00:43:1616424 rv = ReadTransaction(&trans2, &response_data2);
robpercival214763f2016-07-01 23:27:0116425 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416426 EXPECT_EQ("second response", response_data2);
16427}
16428
bncd16676a2016-07-20 16:23:0116429TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5416430 PostReadsErrorResponseAfterResetPartialBodySent) {
danakj1fd259a02016-04-16 03:17:0916431 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216432 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916433 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216434 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416435
16436 HttpRequestInfo request;
16437 request.method = "POST";
16438 request.url = GURL("http://www.foo.com/");
16439 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1016440 request.traffic_annotation =
16441 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416442
danakj1fd259a02016-04-16 03:17:0916443 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616444 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416445 // Send headers successfully, but get an error while sending the body.
16446 MockWrite data_writes[] = {
16447 MockWrite("POST / HTTP/1.1\r\n"
16448 "Host: www.foo.com\r\n"
16449 "Connection: keep-alive\r\n"
16450 "Content-Length: 3\r\n\r\n"
16451 "fo"),
16452 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16453 };
16454
16455 MockRead data_reads[] = {
16456 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16457 MockRead("hello world"),
16458 MockRead(SYNCHRONOUS, OK),
16459 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116460 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5416461 session_deps_.socket_factory->AddSocketDataProvider(&data);
16462
16463 TestCompletionCallback callback;
16464
tfarina42834112016-09-22 13:38:2016465 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116466 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416467
16468 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116469 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416470
bnc691fda62016-08-12 00:43:1616471 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216472 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416473
wezca1070932016-05-26 20:30:5216474 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416475 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16476
16477 std::string response_data;
bnc691fda62016-08-12 00:43:1616478 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116479 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416480 EXPECT_EQ("hello world", response_data);
16481}
16482
16483// This tests the more common case than the previous test, where headers and
16484// body are not merged into a single request.
bncd16676a2016-07-20 16:23:0116485TEST_F(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
mmenkecbc2b712014-10-09 20:29:0716486 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5416487
16488 HttpRequestInfo request;
16489 request.method = "POST";
16490 request.url = GURL("http://www.foo.com/");
16491 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1016492 request.traffic_annotation =
16493 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416494
danakj1fd259a02016-04-16 03:17:0916495 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616496 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416497 // Send headers successfully, but get an error while sending the body.
16498 MockWrite data_writes[] = {
16499 MockWrite("POST / HTTP/1.1\r\n"
16500 "Host: www.foo.com\r\n"
16501 "Connection: keep-alive\r\n"
16502 "Transfer-Encoding: chunked\r\n\r\n"),
16503 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16504 };
16505
16506 MockRead data_reads[] = {
16507 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16508 MockRead("hello world"),
16509 MockRead(SYNCHRONOUS, OK),
16510 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116511 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5416512 session_deps_.socket_factory->AddSocketDataProvider(&data);
16513
16514 TestCompletionCallback callback;
16515
tfarina42834112016-09-22 13:38:2016516 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116517 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416518 // Make sure the headers are sent before adding a chunk. This ensures that
16519 // they can't be merged with the body in a single send. Not currently
16520 // necessary since a chunked body is never merged with headers, but this makes
16521 // the test more future proof.
16522 base::RunLoop().RunUntilIdle();
16523
mmenkecbc2b712014-10-09 20:29:0716524 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5416525
16526 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116527 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416528
bnc691fda62016-08-12 00:43:1616529 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216530 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416531
wezca1070932016-05-26 20:30:5216532 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416533 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16534
16535 std::string response_data;
bnc691fda62016-08-12 00:43:1616536 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116537 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416538 EXPECT_EQ("hello world", response_data);
16539}
16540
bncd16676a2016-07-20 16:23:0116541TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0916542 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216543 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916544 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216545 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416546
16547 HttpRequestInfo request;
16548 request.method = "POST";
16549 request.url = GURL("http://www.foo.com/");
16550 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1016551 request.traffic_annotation =
16552 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416553
danakj1fd259a02016-04-16 03:17:0916554 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616555 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416556
16557 MockWrite data_writes[] = {
16558 MockWrite("POST / HTTP/1.1\r\n"
16559 "Host: www.foo.com\r\n"
16560 "Connection: keep-alive\r\n"
16561 "Content-Length: 3\r\n\r\n"),
16562 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16563 };
16564
16565 MockRead data_reads[] = {
16566 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
16567 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16568 MockRead("hello world"),
16569 MockRead(SYNCHRONOUS, OK),
16570 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116571 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5416572 session_deps_.socket_factory->AddSocketDataProvider(&data);
16573
16574 TestCompletionCallback callback;
16575
tfarina42834112016-09-22 13:38:2016576 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116577 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416578
16579 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116580 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416581
bnc691fda62016-08-12 00:43:1616582 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216583 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416584
wezca1070932016-05-26 20:30:5216585 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416586 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16587
16588 std::string response_data;
bnc691fda62016-08-12 00:43:1616589 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116590 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416591 EXPECT_EQ("hello world", response_data);
16592}
16593
bncd16676a2016-07-20 16:23:0116594TEST_F(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0916595 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216596 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916597 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216598 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416599
16600 HttpRequestInfo request;
16601 request.method = "POST";
16602 request.url = GURL("http://www.foo.com/");
16603 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1016604 request.traffic_annotation =
16605 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416606
danakj1fd259a02016-04-16 03:17:0916607 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616608 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416609 // Send headers successfully, but get an error while sending the body.
16610 MockWrite data_writes[] = {
16611 MockWrite("POST / HTTP/1.1\r\n"
16612 "Host: www.foo.com\r\n"
16613 "Connection: keep-alive\r\n"
16614 "Content-Length: 3\r\n\r\n"),
16615 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16616 };
16617
16618 MockRead data_reads[] = {
16619 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
16620 MockRead("hello world"),
16621 MockRead(SYNCHRONOUS, OK),
16622 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116623 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5416624 session_deps_.socket_factory->AddSocketDataProvider(&data);
16625
16626 TestCompletionCallback callback;
16627
tfarina42834112016-09-22 13:38:2016628 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116629 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416630
16631 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116632 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416633}
16634
bncd16676a2016-07-20 16:23:0116635TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5416636 PostIgnoresNonErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0916637 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216638 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916639 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216640 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416641
16642 HttpRequestInfo request;
16643 request.method = "POST";
16644 request.url = GURL("http://www.foo.com/");
16645 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1016646 request.traffic_annotation =
16647 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416648
danakj1fd259a02016-04-16 03:17:0916649 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616650 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416651 // Send headers successfully, but get an error while sending the body.
16652 MockWrite data_writes[] = {
16653 MockWrite("POST / HTTP/1.1\r\n"
16654 "Host: www.foo.com\r\n"
16655 "Connection: keep-alive\r\n"
16656 "Content-Length: 3\r\n\r\n"),
16657 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16658 };
16659
16660 MockRead data_reads[] = {
16661 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
16662 MockRead("HTTP/1.0 302 Redirect\r\n"),
16663 MockRead("Location: http://somewhere-else.com/\r\n"),
16664 MockRead("Content-Length: 0\r\n\r\n"),
16665 MockRead(SYNCHRONOUS, OK),
16666 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116667 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5416668 session_deps_.socket_factory->AddSocketDataProvider(&data);
16669
16670 TestCompletionCallback callback;
16671
tfarina42834112016-09-22 13:38:2016672 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116673 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416674
16675 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116676 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416677}
16678
bncd16676a2016-07-20 16:23:0116679TEST_F(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0916680 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216681 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916682 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216683 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416684
16685 HttpRequestInfo request;
16686 request.method = "POST";
16687 request.url = GURL("http://www.foo.com/");
16688 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1016689 request.traffic_annotation =
16690 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416691
danakj1fd259a02016-04-16 03:17:0916692 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616693 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416694 // Send headers successfully, but get an error while sending the body.
16695 MockWrite data_writes[] = {
16696 MockWrite("POST / HTTP/1.1\r\n"
16697 "Host: www.foo.com\r\n"
16698 "Connection: keep-alive\r\n"
16699 "Content-Length: 3\r\n\r\n"),
16700 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16701 };
16702
16703 MockRead data_reads[] = {
16704 MockRead("HTTP 0.9 rocks!"),
16705 MockRead(SYNCHRONOUS, OK),
16706 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116707 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5416708 session_deps_.socket_factory->AddSocketDataProvider(&data);
16709
16710 TestCompletionCallback callback;
16711
tfarina42834112016-09-22 13:38:2016712 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116713 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416714
16715 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116716 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416717}
16718
bncd16676a2016-07-20 16:23:0116719TEST_F(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
danakj1fd259a02016-04-16 03:17:0916720 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216721 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916722 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216723 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416724
16725 HttpRequestInfo request;
16726 request.method = "POST";
16727 request.url = GURL("http://www.foo.com/");
16728 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1016729 request.traffic_annotation =
16730 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416731
danakj1fd259a02016-04-16 03:17:0916732 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616733 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416734 // Send headers successfully, but get an error while sending the body.
16735 MockWrite data_writes[] = {
16736 MockWrite("POST / HTTP/1.1\r\n"
16737 "Host: www.foo.com\r\n"
16738 "Connection: keep-alive\r\n"
16739 "Content-Length: 3\r\n\r\n"),
16740 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16741 };
16742
16743 MockRead data_reads[] = {
16744 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
16745 MockRead(SYNCHRONOUS, OK),
16746 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116747 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5416748 session_deps_.socket_factory->AddSocketDataProvider(&data);
16749
16750 TestCompletionCallback callback;
16751
tfarina42834112016-09-22 13:38:2016752 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116753 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416754
16755 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116756 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416757}
16758
Bence Békydca6bd92018-01-30 13:43:0616759#if BUILDFLAG(ENABLE_WEBSOCKETS)
16760
16761namespace {
16762
16763void AddWebSocketHeaders(HttpRequestHeaders* headers) {
16764 headers->SetHeader("Connection", "Upgrade");
16765 headers->SetHeader("Upgrade", "websocket");
16766 headers->SetHeader("Origin", "http://www.example.org");
16767 headers->SetHeader("Sec-WebSocket-Version", "13");
Bence Békydca6bd92018-01-30 13:43:0616768}
16769
16770} // namespace
16771
16772TEST_F(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
Bence Béky2fcf4fa2018-04-06 20:06:0116773 for (bool secure : {true, false}) {
16774 MockWrite data_writes[] = {
16775 MockWrite("GET / HTTP/1.1\r\n"
16776 "Host: www.example.org\r\n"
16777 "Connection: Upgrade\r\n"
16778 "Upgrade: websocket\r\n"
16779 "Origin: http://www.example.org\r\n"
16780 "Sec-WebSocket-Version: 13\r\n"
16781 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
16782 "Sec-WebSocket-Extensions: permessage-deflate; "
16783 "client_max_window_bits\r\n\r\n")};
16784
16785 MockRead data_reads[] = {
16786 MockRead("HTTP/1.1 101 Switching Protocols\r\n"
16787 "Upgrade: websocket\r\n"
16788 "Connection: Upgrade\r\n"
16789 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
16790
Ryan Sleevib8d7ea02018-05-07 20:01:0116791 StaticSocketDataProvider data(data_reads, data_writes);
Bence Béky2fcf4fa2018-04-06 20:06:0116792 session_deps_.socket_factory->AddSocketDataProvider(&data);
16793 SSLSocketDataProvider ssl(ASYNC, OK);
16794 if (secure)
16795 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
Bence Békydca6bd92018-01-30 13:43:0616796
16797 HttpRequestInfo request;
16798 request.method = "GET";
Bence Béky2fcf4fa2018-04-06 20:06:0116799 request.url =
16800 GURL(secure ? "ws://www.example.org/" : "wss://www.example.org/");
16801 AddWebSocketHeaders(&request.extra_headers);
Ramin Halavatib5e433e62018-02-07 07:41:1016802 request.traffic_annotation =
16803 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Békydca6bd92018-01-30 13:43:0616804
Bence Béky2fcf4fa2018-04-06 20:06:0116805 TestWebSocketHandshakeStreamCreateHelper
16806 websocket_handshake_stream_create_helper;
Bence Béky8d1c6052018-02-07 12:48:1516807
Bence Béky2fcf4fa2018-04-06 20:06:0116808 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Bence Békydca6bd92018-01-30 13:43:0616809 HttpNetworkTransaction trans(LOW, session.get());
16810 trans.SetWebSocketHandshakeStreamCreateHelper(
Bence Béky2fcf4fa2018-04-06 20:06:0116811 &websocket_handshake_stream_create_helper);
Bence Békydca6bd92018-01-30 13:43:0616812
16813 TestCompletionCallback callback;
Bence Béky2fcf4fa2018-04-06 20:06:0116814 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
16815 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Bence Békydca6bd92018-01-30 13:43:0616816
Bence Béky2fcf4fa2018-04-06 20:06:0116817 const HttpStreamRequest* stream_request = trans.stream_request_.get();
16818 ASSERT_TRUE(stream_request);
16819 EXPECT_EQ(&websocket_handshake_stream_create_helper,
16820 stream_request->websocket_handshake_stream_create_helper());
16821
16822 rv = callback.WaitForResult();
16823 EXPECT_THAT(rv, IsOk());
16824
16825 EXPECT_TRUE(data.AllReadDataConsumed());
16826 EXPECT_TRUE(data.AllWriteDataConsumed());
Bence Békydca6bd92018-01-30 13:43:0616827 }
16828}
16829
Adam Rice425cf122015-01-19 06:18:2416830// Verify that proxy headers are not sent to the destination server when
16831// establishing a tunnel for a secure WebSocket connection.
bncd16676a2016-07-20 16:23:0116832TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
Adam Rice425cf122015-01-19 06:18:2416833 HttpRequestInfo request;
16834 request.method = "GET";
bncce36dca22015-04-21 22:11:2316835 request.url = GURL("wss://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016836 request.traffic_annotation =
16837 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2416838 AddWebSocketHeaders(&request.extra_headers);
16839
16840 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:5916841 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4916842 ProxyResolutionService::CreateFixedFromPacResult(
16843 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2416844
danakj1fd259a02016-04-16 03:17:0916845 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2416846
16847 // Since a proxy is configured, try to establish a tunnel.
16848 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1716849 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
16850 "Host: www.example.org:443\r\n"
16851 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416852
16853 // After calling trans->RestartWithAuth(), this is the request we should
16854 // be issuing -- the final header line contains the credentials.
rsleevidb16bb02015-11-12 23:47:1716855 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
16856 "Host: www.example.org:443\r\n"
16857 "Proxy-Connection: keep-alive\r\n"
16858 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416859
rsleevidb16bb02015-11-12 23:47:1716860 MockWrite("GET / HTTP/1.1\r\n"
16861 "Host: www.example.org\r\n"
16862 "Connection: Upgrade\r\n"
16863 "Upgrade: websocket\r\n"
16864 "Origin: http://www.example.org\r\n"
16865 "Sec-WebSocket-Version: 13\r\n"
Bence Béky8d1c6052018-02-07 12:48:1516866 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
16867 "Sec-WebSocket-Extensions: permessage-deflate; "
16868 "client_max_window_bits\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2416869
16870 // The proxy responds to the connect with a 407, using a persistent
16871 // connection.
16872 MockRead data_reads[] = {
16873 // No credentials.
Bence Béky8d1c6052018-02-07 12:48:1516874 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"
16875 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
16876 "Content-Length: 0\r\n"
16877 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416878
16879 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
16880
Bence Béky8d1c6052018-02-07 12:48:1516881 MockRead("HTTP/1.1 101 Switching Protocols\r\n"
16882 "Upgrade: websocket\r\n"
16883 "Connection: Upgrade\r\n"
16884 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2416885
Ryan Sleevib8d7ea02018-05-07 20:01:0116886 StaticSocketDataProvider data(data_reads, data_writes);
Adam Rice425cf122015-01-19 06:18:2416887 session_deps_.socket_factory->AddSocketDataProvider(&data);
16888 SSLSocketDataProvider ssl(ASYNC, OK);
16889 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16890
Bence Béky8d1c6052018-02-07 12:48:1516891 TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
16892
bnc87dcefc2017-05-25 12:47:5816893 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1916894 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2416895 trans->SetWebSocketHandshakeStreamCreateHelper(
16896 &websocket_stream_create_helper);
16897
16898 {
16899 TestCompletionCallback callback;
16900
tfarina42834112016-09-22 13:38:2016901 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116902 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2416903
16904 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116905 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2416906 }
16907
16908 const HttpResponseInfo* response = trans->GetResponseInfo();
16909 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5216910 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2416911 EXPECT_EQ(407, response->headers->response_code());
16912
16913 {
16914 TestCompletionCallback callback;
16915
16916 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
16917 callback.callback());
robpercival214763f2016-07-01 23:27:0116918 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2416919
16920 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116921 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2416922 }
16923
16924 response = trans->GetResponseInfo();
16925 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5216926 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2416927
16928 EXPECT_EQ(101, response->headers->response_code());
16929
16930 trans.reset();
16931 session->CloseAllConnections();
16932}
16933
16934// Verify that proxy headers are not sent to the destination server when
16935// establishing a tunnel for an insecure WebSocket connection.
16936// This requires the authentication info to be injected into the auth cache
16937// due to crbug.com/395064
16938// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
bncd16676a2016-07-20 16:23:0116939TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
Adam Rice425cf122015-01-19 06:18:2416940 HttpRequestInfo request;
16941 request.method = "GET";
bncce36dca22015-04-21 22:11:2316942 request.url = GURL("ws://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016943 request.traffic_annotation =
16944 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2416945 AddWebSocketHeaders(&request.extra_headers);
16946
16947 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:5916948 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4916949 ProxyResolutionService::CreateFixedFromPacResult(
16950 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2416951
danakj1fd259a02016-04-16 03:17:0916952 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2416953
16954 MockWrite data_writes[] = {
16955 // Try to establish a tunnel for the WebSocket connection, with
16956 // credentials. Because WebSockets have a separate set of socket pools,
16957 // they cannot and will not use the same TCP/IP connection as the
16958 // preflight HTTP request.
Bence Béky8d1c6052018-02-07 12:48:1516959 MockWrite("CONNECT www.example.org:80 HTTP/1.1\r\n"
16960 "Host: www.example.org:80\r\n"
16961 "Proxy-Connection: keep-alive\r\n"
16962 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416963
Bence Béky8d1c6052018-02-07 12:48:1516964 MockWrite("GET / HTTP/1.1\r\n"
16965 "Host: www.example.org\r\n"
16966 "Connection: Upgrade\r\n"
16967 "Upgrade: websocket\r\n"
16968 "Origin: http://www.example.org\r\n"
16969 "Sec-WebSocket-Version: 13\r\n"
16970 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
16971 "Sec-WebSocket-Extensions: permessage-deflate; "
16972 "client_max_window_bits\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2416973
16974 MockRead data_reads[] = {
16975 // HTTP CONNECT with credentials.
16976 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
16977
16978 // WebSocket connection established inside tunnel.
Bence Béky8d1c6052018-02-07 12:48:1516979 MockRead("HTTP/1.1 101 Switching Protocols\r\n"
16980 "Upgrade: websocket\r\n"
16981 "Connection: Upgrade\r\n"
16982 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2416983
Ryan Sleevib8d7ea02018-05-07 20:01:0116984 StaticSocketDataProvider data(data_reads, data_writes);
Adam Rice425cf122015-01-19 06:18:2416985 session_deps_.socket_factory->AddSocketDataProvider(&data);
16986
16987 session->http_auth_cache()->Add(
16988 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
16989 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
16990
Bence Béky8d1c6052018-02-07 12:48:1516991 TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
16992
bnc87dcefc2017-05-25 12:47:5816993 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1916994 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2416995 trans->SetWebSocketHandshakeStreamCreateHelper(
16996 &websocket_stream_create_helper);
16997
16998 TestCompletionCallback callback;
16999
tfarina42834112016-09-22 13:38:2017000 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117001 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2417002
17003 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117004 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2417005
17006 const HttpResponseInfo* response = trans->GetResponseInfo();
17007 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5217008 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2417009
17010 EXPECT_EQ(101, response->headers->response_code());
17011
17012 trans.reset();
17013 session->CloseAllConnections();
17014}
17015
Bence Békydca6bd92018-01-30 13:43:0617016#endif // BUILDFLAG(ENABLE_WEBSOCKETS)
17017
bncd16676a2016-07-20 16:23:0117018TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost) {
danakj1fd259a02016-04-16 03:17:0917019 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217020 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917021 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217022 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2217023
17024 HttpRequestInfo request;
17025 request.method = "POST";
17026 request.url = GURL("http://www.foo.com/");
17027 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017028 request.traffic_annotation =
17029 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2217030
danakj1fd259a02016-04-16 03:17:0917031 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617032 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2217033 MockWrite data_writes[] = {
17034 MockWrite("POST / HTTP/1.1\r\n"
17035 "Host: www.foo.com\r\n"
17036 "Connection: keep-alive\r\n"
17037 "Content-Length: 3\r\n\r\n"),
17038 MockWrite("foo"),
17039 };
17040
17041 MockRead data_reads[] = {
17042 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
17043 MockRead(SYNCHRONOUS, OK),
17044 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117045 StaticSocketDataProvider data(data_reads, data_writes);
sclittlefb249892015-09-10 21:33:2217046 session_deps_.socket_factory->AddSocketDataProvider(&data);
17047
17048 TestCompletionCallback callback;
17049
17050 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017051 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0117052 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2217053
17054 std::string response_data;
bnc691fda62016-08-12 00:43:1617055 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2217056
Ryan Sleevib8d7ea02018-05-07 20:01:0117057 EXPECT_EQ(CountWriteBytes(data_writes), trans.GetTotalSentBytes());
17058 EXPECT_EQ(CountReadBytes(data_reads), trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2217059}
17060
bncd16676a2016-07-20 16:23:0117061TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost100Continue) {
danakj1fd259a02016-04-16 03:17:0917062 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217063 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917064 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217065 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2217066
17067 HttpRequestInfo request;
17068 request.method = "POST";
17069 request.url = GURL("http://www.foo.com/");
17070 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017071 request.traffic_annotation =
17072 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2217073
danakj1fd259a02016-04-16 03:17:0917074 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617075 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2217076 MockWrite data_writes[] = {
17077 MockWrite("POST / HTTP/1.1\r\n"
17078 "Host: www.foo.com\r\n"
17079 "Connection: keep-alive\r\n"
17080 "Content-Length: 3\r\n\r\n"),
17081 MockWrite("foo"),
17082 };
17083
17084 MockRead data_reads[] = {
17085 MockRead("HTTP/1.1 100 Continue\r\n\r\n"),
17086 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
17087 MockRead(SYNCHRONOUS, OK),
17088 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117089 StaticSocketDataProvider data(data_reads, data_writes);
sclittlefb249892015-09-10 21:33:2217090 session_deps_.socket_factory->AddSocketDataProvider(&data);
17091
17092 TestCompletionCallback callback;
17093
17094 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017095 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0117096 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2217097
17098 std::string response_data;
bnc691fda62016-08-12 00:43:1617099 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2217100
Ryan Sleevib8d7ea02018-05-07 20:01:0117101 EXPECT_EQ(CountWriteBytes(data_writes), trans.GetTotalSentBytes());
17102 EXPECT_EQ(CountReadBytes(data_reads), trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2217103}
17104
bncd16676a2016-07-20 16:23:0117105TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) {
sclittlefb249892015-09-10 21:33:2217106 ChunkedUploadDataStream upload_data_stream(0);
17107
17108 HttpRequestInfo request;
17109 request.method = "POST";
17110 request.url = GURL("http://www.foo.com/");
17111 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017112 request.traffic_annotation =
17113 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2217114
danakj1fd259a02016-04-16 03:17:0917115 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617116 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2217117 // Send headers successfully, but get an error while sending the body.
17118 MockWrite data_writes[] = {
17119 MockWrite("POST / HTTP/1.1\r\n"
17120 "Host: www.foo.com\r\n"
17121 "Connection: keep-alive\r\n"
17122 "Transfer-Encoding: chunked\r\n\r\n"),
17123 MockWrite("1\r\nf\r\n"), MockWrite("2\r\noo\r\n"), MockWrite("0\r\n\r\n"),
17124 };
17125
17126 MockRead data_reads[] = {
17127 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
17128 MockRead(SYNCHRONOUS, OK),
17129 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117130 StaticSocketDataProvider data(data_reads, data_writes);
sclittlefb249892015-09-10 21:33:2217131 session_deps_.socket_factory->AddSocketDataProvider(&data);
17132
17133 TestCompletionCallback callback;
17134
17135 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017136 trans.Start(&request, callback.callback(), NetLogWithSource()));
sclittlefb249892015-09-10 21:33:2217137
17138 base::RunLoop().RunUntilIdle();
17139 upload_data_stream.AppendData("f", 1, false);
17140
17141 base::RunLoop().RunUntilIdle();
17142 upload_data_stream.AppendData("oo", 2, true);
17143
robpercival214763f2016-07-01 23:27:0117144 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2217145
17146 std::string response_data;
bnc691fda62016-08-12 00:43:1617147 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2217148
Ryan Sleevib8d7ea02018-05-07 20:01:0117149 EXPECT_EQ(CountWriteBytes(data_writes), trans.GetTotalSentBytes());
17150 EXPECT_EQ(CountReadBytes(data_reads), trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2217151}
17152
nharperb7441ef2016-01-25 23:54:1417153#if !defined(OS_IOS)
bncd16676a2016-07-20 16:23:0117154TEST_F(HttpNetworkTransactionTest, TokenBindingSpdy) {
nharperb7441ef2016-01-25 23:54:1417155 const std::string https_url = "https://www.example.com";
17156 HttpRequestInfo request;
17157 request.url = GURL(https_url);
17158 request.method = "GET";
Ramin Halavatib5e433e62018-02-07 07:41:1017159 request.traffic_annotation =
17160 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
nharperb7441ef2016-01-25 23:54:1417161
17162 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4917163 ssl.ssl_info.token_binding_negotiated = true;
17164 ssl.ssl_info.token_binding_key_param = TB_PARAM_ECDSAP256;
bnc3cf2a592016-08-11 14:48:3617165 ssl.next_proto = kProtoHTTP2;
nharperb7441ef2016-01-25 23:54:1417166 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
17167
Ryan Hamilton0239aac2018-05-19 00:03:1317168 spdy::SpdySerializedFrame resp(
17169 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
17170 spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
bncdf80d44fd2016-07-15 20:27:4117171 MockRead reads[] = {CreateMockRead(resp), CreateMockRead(body),
nharperb7441ef2016-01-25 23:54:1417172 MockRead(ASYNC, ERR_IO_PENDING)};
Ryan Sleevib8d7ea02018-05-07 20:01:0117173 StaticSocketDataProvider data(reads, base::span<MockWrite>());
nharperb7441ef2016-01-25 23:54:1417174 session_deps_.socket_factory->AddSocketDataProvider(&data);
bnc87dcefc2017-05-25 12:47:5817175 session_deps_.channel_id_service =
Jeremy Roman0579ed62017-08-29 15:56:1917176 std::make_unique<ChannelIDService>(new DefaultChannelIDStore(nullptr));
danakj1fd259a02016-04-16 03:17:0917177 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
nharperb7441ef2016-01-25 23:54:1417178
17179 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17180 TestCompletionCallback callback;
17181 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017182 trans.Start(&request, callback.callback(), NetLogWithSource()));
fdorayf33fede2017-05-11 21:18:1017183
Bence Béky98447b12018-05-08 03:14:0117184 RunUntilIdle();
nharperb7441ef2016-01-25 23:54:1417185
17186 EXPECT_TRUE(trans.GetResponseInfo()->was_fetched_via_spdy);
17187 HttpRequestHeaders headers;
17188 ASSERT_TRUE(trans.GetFullRequestHeaders(&headers));
17189 EXPECT_TRUE(headers.HasHeader(HttpRequestHeaders::kTokenBinding));
17190}
17191#endif // !defined(OS_IOS)
17192
eustasc7d27da2017-04-06 10:33:2017193void CheckContentEncodingMatching(SpdySessionDependencies* session_deps,
17194 const std::string& accept_encoding,
17195 const std::string& content_encoding,
sky50576f32017-05-01 19:28:0317196 const std::string& location,
eustasc7d27da2017-04-06 10:33:2017197 bool should_match) {
17198 HttpRequestInfo request;
17199 request.method = "GET";
17200 request.url = GURL("http://www.foo.com/");
17201 request.extra_headers.SetHeader(HttpRequestHeaders::kAcceptEncoding,
17202 accept_encoding);
Ramin Halavatib5e433e62018-02-07 07:41:1017203 request.traffic_annotation =
17204 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
eustasc7d27da2017-04-06 10:33:2017205
17206 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps));
17207 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17208 // Send headers successfully, but get an error while sending the body.
17209 MockWrite data_writes[] = {
17210 MockWrite("GET / HTTP/1.1\r\n"
17211 "Host: www.foo.com\r\n"
17212 "Connection: keep-alive\r\n"
17213 "Accept-Encoding: "),
17214 MockWrite(accept_encoding.data()), MockWrite("\r\n\r\n"),
17215 };
17216
sky50576f32017-05-01 19:28:0317217 std::string response_code = "200 OK";
17218 std::string extra;
17219 if (!location.empty()) {
17220 response_code = "301 Redirect\r\nLocation: ";
17221 response_code.append(location);
17222 }
17223
eustasc7d27da2017-04-06 10:33:2017224 MockRead data_reads[] = {
sky50576f32017-05-01 19:28:0317225 MockRead("HTTP/1.0 "),
17226 MockRead(response_code.data()),
17227 MockRead("\r\nContent-Encoding: "),
17228 MockRead(content_encoding.data()),
17229 MockRead("\r\n\r\n"),
eustasc7d27da2017-04-06 10:33:2017230 MockRead(SYNCHRONOUS, OK),
17231 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117232 StaticSocketDataProvider data(data_reads, data_writes);
eustasc7d27da2017-04-06 10:33:2017233 session_deps->socket_factory->AddSocketDataProvider(&data);
17234
17235 TestCompletionCallback callback;
17236
17237 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17238 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17239
17240 rv = callback.WaitForResult();
17241 if (should_match) {
17242 EXPECT_THAT(rv, IsOk());
17243 } else {
17244 EXPECT_THAT(rv, IsError(ERR_CONTENT_DECODING_FAILED));
17245 }
17246}
17247
17248TEST_F(HttpNetworkTransactionTest, MatchContentEncoding1) {
sky50576f32017-05-01 19:28:0317249 CheckContentEncodingMatching(&session_deps_, "gzip,sdch", "br", "", false);
eustasc7d27da2017-04-06 10:33:2017250}
17251
17252TEST_F(HttpNetworkTransactionTest, MatchContentEncoding2) {
sky50576f32017-05-01 19:28:0317253 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "", "",
17254 true);
eustasc7d27da2017-04-06 10:33:2017255}
17256
17257TEST_F(HttpNetworkTransactionTest, MatchContentEncoding3) {
17258 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
sky50576f32017-05-01 19:28:0317259 "", false);
17260}
17261
17262TEST_F(HttpNetworkTransactionTest, MatchContentEncoding4) {
17263 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
17264 "www.foo.com/other", true);
eustasc7d27da2017-04-06 10:33:2017265}
17266
xunjieli96f2a402017-06-05 17:24:2717267TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsSync) {
17268 ProxyConfig proxy_config;
17269 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
17270 proxy_config.set_pac_mandatory(true);
17271 MockAsyncProxyResolver resolver;
Lily Houghton8c2f97d2018-01-22 05:06:5917272 session_deps_.proxy_resolution_service.reset(new ProxyResolutionService(
Ramin Halavatica8d5252018-03-12 05:33:4917273 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
17274 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
Bence Béky8f9d7d3952017-10-09 19:58:0417275 std::make_unique<FailingProxyResolverFactory>(), nullptr));
xunjieli96f2a402017-06-05 17:24:2717276
17277 HttpRequestInfo request;
17278 request.method = "GET";
17279 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1017280 request.traffic_annotation =
17281 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2717282
17283 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17284 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17285
17286 TestCompletionCallback callback;
17287
17288 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17289 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17290 EXPECT_THAT(callback.WaitForResult(),
17291 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
17292}
17293
17294TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsAsync) {
17295 ProxyConfig proxy_config;
17296 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
17297 proxy_config.set_pac_mandatory(true);
17298 MockAsyncProxyResolverFactory* proxy_resolver_factory =
17299 new MockAsyncProxyResolverFactory(false);
17300 MockAsyncProxyResolver resolver;
Lily Houghton8c2f97d2018-01-22 05:06:5917301 session_deps_.proxy_resolution_service.reset(new ProxyResolutionService(
Ramin Halavatica8d5252018-03-12 05:33:4917302 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
17303 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
Lily Houghton8c2f97d2018-01-22 05:06:5917304 base::WrapUnique(proxy_resolver_factory), nullptr));
xunjieli96f2a402017-06-05 17:24:2717305 HttpRequestInfo request;
17306 request.method = "GET";
17307 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1017308 request.traffic_annotation =
17309 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2717310
17311 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17312 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17313
17314 TestCompletionCallback callback;
17315 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17316 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17317
17318 proxy_resolver_factory->pending_requests()[0]->CompleteNowWithForwarder(
17319 ERR_FAILED, &resolver);
17320 EXPECT_THAT(callback.WaitForResult(),
17321 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
17322}
17323
17324TEST_F(HttpNetworkTransactionTest, NoSupportedProxies) {
Lily Houghton8c2f97d2018-01-22 05:06:5917325 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4917326 ProxyResolutionService::CreateFixedFromPacResult(
17327 "QUIC myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2717328 session_deps_.enable_quic = false;
17329 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17330
17331 HttpRequestInfo request;
17332 request.method = "GET";
17333 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1017334 request.traffic_annotation =
17335 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2717336
17337 TestCompletionCallback callback;
17338 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17339 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17340 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17341
17342 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NO_SUPPORTED_PROXIES));
17343}
17344
[email protected]89ceba9a2009-03-21 03:46:0617345} // namespace net