blob: 250598d55c87d9e8214f5de98f88c76d7fbc088c [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"
Bence Békya25e3f72018-02-13 21:13:3933#include "net/base/completion_once_callback.h"
mmenkecbc2b712014-10-09 20:29:0734#include "net/base/elements_upload_data_stream.h"
[email protected]58e32bb2013-01-21 18:23:2535#include "net/base/load_timing_info.h"
36#include "net/base/load_timing_info_test_util.h"
Adam Rice425cf122015-01-19 06:18:2437#include "net/base/net_errors.h"
tbansal28e68f82016-02-04 02:56:1538#include "net/base/proxy_delegate.h"
Lily Houghton582d4622018-01-22 22:43:4039#include "net/base/proxy_server.h"
[email protected]ac790b42009-12-02 04:31:3140#include "net/base/request_priority.h"
initial.commit586acc5fe2008-07-26 22:42:5241#include "net/base/test_completion_callback.h"
tbansal28e68f82016-02-04 02:56:1542#include "net/base/test_proxy_delegate.h"
[email protected]b2d26cfd2012-12-11 10:36:0643#include "net/base/upload_bytes_element_reader.h"
[email protected]d98961652012-09-11 20:27:2144#include "net/base/upload_file_element_reader.h"
Bence Béky230ac612017-08-30 19:17:0845#include "net/cert/cert_status_flags.h"
[email protected]6e7845ae2013-03-29 21:48:1146#include "net/cert/mock_cert_verifier.h"
[email protected]bc71b8772013-04-10 20:55:1647#include "net/dns/host_cache.h"
[email protected]f2cb3cf2013-03-21 01:40:5348#include "net/dns/mock_host_resolver.h"
[email protected]df41d0d82014-03-13 00:43:2449#include "net/http/http_auth_challenge_tokenizer.h"
[email protected]3c32c5f2010-05-18 15:18:1250#include "net/http/http_auth_handler_digest.h"
[email protected]3fd9dae2010-06-21 11:39:0051#include "net/http/http_auth_handler_mock.h"
[email protected]385a4672009-03-11 22:21:2952#include "net/http/http_auth_handler_ntlm.h"
aberentbba302d2015-12-03 10:20:1953#include "net/http/http_auth_scheme.h"
[email protected]0877e3d2009-10-17 22:29:5754#include "net/http/http_basic_stream.h"
initial.commit586acc5fe2008-07-26 22:42:5255#include "net/http/http_network_session.h"
[email protected]87bfa3f2010-09-30 14:54:5656#include "net/http/http_network_session_peer.h"
Adam Rice425cf122015-01-19 06:18:2457#include "net/http/http_request_headers.h"
mmenke5f94fda2016-06-02 20:54:1358#include "net/http/http_response_info.h"
[email protected]17291a022011-10-10 07:32:5359#include "net/http/http_server_properties_impl.h"
[email protected]0877e3d2009-10-17 22:29:5760#include "net/http/http_stream.h"
[email protected]8e6441ca2010-08-19 05:56:3861#include "net/http/http_stream_factory.h"
[email protected]c41737d2014-05-14 07:47:1962#include "net/http/http_transaction_test_util.h"
eroman87c53d62015-04-02 06:51:0763#include "net/log/net_log.h"
mikecirone8b85c432016-09-08 19:11:0064#include "net/log/net_log_event_type.h"
mikecironef22f9812016-10-04 03:40:1965#include "net/log/net_log_source.h"
vishal.b62985ca92015-04-17 08:45:5166#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4667#include "net/log/test_net_log_entry.h"
68#include "net/log/test_net_log_util.h"
Lily Houghton582d4622018-01-22 22:43:4069#include "net/proxy_resolution/mock_proxy_resolver.h"
70#include "net/proxy_resolution/proxy_config_service_fixed.h"
71#include "net/proxy_resolution/proxy_info.h"
Lily Houghtonffe89daa02018-03-09 18:30:0372#include "net/proxy_resolution/proxy_resolution_service.h"
Lily Houghton582d4622018-01-22 22:43:4073#include "net/proxy_resolution/proxy_resolver.h"
74#include "net/proxy_resolution/proxy_resolver_factory.h"
[email protected]f7984fc62009-06-22 23:26:4475#include "net/socket/client_socket_factory.h"
mmenked3641e12016-01-28 16:06:1576#include "net/socket/client_socket_pool.h"
[email protected]483fa202013-05-14 01:07:0377#include "net/socket/client_socket_pool_manager.h"
ttuttle1f2d7e92015-04-28 16:17:4778#include "net/socket/connection_attempts.h"
[email protected]a42dbd142011-11-17 16:42:0279#include "net/socket/mock_client_socket_pool_manager.h"
[email protected]bb88e1d32013-05-03 23:11:0780#include "net/socket/next_proto.h"
Paul Jensena457017a2018-01-19 23:52:0481#include "net/socket/socket_tag.h"
[email protected]f7984fc62009-06-22 23:26:4482#include "net/socket/socket_test_util.h"
83#include "net/socket/ssl_client_socket.h"
Bence Béky94658bf2018-05-11 19:22:5884#include "net/spdy/spdy_session.h"
85#include "net/spdy/spdy_session_pool.h"
86#include "net/spdy/spdy_test_util_common.h"
nharperb7441ef2016-01-25 23:54:1487#include "net/ssl/default_channel_id_store.h"
[email protected]536fd0b2013-03-14 17:41:5788#include "net/ssl/ssl_cert_request_info.h"
[email protected]e86839fd2013-08-14 18:29:0389#include "net/ssl/ssl_config_service.h"
[email protected]536fd0b2013-03-14 17:41:5790#include "net/ssl/ssl_info.h"
svaldez7872fd02015-11-19 21:10:5491#include "net/ssl/ssl_private_key.h"
[email protected]6e7845ae2013-03-29 21:48:1192#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:0193#include "net/test/gtest_util.h"
rsleevia69c79a2016-06-22 03:28:4394#include "net/test/test_data_directory.h"
Bence Béky98447b12018-05-08 03:14:0195#include "net/test/test_with_scoped_task_environment.h"
Ryan Hamilton2e003eea2018-05-02 00:24:2996#include "net/third_party/spdy/core/spdy_framer.h"
[email protected]baee31a2018-01-18 06:10:2397#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
[email protected]831e4a32013-11-14 02:14:4498#include "net/websockets/websocket_handshake_stream_base.h"
Bence Békydca6bd92018-01-30 13:43:0699#include "net/websockets/websocket_test_util.h"
bncf4588402015-11-24 13:33:18100#include "testing/gmock/include/gmock/gmock.h"
initial.commit586acc5fe2008-07-26 22:42:52101#include "testing/gtest/include/gtest/gtest.h"
[email protected]23887f04f2008-12-02 19:20:15102#include "testing/platform_test.h"
[email protected]795cbf82013-07-22 09:37:27103#include "url/gurl.h"
initial.commit586acc5fe2008-07-26 22:42:52104
Zentaro Kavanagh5b27a6e22017-09-25 23:00:37105#if defined(NTLM_PORTABLE)
106#include "base/base64.h"
107#include "net/ntlm/ntlm_test_data.h"
108#endif
109
robpercival214763f2016-07-01 23:27:01110using net::test::IsError;
111using net::test::IsOk;
112
[email protected]ad65a3e2013-12-25 18:18:01113using base::ASCIIToUTF16;
114
initial.commit586acc5fe2008-07-26 22:42:52115//-----------------------------------------------------------------------------
116
ttuttle859dc7a2015-04-23 19:42:29117namespace net {
118
[email protected]13c8a092010-07-29 06:15:44119namespace {
120
[email protected]42cba2fb2013-03-29 19:58:57121const base::string16 kBar(ASCIIToUTF16("bar"));
122const base::string16 kBar2(ASCIIToUTF16("bar2"));
123const base::string16 kBar3(ASCIIToUTF16("bar3"));
124const base::string16 kBaz(ASCIIToUTF16("baz"));
125const base::string16 kFirst(ASCIIToUTF16("first"));
126const base::string16 kFoo(ASCIIToUTF16("foo"));
127const base::string16 kFoo2(ASCIIToUTF16("foo2"));
128const base::string16 kFoo3(ASCIIToUTF16("foo3"));
129const base::string16 kFou(ASCIIToUTF16("fou"));
130const base::string16 kSecond(ASCIIToUTF16("second"));
[email protected]42cba2fb2013-03-29 19:58:57131const base::string16 kWrongPassword(ASCIIToUTF16("wrongpassword"));
[email protected]13c8a092010-07-29 06:15:44132
bnc2df4b522016-07-08 18:17:43133const char kAlternativeServiceHttpHeader[] =
134 "Alt-Svc: h2=\"mail.example.org:443\"\r\n";
135
ttuttle859dc7a2015-04-23 19:42:29136int GetIdleSocketCountInTransportSocketPool(HttpNetworkSession* session) {
137 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
138 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02139}
140
ttuttle859dc7a2015-04-23 19:42:29141int GetIdleSocketCountInSSLSocketPool(HttpNetworkSession* session) {
142 return session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
143 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02144}
145
ttuttle859dc7a2015-04-23 19:42:29146bool IsTransportSocketPoolStalled(HttpNetworkSession* session) {
147 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
148 ->IsStalled();
[email protected]043b68c82013-08-22 23:41:52149}
150
[email protected]f3da152d2012-06-02 01:00:57151// Takes in a Value created from a NetLogHttpResponseParameter, and returns
152// a JSONified list of headers as a single string. Uses single quotes instead
153// of double quotes for easier comparison. Returns false on failure.
[email protected]ea5ef4c2013-06-13 22:50:27154bool GetHeaders(base::DictionaryValue* params, std::string* headers) {
[email protected]f3da152d2012-06-02 01:00:57155 if (!params)
156 return false;
[email protected]ea5ef4c2013-06-13 22:50:27157 base::ListValue* header_list;
[email protected]f3da152d2012-06-02 01:00:57158 if (!params->GetList("headers", &header_list))
159 return false;
160 std::string double_quote_headers;
estade8d046462015-05-16 01:02:34161 base::JSONWriter::Write(*header_list, &double_quote_headers);
[email protected]466c9862013-12-03 22:05:28162 base::ReplaceChars(double_quote_headers, "\"", "'", headers);
[email protected]f3da152d2012-06-02 01:00:57163 return true;
164}
165
[email protected]029c83b62013-01-24 05:28:20166// Tests LoadTimingInfo in the case a socket is reused and no PAC script is
167// used.
ttuttle859dc7a2015-04-23 19:42:29168void TestLoadTimingReused(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20169 EXPECT_TRUE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19170 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]58e32bb2013-01-21 18:23:25171
[email protected]029c83b62013-01-24 05:28:20172 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
173 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
174
ttuttle859dc7a2015-04-23 19:42:29175 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20176 EXPECT_FALSE(load_timing_info.send_start.is_null());
[email protected]58e32bb2013-01-21 18:23:25177
178 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]58e32bb2013-01-21 18:23:25179
[email protected]3b23a222013-05-15 21:33:25180 // Set at a higher level.
[email protected]58e32bb2013-01-21 18:23:25181 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
182 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25183 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25184}
185
[email protected]029c83b62013-01-24 05:28:20186// Tests LoadTimingInfo in the case a new socket is used and no PAC script is
187// used.
ttuttle859dc7a2015-04-23 19:42:29188void TestLoadTimingNotReused(const LoadTimingInfo& load_timing_info,
[email protected]58e32bb2013-01-21 18:23:25189 int connect_timing_flags) {
[email protected]029c83b62013-01-24 05:28:20190 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19191 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20192
193 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
194 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
195
ttuttle859dc7a2015-04-23 19:42:29196 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
197 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20198 EXPECT_LE(load_timing_info.connect_timing.connect_end,
199 load_timing_info.send_start);
200
201 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20202
[email protected]3b23a222013-05-15 21:33:25203 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20204 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
205 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25206 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20207}
208
209// Tests LoadTimingInfo in the case a socket is reused and a PAC script is
210// used.
ttuttle859dc7a2015-04-23 19:42:29211void TestLoadTimingReusedWithPac(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20212 EXPECT_TRUE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19213 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20214
ttuttle859dc7a2015-04-23 19:42:29215 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20216
217 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
218 EXPECT_LE(load_timing_info.proxy_resolve_start,
219 load_timing_info.proxy_resolve_end);
220 EXPECT_LE(load_timing_info.proxy_resolve_end,
221 load_timing_info.send_start);
222 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20223
[email protected]3b23a222013-05-15 21:33:25224 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20225 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
226 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25227 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20228}
229
230// Tests LoadTimingInfo in the case a new socket is used and a PAC script is
231// used.
ttuttle859dc7a2015-04-23 19:42:29232void TestLoadTimingNotReusedWithPac(const LoadTimingInfo& load_timing_info,
[email protected]029c83b62013-01-24 05:28:20233 int connect_timing_flags) {
234 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19235 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20236
237 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
238 EXPECT_LE(load_timing_info.proxy_resolve_start,
239 load_timing_info.proxy_resolve_end);
240 EXPECT_LE(load_timing_info.proxy_resolve_end,
241 load_timing_info.connect_timing.connect_start);
ttuttle859dc7a2015-04-23 19:42:29242 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
243 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20244 EXPECT_LE(load_timing_info.connect_timing.connect_end,
245 load_timing_info.send_start);
246
247 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20248
[email protected]3b23a222013-05-15 21:33:25249 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20250 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
251 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25252 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25253}
254
danakj1fd259a02016-04-16 03:17:09255std::unique_ptr<HttpNetworkSession> CreateSession(
mmenkee65e7af2015-10-13 17:16:42256 SpdySessionDependencies* session_deps) {
[email protected]c6bf8152012-12-02 07:43:34257 return SpdySessionDependencies::SpdyCreateSession(session_deps);
[email protected]e8d536192008-10-17 22:21:14258}
259
xunjieli96f2a402017-06-05 17:24:27260class FailingProxyResolverFactory : public ProxyResolverFactory {
261 public:
262 FailingProxyResolverFactory() : ProxyResolverFactory(false) {}
263
264 // ProxyResolverFactory override.
Lily Houghton99597862018-03-07 16:40:42265 int CreateProxyResolver(const scoped_refptr<PacFileData>& script_data,
266 std::unique_ptr<ProxyResolver>* result,
Bence Békycc5b88a2018-05-25 20:24:17267 CompletionOnceCallback callback,
Lily Houghton99597862018-03-07 16:40:42268 std::unique_ptr<Request>* request) override {
xunjieli96f2a402017-06-05 17:24:27269 return ERR_PAC_SCRIPT_FAILED;
270 }
271};
272
David Benjamin5cb91132018-04-06 05:54:49273class TestSSLConfigService : public SSLConfigService {
274 public:
275 explicit TestSSLConfigService(const SSLConfig& config) : config_(config) {}
Ryan Sleevib8449e02018-07-15 04:31:07276 ~TestSSLConfigService() override = default;
David Benjamin5cb91132018-04-06 05:54:49277
278 void GetSSLConfig(SSLConfig* config) override { *config = config_; }
279
Nick Harper89bc7212018-07-31 19:07:57280 bool CanShareConnectionWithClientCerts(
281 const std::string& hostname) const override {
282 return false;
283 }
284
David Benjamin5cb91132018-04-06 05:54:49285 private:
David Benjamin5cb91132018-04-06 05:54:49286 SSLConfig config_;
287};
288
[email protected]448d4ca52012-03-04 04:12:23289} // namespace
290
Bence Béky98447b12018-05-08 03:14:01291class HttpNetworkTransactionTest : public PlatformTest,
292 public WithScopedTaskEnvironment {
[email protected]483fa202013-05-14 01:07:03293 public:
bncd16676a2016-07-20 16:23:01294 ~HttpNetworkTransactionTest() override {
[email protected]483fa202013-05-14 01:07:03295 // Important to restore the per-pool limit first, since the pool limit must
296 // always be greater than group limit, and the tests reduce both limits.
297 ClientSocketPoolManager::set_max_sockets_per_pool(
298 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
299 ClientSocketPoolManager::set_max_sockets_per_group(
300 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
301 }
302
[email protected]e3ceb682011-06-28 23:55:46303 protected:
[email protected]23e482282013-06-14 16:08:02304 HttpNetworkTransactionTest()
bnc032658ba2016-09-26 18:17:15305 : ssl_(ASYNC, OK),
306 old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
[email protected]483fa202013-05-14 01:07:03307 HttpNetworkSession::NORMAL_SOCKET_POOL)),
308 old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
309 HttpNetworkSession::NORMAL_SOCKET_POOL)) {
bnca86731e2017-04-17 12:31:28310 session_deps_.enable_http2_alternative_service = true;
[email protected]483fa202013-05-14 01:07:03311 }
[email protected]bb88e1d32013-05-03 23:11:07312
[email protected]e3ceb682011-06-28 23:55:46313 struct SimpleGetHelperResult {
314 int rv;
315 std::string status_line;
316 std::string response_data;
sclittlefb249892015-09-10 21:33:22317 int64_t total_received_bytes;
318 int64_t total_sent_bytes;
[email protected]58e32bb2013-01-21 18:23:25319 LoadTimingInfo load_timing_info;
ttuttle1f2d7e92015-04-28 16:17:47320 ConnectionAttempts connection_attempts;
ttuttled9dbc652015-09-29 20:00:59321 IPEndPoint remote_endpoint_after_start;
[email protected]e3ceb682011-06-28 23:55:46322 };
323
dcheng67be2b1f2014-10-27 21:47:29324 void SetUp() override {
[email protected]0b0bf032010-09-21 18:08:50325 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55326 base::RunLoop().RunUntilIdle();
[email protected]2ff8b312010-04-26 22:20:54327 }
328
dcheng67be2b1f2014-10-27 21:47:29329 void TearDown() override {
[email protected]0b0bf032010-09-21 18:08:50330 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55331 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09332 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:55333 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09334 PlatformTest::TearDown();
[email protected]0b0bf032010-09-21 18:08:50335 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55336 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09337 }
338
[email protected]202965992011-12-07 23:04:51339 // Either |write_failure| specifies a write failure or |read_failure|
340 // specifies a read failure when using a reused socket. In either case, the
341 // failure should cause the network transaction to resend the request, and the
342 // other argument should be NULL.
343 void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
344 const MockRead* read_failure);
initial.commit586acc5fe2008-07-26 22:42:52345
[email protected]a34f61ee2014-03-18 20:59:49346 // Either |write_failure| specifies a write failure or |read_failure|
347 // specifies a read failure when using a reused socket. In either case, the
348 // failure should cause the network transaction to resend the request, and the
349 // other argument should be NULL.
350 void PreconnectErrorResendRequestTest(const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:10351 const MockRead* read_failure,
352 bool use_spdy);
[email protected]a34f61ee2014-03-18 20:59:49353
Ryan Sleevib8d7ea02018-05-07 20:01:01354 SimpleGetHelperResult SimpleGetHelperForData(
355 base::span<StaticSocketDataProvider*> providers) {
[email protected]ff007e162009-05-23 09:13:15356 SimpleGetHelperResult out;
initial.commit586acc5fe2008-07-26 22:42:52357
[email protected]ff007e162009-05-23 09:13:15358 HttpRequestInfo request;
359 request.method = "GET";
bncce36dca22015-04-21 22:11:23360 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:10361 request.traffic_annotation =
362 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:52363
vishal.b62985ca92015-04-17 08:45:51364 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:07365 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:09366 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16367 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:27368
Ryan Sleevib8d7ea02018-05-07 20:01:01369 for (auto* provider : providers) {
370 session_deps_.socket_factory->AddSocketDataProvider(provider);
[email protected]5a60c8b2011-10-19 20:14:29371 }
initial.commit586acc5fe2008-07-26 22:42:52372
[email protected]49639fa2011-12-20 23:22:41373 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52374
eroman24bc6a12015-05-06 19:55:48375 EXPECT_TRUE(log.bound().IsCapturing());
bnc691fda62016-08-12 00:43:16376 int rv = trans.Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:01377 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:52378
[email protected]ff007e162009-05-23 09:13:15379 out.rv = callback.WaitForResult();
bnc691fda62016-08-12 00:43:16380 out.total_received_bytes = trans.GetTotalReceivedBytes();
381 out.total_sent_bytes = trans.GetTotalSentBytes();
[email protected]58e32bb2013-01-21 18:23:25382
383 // Even in the failure cases that use this function, connections are always
384 // successfully established before the error.
bnc691fda62016-08-12 00:43:16385 EXPECT_TRUE(trans.GetLoadTimingInfo(&out.load_timing_info));
[email protected]58e32bb2013-01-21 18:23:25386 TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
387
[email protected]ff007e162009-05-23 09:13:15388 if (out.rv != OK)
389 return out;
390
bnc691fda62016-08-12 00:43:16391 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50392 // Can't use ASSERT_* inside helper functions like this, so
393 // return an error.
wezca1070932016-05-26 20:30:52394 if (!response || !response->headers) {
[email protected]fe2255a2011-09-20 19:37:50395 out.rv = ERR_UNEXPECTED;
396 return out;
397 }
[email protected]ff007e162009-05-23 09:13:15398 out.status_line = response->headers->GetStatusLine();
399
[email protected]80a09a82012-11-16 17:40:06400 EXPECT_EQ("127.0.0.1", response->socket_address.host());
401 EXPECT_EQ(80, response->socket_address.port());
[email protected]6d81b482011-02-22 19:47:19402
ttuttled9dbc652015-09-29 20:00:59403 bool got_endpoint =
bnc691fda62016-08-12 00:43:16404 trans.GetRemoteEndpoint(&out.remote_endpoint_after_start);
ttuttled9dbc652015-09-29 20:00:59405 EXPECT_EQ(got_endpoint,
406 out.remote_endpoint_after_start.address().size() > 0);
407
bnc691fda62016-08-12 00:43:16408 rv = ReadTransaction(&trans, &out.response_data);
robpercival214763f2016-07-01 23:27:01409 EXPECT_THAT(rv, IsOk());
[email protected]b2fcd0e2010-12-01 15:19:40410
mmenke43758e62015-05-04 21:09:46411 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40412 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:39413 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00414 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
415 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:39416 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00417 entries, pos, NetLogEventType::HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
418 NetLogEventPhase::NONE);
[email protected]ff007e162009-05-23 09:13:15419
[email protected]f3da152d2012-06-02 01:00:57420 std::string line;
421 EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
422 EXPECT_EQ("GET / HTTP/1.1\r\n", line);
423
[email protected]79e1fd62013-06-20 06:50:04424 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:16425 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:04426 std::string value;
427 EXPECT_TRUE(request_headers.GetHeader("Host", &value));
bncce36dca22015-04-21 22:11:23428 EXPECT_EQ("www.example.org", value);
[email protected]79e1fd62013-06-20 06:50:04429 EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
430 EXPECT_EQ("keep-alive", value);
431
432 std::string response_headers;
433 EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
bncce36dca22015-04-21 22:11:23434 EXPECT_EQ("['Host: www.example.org','Connection: keep-alive']",
[email protected]79e1fd62013-06-20 06:50:04435 response_headers);
[email protected]3deb9a52010-11-11 00:24:40436
bnc691fda62016-08-12 00:43:16437 out.total_received_bytes = trans.GetTotalReceivedBytes();
sclittlefb249892015-09-10 21:33:22438 // The total number of sent bytes should not have changed.
bnc691fda62016-08-12 00:43:16439 EXPECT_EQ(out.total_sent_bytes, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:22440
bnc691fda62016-08-12 00:43:16441 trans.GetConnectionAttempts(&out.connection_attempts);
[email protected]aecfbf22008-10-16 02:02:47442 return out;
[email protected]ff007e162009-05-23 09:13:15443 }
initial.commit586acc5fe2008-07-26 22:42:52444
Ryan Sleevib8d7ea02018-05-07 20:01:01445 SimpleGetHelperResult SimpleGetHelper(base::span<const MockRead> data_reads) {
sclittlefb249892015-09-10 21:33:22446 MockWrite data_writes[] = {
447 MockWrite("GET / HTTP/1.1\r\n"
448 "Host: www.example.org\r\n"
449 "Connection: keep-alive\r\n\r\n"),
450 };
[email protected]5a60c8b2011-10-19 20:14:29451
Ryan Sleevib8d7ea02018-05-07 20:01:01452 StaticSocketDataProvider reads(data_reads, data_writes);
sclittlefb249892015-09-10 21:33:22453 StaticSocketDataProvider* data[] = {&reads};
Ryan Sleevib8d7ea02018-05-07 20:01:01454 SimpleGetHelperResult out = SimpleGetHelperForData(data);
sclittlefb249892015-09-10 21:33:22455
Ryan Sleevib8d7ea02018-05-07 20:01:01456 EXPECT_EQ(CountWriteBytes(data_writes), out.total_sent_bytes);
sclittlefb249892015-09-10 21:33:22457 return out;
[email protected]b8015c42013-12-24 15:18:19458 }
459
bnc032658ba2016-09-26 18:17:15460 void AddSSLSocketData() {
461 ssl_.next_proto = kProtoHTTP2;
Ryan Sleevi4f832092017-11-21 23:25:49462 ssl_.ssl_info.cert =
463 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
464 ASSERT_TRUE(ssl_.ssl_info.cert);
bnc032658ba2016-09-26 18:17:15465 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_);
466 }
467
[email protected]ff007e162009-05-23 09:13:15468 void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
469 int expected_status);
initial.commit586acc5fe2008-07-26 22:42:52470
[email protected]ff007e162009-05-23 09:13:15471 void ConnectStatusHelper(const MockRead& status);
[email protected]bb88e1d32013-05-03 23:11:07472
[email protected]bb88e1d32013-05-03 23:11:07473 void CheckErrorIsPassedBack(int error, IoMode mode);
474
[email protected]4bd46222013-05-14 19:32:23475 SpdyTestUtil spdy_util_;
[email protected]bb88e1d32013-05-03 23:11:07476 SpdySessionDependencies session_deps_;
bnc032658ba2016-09-26 18:17:15477 SSLSocketDataProvider ssl_;
[email protected]483fa202013-05-14 01:07:03478
479 // Original socket limits. Some tests set these. Safest to always restore
480 // them once each test has been run.
481 int old_max_group_sockets_;
482 int old_max_pool_sockets_;
[email protected]ff007e162009-05-23 09:13:15483};
[email protected]231d5a32008-09-13 00:45:27484
[email protected]448d4ca52012-03-04 04:12:23485namespace {
486
ryansturm49a8cb12016-06-15 16:51:09487class BeforeHeadersSentHandler {
[email protected]597a1ab2014-06-26 08:12:27488 public:
ryansturm49a8cb12016-06-15 16:51:09489 BeforeHeadersSentHandler()
490 : observed_before_headers_sent_with_proxy_(false),
491 observed_before_headers_sent_(false) {}
[email protected]597a1ab2014-06-26 08:12:27492
ryansturm49a8cb12016-06-15 16:51:09493 void OnBeforeHeadersSent(const ProxyInfo& proxy_info,
494 HttpRequestHeaders* request_headers) {
495 observed_before_headers_sent_ = true;
496 if (!proxy_info.is_http() && !proxy_info.is_https() &&
497 !proxy_info.is_quic()) {
498 return;
499 }
500 observed_before_headers_sent_with_proxy_ = true;
[email protected]597a1ab2014-06-26 08:12:27501 observed_proxy_server_uri_ = proxy_info.proxy_server().ToURI();
502 }
503
ryansturm49a8cb12016-06-15 16:51:09504 bool observed_before_headers_sent_with_proxy() const {
505 return observed_before_headers_sent_with_proxy_;
506 }
507
508 bool observed_before_headers_sent() const {
509 return observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27510 }
511
512 std::string observed_proxy_server_uri() const {
513 return observed_proxy_server_uri_;
514 }
515
516 private:
ryansturm49a8cb12016-06-15 16:51:09517 bool observed_before_headers_sent_with_proxy_;
518 bool observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27519 std::string observed_proxy_server_uri_;
520
ryansturm49a8cb12016-06-15 16:51:09521 DISALLOW_COPY_AND_ASSIGN(BeforeHeadersSentHandler);
[email protected]597a1ab2014-06-26 08:12:27522};
523
[email protected]15a5ccf82008-10-23 19:57:43524// Fill |str| with a long header list that consumes >= |size| bytes.
525void FillLargeHeadersString(std::string* str, int size) {
thestig9d3bb0c2015-01-24 00:49:51526 const char row[] =
[email protected]4ddaf2502008-10-23 18:26:19527 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
528 const int sizeof_row = strlen(row);
529 const int num_rows = static_cast<int>(
530 ceil(static_cast<float>(size) / sizeof_row));
531 const int sizeof_data = num_rows * sizeof_row;
532 DCHECK(sizeof_data >= size);
[email protected]15a5ccf82008-10-23 19:57:43533 str->reserve(sizeof_data);
[email protected]372d34a2008-11-05 21:30:51534
[email protected]4ddaf2502008-10-23 18:26:19535 for (int i = 0; i < num_rows; ++i)
[email protected]15a5ccf82008-10-23 19:57:43536 str->append(row, sizeof_row);
[email protected]4ddaf2502008-10-23 18:26:19537}
538
thakis84dff942015-07-28 20:47:38539#if defined(NTLM_PORTABLE)
Zentaro Kavanagh6ccee512017-09-28 18:34:09540uint64_t MockGetMSTime() {
541 // Tue, 23 May 2017 20:13:07 +0000
542 return 131400439870000000;
543}
544
[email protected]385a4672009-03-11 22:21:29545// Alternative functions that eliminate randomness and dependency on the local
546// host name so that the generated NTLM messages are reproducible.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:37547void MockGenerateRandom(uint8_t* output, size_t n) {
548 // This is set to 0xaa because the client challenge for testing in
549 // [MS-NLMP] Section 4.2.1 is 8 bytes of 0xaa.
550 memset(output, 0xaa, n);
[email protected]385a4672009-03-11 22:21:29551}
552
[email protected]fe2bc6a2009-03-23 16:52:20553std::string MockGetHostName() {
Zentaro Kavanagh5b27a6e22017-09-25 23:00:37554 return ntlm::test::kHostnameAscii;
[email protected]385a4672009-03-11 22:21:29555}
thakis84dff942015-07-28 20:47:38556#endif // defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29557
[email protected]e60e47a2010-07-14 03:37:18558template<typename ParentPool>
559class CaptureGroupNameSocketPool : public ParentPool {
[email protected]04e5be32009-06-26 20:00:31560 public:
[email protected]9e1bdd32011-02-03 21:48:34561 CaptureGroupNameSocketPool(HostResolver* host_resolver,
562 CertVerifier* cert_verifier);
[email protected]e60e47a2010-07-14 03:37:18563
[email protected]d80a4322009-08-14 07:07:49564 const std::string last_group_name_received() const {
565 return last_group_name_;
566 }
567
Tarun Bansal162eabe52018-01-20 01:16:39568 bool socket_requested() const { return socket_requested_; }
569
dmichaeld6e570d2014-12-18 22:30:57570 int RequestSocket(const std::string& group_name,
571 const void* socket_params,
572 RequestPriority priority,
Paul Jensen8d6f87ec2018-01-13 00:46:54573 const SocketTag& socket_tag,
mmenked3641e12016-01-28 16:06:15574 ClientSocketPool::RespectLimits respect_limits,
dmichaeld6e570d2014-12-18 22:30:57575 ClientSocketHandle* handle,
Bence Béky5a8662b2018-07-03 13:04:03576 CompletionOnceCallback callback,
tfarina42834112016-09-22 13:38:20577 const NetLogWithSource& net_log) override {
[email protected]04e5be32009-06-26 20:00:31578 last_group_name_ = group_name;
Tarun Bansal162eabe52018-01-20 01:16:39579 socket_requested_ = true;
[email protected]04e5be32009-06-26 20:00:31580 return ERR_IO_PENDING;
581 }
dmichaeld6e570d2014-12-18 22:30:57582 void CancelRequest(const std::string& group_name,
583 ClientSocketHandle* handle) override {}
584 void ReleaseSocket(const std::string& group_name,
danakj1fd259a02016-04-16 03:17:09585 std::unique_ptr<StreamSocket> socket,
dmichaeld6e570d2014-12-18 22:30:57586 int id) override {}
587 void CloseIdleSockets() override {}
xunjieli92feb332017-03-03 17:19:23588 void CloseIdleSocketsInGroup(const std::string& group_name) override {}
dmichaeld6e570d2014-12-18 22:30:57589 int IdleSocketCount() const override { return 0; }
590 int IdleSocketCountInGroup(const std::string& group_name) const override {
[email protected]04e5be32009-06-26 20:00:31591 return 0;
592 }
dmichaeld6e570d2014-12-18 22:30:57593 LoadState GetLoadState(const std::string& group_name,
594 const ClientSocketHandle* handle) const override {
[email protected]04e5be32009-06-26 20:00:31595 return LOAD_STATE_IDLE;
596 }
dmichaeld6e570d2014-12-18 22:30:57597 base::TimeDelta ConnectionTimeout() const override {
[email protected]a796bcec2010-03-22 17:17:26598 return base::TimeDelta();
599 }
[email protected]d80a4322009-08-14 07:07:49600
601 private:
[email protected]04e5be32009-06-26 20:00:31602 std::string last_group_name_;
Tarun Bansal162eabe52018-01-20 01:16:39603 bool socket_requested_ = false;
[email protected]04e5be32009-06-26 20:00:31604};
605
[email protected]ab739042011-04-07 15:22:28606typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
607CaptureGroupNameTransportSocketPool;
[email protected]e772db3f2010-07-12 18:11:13608typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
609CaptureGroupNameHttpProxySocketPool;
[email protected]2d731a32010-04-29 01:04:06610typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
[email protected]2227c692010-05-04 15:36:11611CaptureGroupNameSOCKSSocketPool;
[email protected]e60e47a2010-07-14 03:37:18612typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
613CaptureGroupNameSSLSocketPool;
614
rkaplowd90695c2015-03-25 22:12:41615template <typename ParentPool>
[email protected]e60e47a2010-07-14 03:37:18616CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34617 HostResolver* host_resolver,
618 CertVerifier* /* cert_verifier */)
tbansal7b403bcc2016-04-13 22:33:21619 : ParentPool(0, 0, host_resolver, NULL, NULL, NULL) {}
[email protected]e60e47a2010-07-14 03:37:18620
hashimoto0d3e4fb2015-01-09 05:02:50621template <>
[email protected]2df19bb2010-08-25 20:13:46622CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21623 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34624 CertVerifier* /* cert_verifier */)
tbansal16196a1e2017-06-09 01:50:09625 : HttpProxyClientSocketPool(0, 0, NULL, NULL, NULL, NULL) {}
[email protected]2df19bb2010-08-25 20:13:46626
[email protected]007b3f82013-04-09 08:46:45627template <>
[email protected]e60e47a2010-07-14 03:37:18628CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21629 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34630 CertVerifier* cert_verifier)
[email protected]007b3f82013-04-09 08:46:45631 : SSLClientSocketPool(0,
632 0,
[email protected]007b3f82013-04-09 08:46:45633 cert_verifier,
634 NULL,
635 NULL,
[email protected]284303b62013-11-28 15:11:54636 NULL,
eranm6571b2b2014-12-03 15:53:23637 NULL,
[email protected]007b3f82013-04-09 08:46:45638 std::string(),
639 NULL,
640 NULL,
641 NULL,
642 NULL,
643 NULL,
[email protected]8e458552014-08-05 00:02:15644 NULL) {
645}
[email protected]2227c692010-05-04 15:36:11646
[email protected]231d5a32008-09-13 00:45:27647//-----------------------------------------------------------------------------
648
[email protected]79cb5c12011-09-12 13:12:04649// Helper functions for validating that AuthChallengeInfo's are correctly
650// configured for common cases.
651bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
652 if (!auth_challenge)
653 return false;
654 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43655 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04656 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19657 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04658 return true;
659}
660
661bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
662 if (!auth_challenge)
663 return false;
664 EXPECT_TRUE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43665 EXPECT_EQ("http://myproxy:70", auth_challenge->challenger.Serialize());
666 EXPECT_EQ("MyRealm1", auth_challenge->realm);
667 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
668 return true;
669}
670
671bool CheckBasicSecureProxyAuth(const AuthChallengeInfo* auth_challenge) {
672 if (!auth_challenge)
673 return false;
674 EXPECT_TRUE(auth_challenge->is_proxy);
675 EXPECT_EQ("https://myproxy:70", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04676 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19677 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04678 return true;
679}
680
681bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
682 if (!auth_challenge)
683 return false;
684 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43685 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04686 EXPECT_EQ("digestive", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19687 EXPECT_EQ(kDigestAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04688 return true;
689}
690
thakis84dff942015-07-28 20:47:38691#if defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04692bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
693 if (!auth_challenge)
694 return false;
695 EXPECT_FALSE(auth_challenge->is_proxy);
Zentaro Kavanagh1890a3d2018-01-29 19:52:55696 EXPECT_EQ("https://server", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04697 EXPECT_EQ(std::string(), auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19698 EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04699 return true;
700}
David Benjamin5cb91132018-04-06 05:54:49701
702bool CheckNTLMProxyAuth(const AuthChallengeInfo* auth_challenge) {
703 if (!auth_challenge)
704 return false;
705 EXPECT_TRUE(auth_challenge->is_proxy);
706 EXPECT_EQ("http://server", auth_challenge->challenger.Serialize());
707 EXPECT_EQ(std::string(), auth_challenge->realm);
708 EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
709 return true;
710}
thakis84dff942015-07-28 20:47:38711#endif // defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04712
[email protected]448d4ca52012-03-04 04:12:23713} // namespace
714
bncd16676a2016-07-20 16:23:01715TEST_F(HttpNetworkTransactionTest, Basic) {
danakj1fd259a02016-04-16 03:17:09716 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16717 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]231d5a32008-09-13 00:45:27718}
719
bncd16676a2016-07-20 16:23:01720TEST_F(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27721 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35722 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
723 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06724 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27725 };
Ryan Sleevib8d7ea02018-05-07 20:01:01726 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01727 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27728 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
729 EXPECT_EQ("hello world", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01730 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22731 EXPECT_EQ(reads_size, out.total_received_bytes);
ttuttle1f2d7e92015-04-28 16:17:47732 EXPECT_EQ(0u, out.connection_attempts.size());
ttuttled9dbc652015-09-29 20:00:59733
734 EXPECT_FALSE(out.remote_endpoint_after_start.address().empty());
[email protected]231d5a32008-09-13 00:45:27735}
736
737// Response with no status line.
bncd16676a2016-07-20 16:23:01738TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27739 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35740 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06741 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27742 };
Ryan Sleevib8d7ea02018-05-07 20:01:01743 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41744 EXPECT_THAT(out.rv, IsOk());
745 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
746 EXPECT_EQ("hello world", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01747 int64_t reads_size = CountReadBytes(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41748 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27749}
750
mmenkea7da6da2016-09-01 21:56:52751// Response with no status line, and a weird port. Should fail by default.
752TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPort) {
753 MockRead data_reads[] = {
754 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
755 };
756
Ryan Sleevib8d7ea02018-05-07 20:01:01757 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
mmenkea7da6da2016-09-01 21:56:52758 session_deps_.socket_factory->AddSocketDataProvider(&data);
759
760 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
761
krasinc06a72a2016-12-21 03:42:46762 HttpRequestInfo request;
bnc87dcefc2017-05-25 12:47:58763 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:19764 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenkea7da6da2016-09-01 21:56:52765
mmenkea7da6da2016-09-01 21:56:52766 request.method = "GET";
767 request.url = GURL("http://www.example.com:2000/");
Ramin Halavatib5e433e62018-02-07 07:41:10768 request.traffic_annotation =
769 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
770
mmenkea7da6da2016-09-01 21:56:52771 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20772 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52773 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_INVALID_HTTP_RESPONSE));
774}
775
Shivani Sharmafdcaefd2017-11-02 00:12:26776// Tests that request info can be destroyed after the headers phase is complete.
777TEST_F(HttpNetworkTransactionTest, SimpleGETNoReadDestroyRequestInfo) {
778 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
779 auto trans =
780 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
781
782 MockRead data_reads[] = {
783 MockRead("HTTP/1.0 200 OK\r\n"), MockRead("Connection: keep-alive\r\n"),
784 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, 0),
785 };
Ryan Sleevib8d7ea02018-05-07 20:01:01786 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
Shivani Sharmafdcaefd2017-11-02 00:12:26787 session_deps_.socket_factory->AddSocketDataProvider(&data);
788
789 TestCompletionCallback callback;
790
791 {
792 auto request = std::make_unique<HttpRequestInfo>();
793 request->method = "GET";
794 request->url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:10795 request->traffic_annotation =
796 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Shivani Sharmafdcaefd2017-11-02 00:12:26797
798 int rv =
799 trans->Start(request.get(), callback.callback(), NetLogWithSource());
800
801 EXPECT_THAT(callback.GetResult(rv), IsOk());
802 } // Let request info be destroyed.
803
804 trans.reset();
805}
806
mmenkea7da6da2016-09-01 21:56:52807// Response with no status line, and a weird port. Option to allow weird ports
808// enabled.
809TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPortAllowed) {
810 MockRead data_reads[] = {
811 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
812 };
813
Ryan Sleevib8d7ea02018-05-07 20:01:01814 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
mmenkea7da6da2016-09-01 21:56:52815 session_deps_.socket_factory->AddSocketDataProvider(&data);
816 session_deps_.http_09_on_non_default_ports_enabled = true;
817 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
818
krasinc06a72a2016-12-21 03:42:46819 HttpRequestInfo request;
bnc87dcefc2017-05-25 12:47:58820 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:19821 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenkea7da6da2016-09-01 21:56:52822
mmenkea7da6da2016-09-01 21:56:52823 request.method = "GET";
824 request.url = GURL("http://www.example.com:2000/");
Ramin Halavatib5e433e62018-02-07 07:41:10825 request.traffic_annotation =
826 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
827
mmenkea7da6da2016-09-01 21:56:52828 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20829 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52830 EXPECT_THAT(callback.GetResult(rv), IsOk());
831
832 const HttpResponseInfo* info = trans->GetResponseInfo();
833 ASSERT_TRUE(info->headers);
834 EXPECT_EQ("HTTP/0.9 200 OK", info->headers->GetStatusLine());
835
836 // Don't bother to read the body - that's verified elsewhere, important thing
837 // is that the option to allow HTTP/0.9 on non-default ports is respected.
838}
839
[email protected]231d5a32008-09-13 00:45:27840// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01841TEST_F(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27842 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35843 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06844 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27845 };
Ryan Sleevib8d7ea02018-05-07 20:01:01846 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01847 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27848 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
849 EXPECT_EQ("DATA", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01850 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22851 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27852}
853
854// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01855TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27856 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35857 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06858 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27859 };
Ryan Sleevib8d7ea02018-05-07 20:01:01860 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01861 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27862 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
863 EXPECT_EQ("DATA", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01864 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22865 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27866}
867
868// Beyond 4 bytes of slop and it should fail to find a status line.
bncd16676a2016-07-20 16:23:01869TEST_F(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27870 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35871 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06872 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27873 };
Ryan Sleevib8d7ea02018-05-07 20:01:01874 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41875 EXPECT_THAT(out.rv, IsOk());
876 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
877 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01878 int64_t reads_size = CountReadBytes(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41879 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27880}
881
882// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
bncd16676a2016-07-20 16:23:01883TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27884 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35885 MockRead("\n"),
886 MockRead("\n"),
887 MockRead("Q"),
888 MockRead("J"),
889 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06890 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27891 };
Ryan Sleevib8d7ea02018-05-07 20:01:01892 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01893 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27894 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
895 EXPECT_EQ("DATA", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01896 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22897 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27898}
899
900// Close the connection before enough bytes to have a status line.
bncd16676a2016-07-20 16:23:01901TEST_F(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:27902 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35903 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:06904 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27905 };
Ryan Sleevib8d7ea02018-05-07 20:01:01906 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41907 EXPECT_THAT(out.rv, IsOk());
908 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
909 EXPECT_EQ("HTT", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01910 int64_t reads_size = CountReadBytes(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41911 EXPECT_EQ(reads_size, out.total_received_bytes);
initial.commit586acc5fe2008-07-26 22:42:52912}
913
[email protected]f9d44aa2008-09-23 23:57:17914// Simulate a 204 response, lacking a Content-Length header, sent over a
915// persistent connection. The response should still terminate since a 204
916// cannot have a response body.
bncd16676a2016-07-20 16:23:01917TEST_F(HttpNetworkTransactionTest, StopsReading204) {
[email protected]b8015c42013-12-24 15:18:19918 char junk[] = "junk";
[email protected]f9d44aa2008-09-23 23:57:17919 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35920 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
[email protected]b8015c42013-12-24 15:18:19921 MockRead(junk), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:06922 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:17923 };
Ryan Sleevib8d7ea02018-05-07 20:01:01924 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01925 EXPECT_THAT(out.rv, IsOk());
[email protected]f9d44aa2008-09-23 23:57:17926 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
927 EXPECT_EQ("", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01928 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22929 int64_t response_size = reads_size - strlen(junk);
930 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]f9d44aa2008-09-23 23:57:17931}
932
[email protected]0877e3d2009-10-17 22:29:57933// A simple request using chunked encoding with some extra data after.
bncd16676a2016-07-20 16:23:01934TEST_F(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]b8015c42013-12-24 15:18:19935 std::string final_chunk = "0\r\n\r\n";
936 std::string extra_data = "HTTP/1.1 200 OK\r\n";
937 std::string last_read = final_chunk + extra_data;
[email protected]0877e3d2009-10-17 22:29:57938 MockRead data_reads[] = {
939 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
940 MockRead("5\r\nHello\r\n"),
941 MockRead("1\r\n"),
942 MockRead(" \r\n"),
943 MockRead("5\r\nworld\r\n"),
[email protected]b8015c42013-12-24 15:18:19944 MockRead(last_read.data()),
[email protected]8ddf8322012-02-23 18:08:06945 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:57946 };
Ryan Sleevib8d7ea02018-05-07 20:01:01947 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01948 EXPECT_THAT(out.rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:57949 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
950 EXPECT_EQ("Hello world", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01951 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22952 int64_t response_size = reads_size - extra_data.size();
953 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]0877e3d2009-10-17 22:29:57954}
955
[email protected]9fe44f52010-09-23 18:36:00956// Next tests deal with http://crbug.com/56344.
957
bncd16676a2016-07-20 16:23:01958TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00959 MultipleContentLengthHeadersNoTransferEncoding) {
960 MockRead data_reads[] = {
961 MockRead("HTTP/1.1 200 OK\r\n"),
962 MockRead("Content-Length: 10\r\n"),
963 MockRead("Content-Length: 5\r\n\r\n"),
964 };
Ryan Sleevib8d7ea02018-05-07 20:01:01965 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01966 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]9fe44f52010-09-23 18:36:00967}
968
bncd16676a2016-07-20 16:23:01969TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04970 DuplicateContentLengthHeadersNoTransferEncoding) {
971 MockRead data_reads[] = {
972 MockRead("HTTP/1.1 200 OK\r\n"),
973 MockRead("Content-Length: 5\r\n"),
974 MockRead("Content-Length: 5\r\n\r\n"),
975 MockRead("Hello"),
976 };
Ryan Sleevib8d7ea02018-05-07 20:01:01977 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01978 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:04979 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
980 EXPECT_EQ("Hello", out.response_data);
981}
982
bncd16676a2016-07-20 16:23:01983TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04984 ComplexContentLengthHeadersNoTransferEncoding) {
985 // More than 2 dupes.
986 {
987 MockRead data_reads[] = {
988 MockRead("HTTP/1.1 200 OK\r\n"),
989 MockRead("Content-Length: 5\r\n"),
990 MockRead("Content-Length: 5\r\n"),
991 MockRead("Content-Length: 5\r\n\r\n"),
992 MockRead("Hello"),
993 };
Ryan Sleevib8d7ea02018-05-07 20:01:01994 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01995 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:04996 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
997 EXPECT_EQ("Hello", out.response_data);
998 }
999 // HTTP/1.0
1000 {
1001 MockRead data_reads[] = {
1002 MockRead("HTTP/1.0 200 OK\r\n"),
1003 MockRead("Content-Length: 5\r\n"),
1004 MockRead("Content-Length: 5\r\n"),
1005 MockRead("Content-Length: 5\r\n\r\n"),
1006 MockRead("Hello"),
1007 };
Ryan Sleevib8d7ea02018-05-07 20:01:011008 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011009 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041010 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
1011 EXPECT_EQ("Hello", out.response_data);
1012 }
1013 // 2 dupes and one mismatched.
1014 {
1015 MockRead data_reads[] = {
1016 MockRead("HTTP/1.1 200 OK\r\n"),
1017 MockRead("Content-Length: 10\r\n"),
1018 MockRead("Content-Length: 10\r\n"),
1019 MockRead("Content-Length: 5\r\n\r\n"),
1020 };
Ryan Sleevib8d7ea02018-05-07 20:01:011021 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011022 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]44b52042010-10-29 22:48:041023 }
1024}
1025
bncd16676a2016-07-20 16:23:011026TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001027 MultipleContentLengthHeadersTransferEncoding) {
1028 MockRead data_reads[] = {
1029 MockRead("HTTP/1.1 200 OK\r\n"),
1030 MockRead("Content-Length: 666\r\n"),
1031 MockRead("Content-Length: 1337\r\n"),
1032 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
1033 MockRead("5\r\nHello\r\n"),
1034 MockRead("1\r\n"),
1035 MockRead(" \r\n"),
1036 MockRead("5\r\nworld\r\n"),
1037 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:061038 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:001039 };
Ryan Sleevib8d7ea02018-05-07 20:01:011040 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011041 EXPECT_THAT(out.rv, IsOk());
[email protected]9fe44f52010-09-23 18:36:001042 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1043 EXPECT_EQ("Hello world", out.response_data);
1044}
1045
[email protected]1628fe92011-10-04 23:04:551046// Next tests deal with http://crbug.com/98895.
1047
1048// Checks that a single Content-Disposition header results in no error.
bncd16676a2016-07-20 16:23:011049TEST_F(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:551050 MockRead data_reads[] = {
1051 MockRead("HTTP/1.1 200 OK\r\n"),
1052 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
1053 MockRead("Content-Length: 5\r\n\r\n"),
1054 MockRead("Hello"),
1055 };
Ryan Sleevib8d7ea02018-05-07 20:01:011056 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011057 EXPECT_THAT(out.rv, IsOk());
[email protected]1628fe92011-10-04 23:04:551058 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1059 EXPECT_EQ("Hello", out.response_data);
1060}
1061
[email protected]54a9c6e52012-03-21 20:10:591062// Checks that two identical Content-Disposition headers result in no error.
bncd16676a2016-07-20 16:23:011063TEST_F(HttpNetworkTransactionTest, TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551064 MockRead data_reads[] = {
1065 MockRead("HTTP/1.1 200 OK\r\n"),
1066 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1067 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1068 MockRead("Content-Length: 5\r\n\r\n"),
1069 MockRead("Hello"),
1070 };
Ryan Sleevib8d7ea02018-05-07 20:01:011071 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011072 EXPECT_THAT(out.rv, IsOk());
[email protected]54a9c6e52012-03-21 20:10:591073 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1074 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:551075}
1076
1077// Checks that two distinct Content-Disposition headers result in an error.
bncd16676a2016-07-20 16:23:011078TEST_F(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551079 MockRead data_reads[] = {
1080 MockRead("HTTP/1.1 200 OK\r\n"),
1081 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1082 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
1083 MockRead("Content-Length: 5\r\n\r\n"),
1084 MockRead("Hello"),
1085 };
Ryan Sleevib8d7ea02018-05-07 20:01:011086 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011087 EXPECT_THAT(out.rv,
1088 IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION));
[email protected]1628fe92011-10-04 23:04:551089}
1090
[email protected]54a9c6e52012-03-21 20:10:591091// Checks that two identical Location headers result in no error.
1092// Also tests Location header behavior.
bncd16676a2016-07-20 16:23:011093TEST_F(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551094 MockRead data_reads[] = {
1095 MockRead("HTTP/1.1 302 Redirect\r\n"),
1096 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:591097 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:551098 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061099 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551100 };
1101
1102 HttpRequestInfo request;
1103 request.method = "GET";
1104 request.url = GURL("http://redirect.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101105 request.traffic_annotation =
1106 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1628fe92011-10-04 23:04:551107
danakj1fd259a02016-04-16 03:17:091108 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161109 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1628fe92011-10-04 23:04:551110
Ryan Sleevib8d7ea02018-05-07 20:01:011111 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071112 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:551113
[email protected]49639fa2011-12-20 23:22:411114 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:551115
tfarina42834112016-09-22 13:38:201116 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011117 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1628fe92011-10-04 23:04:551118
robpercival214763f2016-07-01 23:27:011119 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]1628fe92011-10-04 23:04:551120
bnc691fda62016-08-12 00:43:161121 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521122 ASSERT_TRUE(response);
1123 ASSERT_TRUE(response->headers);
[email protected]1628fe92011-10-04 23:04:551124 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
1125 std::string url;
1126 EXPECT_TRUE(response->headers->IsRedirect(&url));
1127 EXPECT_EQ("http://good.com/", url);
tbansal2ecbbc72016-10-06 17:15:471128 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]1628fe92011-10-04 23:04:551129}
1130
[email protected]1628fe92011-10-04 23:04:551131// Checks that two distinct Location headers result in an error.
bncd16676a2016-07-20 16:23:011132TEST_F(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551133 MockRead data_reads[] = {
1134 MockRead("HTTP/1.1 302 Redirect\r\n"),
1135 MockRead("Location: http://good.com/\r\n"),
1136 MockRead("Location: http://evil.com/\r\n"),
1137 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061138 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551139 };
Ryan Sleevib8d7ea02018-05-07 20:01:011140 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011141 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION));
[email protected]1628fe92011-10-04 23:04:551142}
1143
[email protected]ef0faf2e72009-03-05 23:27:231144// Do a request using the HEAD method. Verify that we don't try to read the
1145// message body (since HEAD has none).
bncd16676a2016-07-20 16:23:011146TEST_F(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:421147 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:231148 request.method = "HEAD";
bncce36dca22015-04-21 22:11:231149 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:101150 request.traffic_annotation =
1151 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ef0faf2e72009-03-05 23:27:231152
danakj1fd259a02016-04-16 03:17:091153 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161154 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:091155 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:161156 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:091157 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
1158 base::Unretained(&headers_handler)));
[email protected]cb9bf6ca2011-01-28 13:15:271159
[email protected]ef0faf2e72009-03-05 23:27:231160 MockWrite data_writes1[] = {
csharrisonf473dd192015-08-18 13:54:131161 MockWrite("HEAD / HTTP/1.1\r\n"
1162 "Host: www.example.org\r\n"
1163 "Connection: keep-alive\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231164 };
1165 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:231166 MockRead("HTTP/1.1 404 Not Found\r\n"), MockRead("Server: Blah\r\n"),
1167 MockRead("Content-Length: 1234\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231168
mmenked39192ee2015-12-09 00:57:231169 // No response body because the test stops reading here.
1170 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]ef0faf2e72009-03-05 23:27:231171 };
1172
Ryan Sleevib8d7ea02018-05-07 20:01:011173 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:071174 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:231175
[email protected]49639fa2011-12-20 23:22:411176 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:231177
tfarina42834112016-09-22 13:38:201178 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011179 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ef0faf2e72009-03-05 23:27:231180
1181 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:011182 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231183
bnc691fda62016-08-12 00:43:161184 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521185 ASSERT_TRUE(response);
[email protected]ef0faf2e72009-03-05 23:27:231186
1187 // Check that the headers got parsed.
wezca1070932016-05-26 20:30:521188 EXPECT_TRUE(response->headers);
[email protected]ef0faf2e72009-03-05 23:27:231189 EXPECT_EQ(1234, response->headers->GetContentLength());
1190 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471191 EXPECT_TRUE(response->proxy_server.is_direct());
ryansturm49a8cb12016-06-15 16:51:091192 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
1193 EXPECT_FALSE(headers_handler.observed_before_headers_sent_with_proxy());
[email protected]ef0faf2e72009-03-05 23:27:231194
1195 std::string server_header;
olli.raulaee489a52016-01-25 08:37:101196 size_t iter = 0;
[email protected]ef0faf2e72009-03-05 23:27:231197 bool has_server_header = response->headers->EnumerateHeader(
1198 &iter, "Server", &server_header);
1199 EXPECT_TRUE(has_server_header);
1200 EXPECT_EQ("Blah", server_header);
1201
1202 // Reading should give EOF right away, since there is no message body
1203 // (despite non-zero content-length).
1204 std::string response_data;
bnc691fda62016-08-12 00:43:161205 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011206 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231207 EXPECT_EQ("", response_data);
1208}
1209
bncd16676a2016-07-20 16:23:011210TEST_F(HttpNetworkTransactionTest, ReuseConnection) {
danakj1fd259a02016-04-16 03:17:091211 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:521212
1213 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351214 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1215 MockRead("hello"),
1216 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1217 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061218 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521219 };
Ryan Sleevib8d7ea02018-05-07 20:01:011220 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071221 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521222
[email protected]0b0bf032010-09-21 18:08:501223 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521224 "hello", "world"
1225 };
1226
1227 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:421228 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521229 request.method = "GET";
bncce36dca22015-04-21 22:11:231230 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:101231 request.traffic_annotation =
1232 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:521233
bnc691fda62016-08-12 00:43:161234 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271235
[email protected]49639fa2011-12-20 23:22:411236 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521237
tfarina42834112016-09-22 13:38:201238 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011239 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521240
1241 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011242 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521243
bnc691fda62016-08-12 00:43:161244 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521245 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521246
wezca1070932016-05-26 20:30:521247 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251248 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471249 EXPECT_TRUE(response->proxy_server.is_direct());
initial.commit586acc5fe2008-07-26 22:42:521250
1251 std::string response_data;
bnc691fda62016-08-12 00:43:161252 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011253 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251254 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521255 }
1256}
1257
bncd16676a2016-07-20 16:23:011258TEST_F(HttpNetworkTransactionTest, Ignores100) {
danakj1fd259a02016-04-16 03:17:091259 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:221260 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:191261 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:221262 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:271263
[email protected]1c773ea12009-04-28 19:58:421264 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521265 request.method = "POST";
1266 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271267 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:101268 request.traffic_annotation =
1269 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:521270
shivanishab9a143952016-09-19 17:23:411271 // Check the upload progress returned before initialization is correct.
1272 UploadProgress progress = request.upload_data_stream->GetUploadProgress();
1273 EXPECT_EQ(0u, progress.size());
1274 EXPECT_EQ(0u, progress.position());
1275
danakj1fd259a02016-04-16 03:17:091276 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161277 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271278
initial.commit586acc5fe2008-07-26 22:42:521279 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351280 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1281 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1282 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061283 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521284 };
Ryan Sleevib8d7ea02018-05-07 20:01:011285 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071286 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521287
[email protected]49639fa2011-12-20 23:22:411288 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521289
tfarina42834112016-09-22 13:38:201290 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011291 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521292
1293 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011294 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521295
bnc691fda62016-08-12 00:43:161296 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521297 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521298
wezca1070932016-05-26 20:30:521299 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251300 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521301
1302 std::string response_data;
bnc691fda62016-08-12 00:43:161303 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011304 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251305 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521306}
1307
[email protected]3a2d3662009-03-27 03:49:141308// This test is almost the same as Ignores100 above, but the response contains
1309// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571310// HTTP/1.1 and the two status headers are read in one read.
bncd16676a2016-07-20 16:23:011311TEST_F(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421312 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141313 request.method = "GET";
1314 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101315 request.traffic_annotation =
1316 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3a2d3662009-03-27 03:49:141317
danakj1fd259a02016-04-16 03:17:091318 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161319 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271320
[email protected]3a2d3662009-03-27 03:49:141321 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571322 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1323 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141324 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061325 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141326 };
Ryan Sleevib8d7ea02018-05-07 20:01:011327 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071328 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141329
[email protected]49639fa2011-12-20 23:22:411330 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141331
tfarina42834112016-09-22 13:38:201332 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011333 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3a2d3662009-03-27 03:49:141334
1335 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011336 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141337
bnc691fda62016-08-12 00:43:161338 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521339 ASSERT_TRUE(response);
[email protected]3a2d3662009-03-27 03:49:141340
wezca1070932016-05-26 20:30:521341 EXPECT_TRUE(response->headers);
[email protected]3a2d3662009-03-27 03:49:141342 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1343
1344 std::string response_data;
bnc691fda62016-08-12 00:43:161345 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011346 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141347 EXPECT_EQ("hello world", response_data);
1348}
1349
bncd16676a2016-07-20 16:23:011350TEST_F(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
zmo9528c9f42015-08-04 22:12:081351 HttpRequestInfo request;
1352 request.method = "POST";
1353 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101354 request.traffic_annotation =
1355 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
zmo9528c9f42015-08-04 22:12:081356
danakj1fd259a02016-04-16 03:17:091357 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161358 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zmo9528c9f42015-08-04 22:12:081359
1360 MockRead data_reads[] = {
1361 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1362 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381363 };
Ryan Sleevib8d7ea02018-05-07 20:01:011364 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
zmo9528c9f42015-08-04 22:12:081365 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381366
zmo9528c9f42015-08-04 22:12:081367 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381368
tfarina42834112016-09-22 13:38:201369 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011370 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381371
zmo9528c9f42015-08-04 22:12:081372 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011373 EXPECT_THAT(rv, IsOk());
[email protected]ee9410e72010-01-07 01:42:381374
zmo9528c9f42015-08-04 22:12:081375 std::string response_data;
bnc691fda62016-08-12 00:43:161376 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011377 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:081378 EXPECT_EQ("", response_data);
[email protected]ee9410e72010-01-07 01:42:381379}
1380
bncd16676a2016-07-20 16:23:011381TEST_F(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381382 HttpRequestInfo request;
1383 request.method = "POST";
1384 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101385 request.traffic_annotation =
1386 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ee9410e72010-01-07 01:42:381387
danakj1fd259a02016-04-16 03:17:091388 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161389 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271390
[email protected]ee9410e72010-01-07 01:42:381391 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061392 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381393 };
Ryan Sleevib8d7ea02018-05-07 20:01:011394 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071395 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381396
[email protected]49639fa2011-12-20 23:22:411397 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381398
tfarina42834112016-09-22 13:38:201399 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011400 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381401
1402 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011403 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]ee9410e72010-01-07 01:42:381404}
1405
[email protected]23e482282013-06-14 16:08:021406void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511407 const MockWrite* write_failure,
1408 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421409 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521410 request.method = "GET";
1411 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101412 request.traffic_annotation =
1413 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:521414
vishal.b62985ca92015-04-17 08:45:511415 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071416 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091417 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271418
[email protected]202965992011-12-07 23:04:511419 // Written data for successfully sending both requests.
1420 MockWrite data1_writes[] = {
1421 MockWrite("GET / HTTP/1.1\r\n"
1422 "Host: www.foo.com\r\n"
1423 "Connection: keep-alive\r\n\r\n"),
1424 MockWrite("GET / HTTP/1.1\r\n"
1425 "Host: www.foo.com\r\n"
1426 "Connection: keep-alive\r\n\r\n")
1427 };
1428
1429 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521430 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351431 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1432 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061433 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521434 };
[email protected]202965992011-12-07 23:04:511435
1436 if (write_failure) {
[email protected]a34f61ee2014-03-18 20:59:491437 ASSERT_FALSE(read_failure);
[email protected]202965992011-12-07 23:04:511438 data1_writes[1] = *write_failure;
1439 } else {
1440 ASSERT_TRUE(read_failure);
1441 data1_reads[2] = *read_failure;
1442 }
1443
Ryan Sleevib8d7ea02018-05-07 20:01:011444 StaticSocketDataProvider data1(data1_reads, data1_writes);
[email protected]bb88e1d32013-05-03 23:11:071445 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521446
1447 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351448 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1449 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061450 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521451 };
Ryan Sleevib8d7ea02018-05-07 20:01:011452 StaticSocketDataProvider data2(data2_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071453 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521454
thestig9d3bb0c2015-01-24 00:49:511455 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521456 "hello", "world"
1457 };
1458
mikecironef22f9812016-10-04 03:40:191459 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521460 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411461 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521462
bnc691fda62016-08-12 00:43:161463 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
initial.commit586acc5fe2008-07-26 22:42:521464
tfarina42834112016-09-22 13:38:201465 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011466 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521467
1468 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011469 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521470
[email protected]58e32bb2013-01-21 18:23:251471 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161472 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:251473 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1474 if (i == 0) {
1475 first_socket_log_id = load_timing_info.socket_log_id;
1476 } else {
1477 // The second request should be using a new socket.
1478 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1479 }
1480
bnc691fda62016-08-12 00:43:161481 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521482 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521483
wezca1070932016-05-26 20:30:521484 EXPECT_TRUE(response->headers);
tbansal2ecbbc72016-10-06 17:15:471485 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]3d2a59b2008-09-26 19:44:251486 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521487
1488 std::string response_data;
bnc691fda62016-08-12 00:43:161489 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011490 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251491 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521492 }
1493}
[email protected]3d2a59b2008-09-26 19:44:251494
[email protected]a34f61ee2014-03-18 20:59:491495void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1496 const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:101497 const MockRead* read_failure,
1498 bool use_spdy) {
[email protected]a34f61ee2014-03-18 20:59:491499 HttpRequestInfo request;
1500 request.method = "GET";
[email protected]09356c652014-03-25 15:36:101501 request.url = GURL("https://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101502 request.traffic_annotation =
1503 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]a34f61ee2014-03-18 20:59:491504
vishal.b62985ca92015-04-17 08:45:511505 TestNetLog net_log;
[email protected]a34f61ee2014-03-18 20:59:491506 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091507 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a34f61ee2014-03-18 20:59:491508
[email protected]09356c652014-03-25 15:36:101509 SSLSocketDataProvider ssl1(ASYNC, OK);
1510 SSLSocketDataProvider ssl2(ASYNC, OK);
1511 if (use_spdy) {
bnc3cf2a592016-08-11 14:48:361512 ssl1.next_proto = kProtoHTTP2;
1513 ssl2.next_proto = kProtoHTTP2;
[email protected]09356c652014-03-25 15:36:101514 }
1515 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1516 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]a34f61ee2014-03-18 20:59:491517
[email protected]09356c652014-03-25 15:36:101518 // SPDY versions of the request and response.
Ryan Hamilton0239aac2018-05-19 00:03:131519 spdy::SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
bnc38dcd392016-02-09 23:19:491520 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
Ryan Hamilton0239aac2018-05-19 00:03:131521 spdy::SpdySerializedFrame spdy_response(
bnc42331402016-07-25 13:36:151522 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:131523 spdy::SpdySerializedFrame spdy_data(
Bence Békyd74f4382018-02-20 18:26:191524 spdy_util_.ConstructSpdyDataFrame(1, "hello", true));
[email protected]a34f61ee2014-03-18 20:59:491525
[email protected]09356c652014-03-25 15:36:101526 // HTTP/1.1 versions of the request and response.
1527 const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1528 "Host: www.foo.com\r\n"
1529 "Connection: keep-alive\r\n\r\n";
1530 const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1531 const char kHttpData[] = "hello";
1532
1533 std::vector<MockRead> data1_reads;
1534 std::vector<MockWrite> data1_writes;
[email protected]a34f61ee2014-03-18 20:59:491535 if (write_failure) {
1536 ASSERT_FALSE(read_failure);
[email protected]09356c652014-03-25 15:36:101537 data1_writes.push_back(*write_failure);
1538 data1_reads.push_back(MockRead(ASYNC, OK));
[email protected]a34f61ee2014-03-18 20:59:491539 } else {
1540 ASSERT_TRUE(read_failure);
[email protected]09356c652014-03-25 15:36:101541 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411542 data1_writes.push_back(CreateMockWrite(spdy_request));
[email protected]09356c652014-03-25 15:36:101543 } else {
1544 data1_writes.push_back(MockWrite(kHttpRequest));
1545 }
1546 data1_reads.push_back(*read_failure);
[email protected]a34f61ee2014-03-18 20:59:491547 }
1548
Ryan Sleevib8d7ea02018-05-07 20:01:011549 StaticSocketDataProvider data1(data1_reads, data1_writes);
[email protected]a34f61ee2014-03-18 20:59:491550 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1551
[email protected]09356c652014-03-25 15:36:101552 std::vector<MockRead> data2_reads;
1553 std::vector<MockWrite> data2_writes;
1554
1555 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411556 data2_writes.push_back(CreateMockWrite(spdy_request, 0, ASYNC));
[email protected]09356c652014-03-25 15:36:101557
bncdf80d44fd2016-07-15 20:27:411558 data2_reads.push_back(CreateMockRead(spdy_response, 1, ASYNC));
1559 data2_reads.push_back(CreateMockRead(spdy_data, 2, ASYNC));
[email protected]09356c652014-03-25 15:36:101560 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1561 } else {
1562 data2_writes.push_back(
1563 MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1564
1565 data2_reads.push_back(
1566 MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1567 data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1568 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1569 }
Ryan Sleevib8d7ea02018-05-07 20:01:011570 SequencedSocketData data2(data2_reads, data2_writes);
[email protected]a34f61ee2014-03-18 20:59:491571 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1572
1573 // Preconnect a socket.
nharper8cdb0fb2016-04-22 21:34:591574 session->http_stream_factory()->PreconnectStreams(1, request);
[email protected]a34f61ee2014-03-18 20:59:491575 // Wait for the preconnect to complete.
1576 // TODO(davidben): Some way to wait for an idle socket count might be handy.
1577 base::RunLoop().RunUntilIdle();
[email protected]09356c652014-03-25 15:36:101578 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]a34f61ee2014-03-18 20:59:491579
1580 // Make the request.
1581 TestCompletionCallback callback;
1582
bnc691fda62016-08-12 00:43:161583 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a34f61ee2014-03-18 20:59:491584
tfarina42834112016-09-22 13:38:201585 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011586 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a34f61ee2014-03-18 20:59:491587
1588 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011589 EXPECT_THAT(rv, IsOk());
[email protected]a34f61ee2014-03-18 20:59:491590
1591 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161592 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]09356c652014-03-25 15:36:101593 TestLoadTimingNotReused(
1594 load_timing_info,
1595 CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]a34f61ee2014-03-18 20:59:491596
bnc691fda62016-08-12 00:43:161597 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521598 ASSERT_TRUE(response);
[email protected]a34f61ee2014-03-18 20:59:491599
wezca1070932016-05-26 20:30:521600 EXPECT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:021601 if (response->was_fetched_via_spdy) {
1602 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
1603 } else {
1604 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1605 }
[email protected]a34f61ee2014-03-18 20:59:491606
1607 std::string response_data;
bnc691fda62016-08-12 00:43:161608 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011609 EXPECT_THAT(rv, IsOk());
[email protected]09356c652014-03-25 15:36:101610 EXPECT_EQ(kHttpData, response_data);
[email protected]a34f61ee2014-03-18 20:59:491611}
1612
Biljith Jayan45a41722017-08-16 18:43:141613// Test that we do not retry indefinitely when a server sends an error like
1614// ERR_SPDY_PING_FAILED, ERR_SPDY_SERVER_REFUSED_STREAM,
1615// ERR_QUIC_HANDSHAKE_FAILED or ERR_QUIC_PROTOCOL_ERROR.
1616TEST_F(HttpNetworkTransactionTest, FiniteRetriesOnIOError) {
1617 HttpRequestInfo request;
1618 request.method = "GET";
1619 request.url = GURL("https://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101620 request.traffic_annotation =
1621 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Biljith Jayan45a41722017-08-16 18:43:141622
1623 // Check whether we give up after the third try.
1624
1625 // Construct an HTTP2 request and a "Go away" response.
Ryan Hamilton0239aac2018-05-19 00:03:131626 spdy::SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
Biljith Jayan45a41722017-08-16 18:43:141627 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
Ryan Hamilton0239aac2018-05-19 00:03:131628 spdy::SpdySerializedFrame spdy_response_go_away(
1629 spdy_util_.ConstructSpdyGoAway(0));
Ryan Sleevib8d7ea02018-05-07 20:01:011630 MockRead data_read1[] = {CreateMockRead(spdy_response_go_away)};
1631 MockWrite data_write[] = {CreateMockWrite(spdy_request, 0)};
Biljith Jayan45a41722017-08-16 18:43:141632
1633 // Three go away responses.
Ryan Sleevib8d7ea02018-05-07 20:01:011634 StaticSocketDataProvider data1(data_read1, data_write);
1635 StaticSocketDataProvider data2(data_read1, data_write);
1636 StaticSocketDataProvider data3(data_read1, data_write);
Biljith Jayan45a41722017-08-16 18:43:141637
1638 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1639 AddSSLSocketData();
1640 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1641 AddSSLSocketData();
1642 session_deps_.socket_factory->AddSocketDataProvider(&data3);
1643 AddSSLSocketData();
1644
1645 TestCompletionCallback callback;
1646 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1647 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1648
1649 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1650 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1651
1652 rv = callback.WaitForResult();
1653 EXPECT_THAT(rv, IsError(ERR_SPDY_SERVER_REFUSED_STREAM));
1654}
1655
1656TEST_F(HttpNetworkTransactionTest, RetryTwiceOnIOError) {
1657 HttpRequestInfo request;
1658 request.method = "GET";
1659 request.url = GURL("https://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101660 request.traffic_annotation =
1661 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Biljith Jayan45a41722017-08-16 18:43:141662
1663 // Check whether we try atleast thrice before giving up.
1664
1665 // Construct an HTTP2 request and a "Go away" response.
Ryan Hamilton0239aac2018-05-19 00:03:131666 spdy::SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
Biljith Jayan45a41722017-08-16 18:43:141667 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
Ryan Hamilton0239aac2018-05-19 00:03:131668 spdy::SpdySerializedFrame spdy_response_go_away(
1669 spdy_util_.ConstructSpdyGoAway(0));
Ryan Sleevib8d7ea02018-05-07 20:01:011670 MockRead data_read1[] = {CreateMockRead(spdy_response_go_away)};
1671 MockWrite data_write[] = {CreateMockWrite(spdy_request, 0)};
Biljith Jayan45a41722017-08-16 18:43:141672
1673 // Construct a non error HTTP2 response.
Ryan Hamilton0239aac2018-05-19 00:03:131674 spdy::SpdySerializedFrame spdy_response_no_error(
Biljith Jayan45a41722017-08-16 18:43:141675 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:131676 spdy::SpdySerializedFrame spdy_data(
1677 spdy_util_.ConstructSpdyDataFrame(1, true));
Biljith Jayan45a41722017-08-16 18:43:141678 MockRead data_read2[] = {CreateMockRead(spdy_response_no_error, 1),
1679 CreateMockRead(spdy_data, 2)};
1680
1681 // Two error responses.
Ryan Sleevib8d7ea02018-05-07 20:01:011682 StaticSocketDataProvider data1(data_read1, data_write);
1683 StaticSocketDataProvider data2(data_read1, data_write);
Biljith Jayan45a41722017-08-16 18:43:141684 // Followed by a success response.
Ryan Sleevib8d7ea02018-05-07 20:01:011685 SequencedSocketData data3(data_read2, data_write);
Biljith Jayan45a41722017-08-16 18:43:141686
1687 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1688 AddSSLSocketData();
1689 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1690 AddSSLSocketData();
1691 session_deps_.socket_factory->AddSocketDataProvider(&data3);
1692 AddSSLSocketData();
1693
1694 TestCompletionCallback callback;
1695 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1696 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1697
1698 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1699 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1700
1701 rv = callback.WaitForResult();
1702 EXPECT_THAT(rv, IsOk());
1703}
1704
bncd16676a2016-07-20 16:23:011705TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061706 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]202965992011-12-07 23:04:511707 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1708}
1709
bncd16676a2016-07-20 16:23:011710TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061711 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]202965992011-12-07 23:04:511712 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251713}
1714
bncd16676a2016-07-20 16:23:011715TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061716 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]202965992011-12-07 23:04:511717 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251718}
1719
[email protected]d58ceea82014-06-04 10:55:541720// Make sure that on a 408 response (Request Timeout), the request is retried,
1721// if the socket was a reused keep alive socket.
bncd16676a2016-07-20 16:23:011722TEST_F(HttpNetworkTransactionTest, KeepAlive408) {
[email protected]d58ceea82014-06-04 10:55:541723 MockRead read_failure(SYNCHRONOUS,
1724 "HTTP/1.1 408 Request Timeout\r\n"
1725 "Connection: Keep-Alive\r\n"
1726 "Content-Length: 6\r\n\r\n"
1727 "Pickle");
1728 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1729}
1730
bncd16676a2016-07-20 16:23:011731TEST_F(HttpNetworkTransactionTest, PreconnectErrorNotConnectedOnWrite) {
[email protected]a34f61ee2014-03-18 20:59:491732 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]09356c652014-03-25 15:36:101733 PreconnectErrorResendRequestTest(&write_failure, NULL, false);
[email protected]a34f61ee2014-03-18 20:59:491734}
1735
bncd16676a2016-07-20 16:23:011736TEST_F(HttpNetworkTransactionTest, PreconnectErrorReset) {
[email protected]a34f61ee2014-03-18 20:59:491737 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]09356c652014-03-25 15:36:101738 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
[email protected]a34f61ee2014-03-18 20:59:491739}
1740
bncd16676a2016-07-20 16:23:011741TEST_F(HttpNetworkTransactionTest, PreconnectErrorEOF) {
[email protected]a34f61ee2014-03-18 20:59:491742 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]09356c652014-03-25 15:36:101743 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1744}
1745
bncd16676a2016-07-20 16:23:011746TEST_F(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:101747 MockRead read_failure(ASYNC, OK); // EOF
1748 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1749}
1750
[email protected]d58ceea82014-06-04 10:55:541751// Make sure that on a 408 response (Request Timeout), the request is retried,
1752// if the socket was a preconnected (UNUSED_IDLE) socket.
bncd16676a2016-07-20 16:23:011753TEST_F(HttpNetworkTransactionTest, RetryOnIdle408) {
[email protected]d58ceea82014-06-04 10:55:541754 MockRead read_failure(SYNCHRONOUS,
1755 "HTTP/1.1 408 Request Timeout\r\n"
1756 "Connection: Keep-Alive\r\n"
1757 "Content-Length: 6\r\n\r\n"
1758 "Pickle");
1759 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1760 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1761}
1762
bncd16676a2016-07-20 16:23:011763TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorNotConnectedOnWrite) {
[email protected]09356c652014-03-25 15:36:101764 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1765 PreconnectErrorResendRequestTest(&write_failure, NULL, true);
1766}
1767
bncd16676a2016-07-20 16:23:011768TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
[email protected]09356c652014-03-25 15:36:101769 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1770 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1771}
1772
bncd16676a2016-07-20 16:23:011773TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
[email protected]09356c652014-03-25 15:36:101774 MockRead read_failure(SYNCHRONOUS, OK); // EOF
1775 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1776}
1777
bncd16676a2016-07-20 16:23:011778TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:101779 MockRead read_failure(ASYNC, OK); // EOF
1780 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
[email protected]a34f61ee2014-03-18 20:59:491781}
1782
bncd16676a2016-07-20 16:23:011783TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:421784 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:251785 request.method = "GET";
bncce36dca22015-04-21 22:11:231786 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:101787 request.traffic_annotation =
1788 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3d2a59b2008-09-26 19:44:251789
danakj1fd259a02016-04-16 03:17:091790 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161791 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271792
[email protected]3d2a59b2008-09-26 19:44:251793 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061794 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:351795 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1796 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061797 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251798 };
Ryan Sleevib8d7ea02018-05-07 20:01:011799 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071800 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:251801
[email protected]49639fa2011-12-20 23:22:411802 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:251803
tfarina42834112016-09-22 13:38:201804 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011805 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3d2a59b2008-09-26 19:44:251806
1807 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011808 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:591809
1810 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:161811 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:591812 EXPECT_LT(0u, endpoint.address().size());
[email protected]3d2a59b2008-09-26 19:44:251813}
1814
1815// What do various browsers do when the server closes a non-keepalive
1816// connection without sending any response header or body?
1817//
1818// IE7: error page
1819// Safari 3.1.2 (Windows): error page
1820// Firefox 3.0.1: blank page
1821// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:421822// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1823// Us: error page (EMPTY_RESPONSE)
bncd16676a2016-07-20 16:23:011824TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:251825 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061826 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:351827 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1828 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061829 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251830 };
Ryan Sleevib8d7ea02018-05-07 20:01:011831 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011832 EXPECT_THAT(out.rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]3d2a59b2008-09-26 19:44:251833}
[email protected]1826a402014-01-08 15:40:481834
[email protected]7a5378b2012-11-04 03:25:171835// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
1836// tests. There was a bug causing HttpNetworkTransaction to hang in the
1837// destructor in such situations.
1838// See http://crbug.com/154712 and http://crbug.com/156609.
bncd16676a2016-07-20 16:23:011839TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:171840 HttpRequestInfo request;
1841 request.method = "GET";
bncce36dca22015-04-21 22:11:231842 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:101843 request.traffic_annotation =
1844 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7a5378b2012-11-04 03:25:171845
danakj1fd259a02016-04-16 03:17:091846 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:581847 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:191848 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:171849
1850 MockRead data_reads[] = {
1851 MockRead("HTTP/1.0 200 OK\r\n"),
1852 MockRead("Connection: keep-alive\r\n"),
1853 MockRead("Content-Length: 100\r\n\r\n"),
1854 MockRead("hello"),
1855 MockRead(SYNCHRONOUS, 0),
1856 };
Ryan Sleevib8d7ea02018-05-07 20:01:011857 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071858 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171859
1860 TestCompletionCallback callback;
1861
tfarina42834112016-09-22 13:38:201862 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011863 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:171864
1865 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011866 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:171867
1868 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501869 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171870 if (rv == ERR_IO_PENDING)
1871 rv = callback.WaitForResult();
1872 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:501873 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
robpercival214763f2016-07-01 23:27:011874 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:171875
1876 trans.reset();
fdoray92e35a72016-06-10 15:54:551877 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171878 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1879}
1880
bncd16676a2016-07-20 16:23:011881TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:171882 HttpRequestInfo request;
1883 request.method = "GET";
bncce36dca22015-04-21 22:11:231884 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:101885 request.traffic_annotation =
1886 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7a5378b2012-11-04 03:25:171887
danakj1fd259a02016-04-16 03:17:091888 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:581889 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:191890 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:171891
1892 MockRead data_reads[] = {
1893 MockRead("HTTP/1.0 200 OK\r\n"),
1894 MockRead("Connection: keep-alive\r\n"),
1895 MockRead("Content-Length: 100\r\n\r\n"),
1896 MockRead(SYNCHRONOUS, 0),
1897 };
Ryan Sleevib8d7ea02018-05-07 20:01:011898 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071899 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171900
1901 TestCompletionCallback callback;
1902
tfarina42834112016-09-22 13:38:201903 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011904 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:171905
1906 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011907 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:171908
1909 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501910 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171911 if (rv == ERR_IO_PENDING)
1912 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011913 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:171914
1915 trans.reset();
fdoray92e35a72016-06-10 15:54:551916 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171917 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1918}
1919
[email protected]0b0bf032010-09-21 18:08:501920// Test that we correctly reuse a keep-alive connection after not explicitly
1921// reading the body.
bncd16676a2016-07-20 16:23:011922TEST_F(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:131923 HttpRequestInfo request;
1924 request.method = "GET";
1925 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101926 request.traffic_annotation =
1927 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]fc31d6a42010-06-24 18:05:131928
vishal.b62985ca92015-04-17 08:45:511929 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071930 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091931 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271932
mmenkecc2298e2015-12-07 18:20:181933 const char* request_data =
1934 "GET / HTTP/1.1\r\n"
1935 "Host: www.foo.com\r\n"
1936 "Connection: keep-alive\r\n\r\n";
1937 MockWrite data_writes[] = {
1938 MockWrite(ASYNC, 0, request_data), MockWrite(ASYNC, 2, request_data),
1939 MockWrite(ASYNC, 4, request_data), MockWrite(ASYNC, 6, request_data),
1940 MockWrite(ASYNC, 8, request_data), MockWrite(ASYNC, 10, request_data),
1941 MockWrite(ASYNC, 12, request_data), MockWrite(ASYNC, 14, request_data),
1942 MockWrite(ASYNC, 17, request_data), MockWrite(ASYNC, 20, request_data),
1943 };
1944
[email protected]0b0bf032010-09-21 18:08:501945 // Note that because all these reads happen in the same
1946 // StaticSocketDataProvider, it shows that the same socket is being reused for
1947 // all transactions.
mmenkecc2298e2015-12-07 18:20:181948 MockRead data_reads[] = {
1949 MockRead(ASYNC, 1, "HTTP/1.1 204 No Content\r\n\r\n"),
1950 MockRead(ASYNC, 3, "HTTP/1.1 205 Reset Content\r\n\r\n"),
1951 MockRead(ASYNC, 5, "HTTP/1.1 304 Not Modified\r\n\r\n"),
1952 MockRead(ASYNC, 7,
1953 "HTTP/1.1 302 Found\r\n"
1954 "Content-Length: 0\r\n\r\n"),
1955 MockRead(ASYNC, 9,
1956 "HTTP/1.1 302 Found\r\n"
1957 "Content-Length: 5\r\n\r\n"
1958 "hello"),
1959 MockRead(ASYNC, 11,
1960 "HTTP/1.1 301 Moved Permanently\r\n"
1961 "Content-Length: 0\r\n\r\n"),
1962 MockRead(ASYNC, 13,
1963 "HTTP/1.1 301 Moved Permanently\r\n"
1964 "Content-Length: 5\r\n\r\n"
1965 "hello"),
[email protected]fc31d6a42010-06-24 18:05:131966
mmenkecc2298e2015-12-07 18:20:181967 // In the next two rounds, IsConnectedAndIdle returns false, due to
1968 // the set_busy_before_sync_reads(true) call, while the
1969 // HttpNetworkTransaction is being shut down, but the socket is still
1970 // reuseable. See http://crbug.com/544255.
1971 MockRead(ASYNC, 15,
1972 "HTTP/1.1 200 Hunky-Dory\r\n"
1973 "Content-Length: 5\r\n\r\n"),
1974 MockRead(SYNCHRONOUS, 16, "hello"),
[email protected]fc31d6a42010-06-24 18:05:131975
mmenkecc2298e2015-12-07 18:20:181976 MockRead(ASYNC, 18,
1977 "HTTP/1.1 200 Hunky-Dory\r\n"
1978 "Content-Length: 5\r\n\r\n"
1979 "he"),
1980 MockRead(SYNCHRONOUS, 19, "llo"),
1981
1982 // The body of the final request is actually read.
1983 MockRead(ASYNC, 21, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1984 MockRead(ASYNC, 22, "hello"),
1985 };
Ryan Sleevib8d7ea02018-05-07 20:01:011986 SequencedSocketData data(data_reads, data_writes);
mmenkecc2298e2015-12-07 18:20:181987 data.set_busy_before_sync_reads(true);
1988 session_deps_.socket_factory->AddSocketDataProvider(&data);
1989
1990 const int kNumUnreadBodies = arraysize(data_writes) - 1;
[email protected]0b0bf032010-09-21 18:08:501991 std::string response_lines[kNumUnreadBodies];
1992
mikecironef22f9812016-10-04 03:40:191993 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
mmenkecc2298e2015-12-07 18:20:181994 for (size_t i = 0; i < kNumUnreadBodies; ++i) {
[email protected]49639fa2011-12-20 23:22:411995 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:131996
Jeremy Roman0579ed62017-08-29 15:56:191997 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
bnc87dcefc2017-05-25 12:47:581998 session.get());
[email protected]fc31d6a42010-06-24 18:05:131999
tfarina42834112016-09-22 13:38:202000 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012001 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]fc31d6a42010-06-24 18:05:132002
[email protected]58e32bb2013-01-21 18:23:252003 LoadTimingInfo load_timing_info;
2004 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2005 if (i == 0) {
2006 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
2007 first_socket_log_id = load_timing_info.socket_log_id;
2008 } else {
2009 TestLoadTimingReused(load_timing_info);
2010 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
2011 }
2012
[email protected]fc31d6a42010-06-24 18:05:132013 const HttpResponseInfo* response = trans->GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182014 ASSERT_TRUE(response);
[email protected]fc31d6a42010-06-24 18:05:132015
mmenkecc2298e2015-12-07 18:20:182016 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502017 response_lines[i] = response->headers->GetStatusLine();
2018
mmenkecc2298e2015-12-07 18:20:182019 // Delete the transaction without reading the response bodies. Then spin
2020 // the message loop, so the response bodies are drained.
2021 trans.reset();
2022 base::RunLoop().RunUntilIdle();
[email protected]fc31d6a42010-06-24 18:05:132023 }
[email protected]0b0bf032010-09-21 18:08:502024
2025 const char* const kStatusLines[] = {
mmenkecc2298e2015-12-07 18:20:182026 "HTTP/1.1 204 No Content",
2027 "HTTP/1.1 205 Reset Content",
2028 "HTTP/1.1 304 Not Modified",
2029 "HTTP/1.1 302 Found",
2030 "HTTP/1.1 302 Found",
2031 "HTTP/1.1 301 Moved Permanently",
2032 "HTTP/1.1 301 Moved Permanently",
2033 "HTTP/1.1 200 Hunky-Dory",
2034 "HTTP/1.1 200 Hunky-Dory",
[email protected]0b0bf032010-09-21 18:08:502035 };
2036
mostynb91e0da982015-01-20 19:17:272037 static_assert(kNumUnreadBodies == arraysize(kStatusLines),
2038 "forgot to update kStatusLines");
[email protected]0b0bf032010-09-21 18:08:502039
2040 for (int i = 0; i < kNumUnreadBodies; ++i)
2041 EXPECT_EQ(kStatusLines[i], response_lines[i]);
2042
[email protected]49639fa2011-12-20 23:22:412043 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:162044 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202045 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012046 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:162047 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182048 ASSERT_TRUE(response);
2049 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502050 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2051 std::string response_data;
bnc691fda62016-08-12 00:43:162052 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:012053 EXPECT_THAT(rv, IsOk());
[email protected]0b0bf032010-09-21 18:08:502054 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:132055}
2056
mmenke5f94fda2016-06-02 20:54:132057// Sockets that receive extra data after a response is complete should not be
2058// reused.
bncd16676a2016-07-20 16:23:012059TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData1) {
mmenke5f94fda2016-06-02 20:54:132060 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2061 MockWrite data_writes1[] = {
2062 MockWrite("HEAD / HTTP/1.1\r\n"
2063 "Host: www.borked.com\r\n"
2064 "Connection: keep-alive\r\n\r\n"),
2065 };
2066
2067 MockRead data_reads1[] = {
2068 MockRead("HTTP/1.1 200 OK\r\n"
2069 "Connection: keep-alive\r\n"
2070 "Content-Length: 22\r\n\r\n"
2071 "This server is borked."),
2072 };
2073
2074 MockWrite data_writes2[] = {
2075 MockWrite("GET /foo HTTP/1.1\r\n"
2076 "Host: www.borked.com\r\n"
2077 "Connection: keep-alive\r\n\r\n"),
2078 };
2079
2080 MockRead data_reads2[] = {
2081 MockRead("HTTP/1.1 200 OK\r\n"
2082 "Content-Length: 3\r\n\r\n"
2083 "foo"),
2084 };
Ryan Sleevib8d7ea02018-05-07 20:01:012085 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke5f94fda2016-06-02 20:54:132086 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:012087 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke5f94fda2016-06-02 20:54:132088 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2089
2090 TestCompletionCallback callback;
2091 HttpRequestInfo request1;
2092 request1.method = "HEAD";
2093 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e62018-02-07 07:41:102094 request1.traffic_annotation =
2095 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132096
bnc87dcefc2017-05-25 12:47:582097 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192098 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202099 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012100 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132101
2102 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2103 ASSERT_TRUE(response1);
2104 ASSERT_TRUE(response1->headers);
2105 EXPECT_EQ(200, response1->headers->response_code());
2106 EXPECT_TRUE(response1->headers->IsKeepAlive());
2107
2108 std::string response_data1;
robpercival214763f2016-07-01 23:27:012109 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132110 EXPECT_EQ("", response_data1);
2111 // Deleting the transaction attempts to release the socket back into the
2112 // socket pool.
2113 trans1.reset();
2114
2115 HttpRequestInfo request2;
2116 request2.method = "GET";
2117 request2.url = GURL("http://www.borked.com/foo");
Ramin Halavatib5e433e62018-02-07 07:41:102118 request2.traffic_annotation =
2119 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132120
bnc87dcefc2017-05-25 12:47:582121 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192122 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202123 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012124 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132125
2126 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2127 ASSERT_TRUE(response2);
2128 ASSERT_TRUE(response2->headers);
2129 EXPECT_EQ(200, response2->headers->response_code());
2130
2131 std::string response_data2;
robpercival214763f2016-07-01 23:27:012132 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132133 EXPECT_EQ("foo", response_data2);
2134}
2135
bncd16676a2016-07-20 16:23:012136TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData2) {
mmenke5f94fda2016-06-02 20:54:132137 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2138 MockWrite data_writes1[] = {
2139 MockWrite("GET / HTTP/1.1\r\n"
2140 "Host: www.borked.com\r\n"
2141 "Connection: keep-alive\r\n\r\n"),
2142 };
2143
2144 MockRead data_reads1[] = {
2145 MockRead("HTTP/1.1 200 OK\r\n"
2146 "Connection: keep-alive\r\n"
2147 "Content-Length: 22\r\n\r\n"
2148 "This server is borked."
2149 "Bonus data!"),
2150 };
2151
2152 MockWrite data_writes2[] = {
2153 MockWrite("GET /foo HTTP/1.1\r\n"
2154 "Host: www.borked.com\r\n"
2155 "Connection: keep-alive\r\n\r\n"),
2156 };
2157
2158 MockRead data_reads2[] = {
2159 MockRead("HTTP/1.1 200 OK\r\n"
2160 "Content-Length: 3\r\n\r\n"
2161 "foo"),
2162 };
Ryan Sleevib8d7ea02018-05-07 20:01:012163 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke5f94fda2016-06-02 20:54:132164 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:012165 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke5f94fda2016-06-02 20:54:132166 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2167
2168 TestCompletionCallback callback;
2169 HttpRequestInfo request1;
2170 request1.method = "GET";
2171 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e62018-02-07 07:41:102172 request1.traffic_annotation =
2173 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132174
bnc87dcefc2017-05-25 12:47:582175 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192176 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202177 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012178 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132179
2180 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2181 ASSERT_TRUE(response1);
2182 ASSERT_TRUE(response1->headers);
2183 EXPECT_EQ(200, response1->headers->response_code());
2184 EXPECT_TRUE(response1->headers->IsKeepAlive());
2185
2186 std::string response_data1;
robpercival214763f2016-07-01 23:27:012187 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132188 EXPECT_EQ("This server is borked.", response_data1);
2189 // Deleting the transaction attempts to release the socket back into the
2190 // socket pool.
2191 trans1.reset();
2192
2193 HttpRequestInfo request2;
2194 request2.method = "GET";
2195 request2.url = GURL("http://www.borked.com/foo");
Ramin Halavatib5e433e62018-02-07 07:41:102196 request2.traffic_annotation =
2197 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132198
bnc87dcefc2017-05-25 12:47:582199 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192200 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202201 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012202 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132203
2204 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2205 ASSERT_TRUE(response2);
2206 ASSERT_TRUE(response2->headers);
2207 EXPECT_EQ(200, response2->headers->response_code());
2208
2209 std::string response_data2;
robpercival214763f2016-07-01 23:27:012210 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132211 EXPECT_EQ("foo", response_data2);
2212}
2213
bncd16676a2016-07-20 16:23:012214TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData3) {
mmenke5f94fda2016-06-02 20:54:132215 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2216 MockWrite data_writes1[] = {
2217 MockWrite("GET / HTTP/1.1\r\n"
2218 "Host: www.borked.com\r\n"
2219 "Connection: keep-alive\r\n\r\n"),
2220 };
2221
2222 MockRead data_reads1[] = {
2223 MockRead("HTTP/1.1 200 OK\r\n"
2224 "Connection: keep-alive\r\n"
2225 "Transfer-Encoding: chunked\r\n\r\n"),
2226 MockRead("16\r\nThis server is borked.\r\n"),
2227 MockRead("0\r\n\r\nBonus data!"),
2228 };
2229
2230 MockWrite data_writes2[] = {
2231 MockWrite("GET /foo HTTP/1.1\r\n"
2232 "Host: www.borked.com\r\n"
2233 "Connection: keep-alive\r\n\r\n"),
2234 };
2235
2236 MockRead data_reads2[] = {
2237 MockRead("HTTP/1.1 200 OK\r\n"
2238 "Content-Length: 3\r\n\r\n"
2239 "foo"),
2240 };
Ryan Sleevib8d7ea02018-05-07 20:01:012241 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke5f94fda2016-06-02 20:54:132242 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:012243 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke5f94fda2016-06-02 20:54:132244 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2245
2246 TestCompletionCallback callback;
2247 HttpRequestInfo request1;
2248 request1.method = "GET";
2249 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e62018-02-07 07:41:102250 request1.traffic_annotation =
2251 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132252
bnc87dcefc2017-05-25 12:47:582253 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192254 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202255 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012256 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132257
2258 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2259 ASSERT_TRUE(response1);
2260 ASSERT_TRUE(response1->headers);
2261 EXPECT_EQ(200, response1->headers->response_code());
2262 EXPECT_TRUE(response1->headers->IsKeepAlive());
2263
2264 std::string response_data1;
robpercival214763f2016-07-01 23:27:012265 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132266 EXPECT_EQ("This server is borked.", response_data1);
2267 // Deleting the transaction attempts to release the socket back into the
2268 // socket pool.
2269 trans1.reset();
2270
2271 HttpRequestInfo request2;
2272 request2.method = "GET";
2273 request2.url = GURL("http://www.borked.com/foo");
Ramin Halavatib5e433e62018-02-07 07:41:102274 request2.traffic_annotation =
2275 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132276
bnc87dcefc2017-05-25 12:47:582277 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192278 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202279 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012280 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132281
2282 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2283 ASSERT_TRUE(response2);
2284 ASSERT_TRUE(response2->headers);
2285 EXPECT_EQ(200, response2->headers->response_code());
2286
2287 std::string response_data2;
robpercival214763f2016-07-01 23:27:012288 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132289 EXPECT_EQ("foo", response_data2);
2290}
2291
2292// This is a little different from the others - it tests the case that the
2293// HttpStreamParser doesn't know if there's extra data on a socket or not when
2294// the HttpNetworkTransaction is torn down, because the response body hasn't
2295// been read from yet, but the request goes through the HttpResponseBodyDrainer.
bncd16676a2016-07-20 16:23:012296TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData4) {
mmenke5f94fda2016-06-02 20:54:132297 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2298 MockWrite data_writes1[] = {
2299 MockWrite("GET / HTTP/1.1\r\n"
2300 "Host: www.borked.com\r\n"
2301 "Connection: keep-alive\r\n\r\n"),
2302 };
2303
2304 MockRead data_reads1[] = {
2305 MockRead("HTTP/1.1 200 OK\r\n"
2306 "Connection: keep-alive\r\n"
2307 "Transfer-Encoding: chunked\r\n\r\n"),
2308 MockRead("16\r\nThis server is borked.\r\n"),
2309 MockRead("0\r\n\r\nBonus data!"),
2310 };
Ryan Sleevib8d7ea02018-05-07 20:01:012311 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke5f94fda2016-06-02 20:54:132312 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2313
2314 TestCompletionCallback callback;
2315 HttpRequestInfo request1;
2316 request1.method = "GET";
2317 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e62018-02-07 07:41:102318 request1.traffic_annotation =
2319 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132320
bnc87dcefc2017-05-25 12:47:582321 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:192322 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
bnc87dcefc2017-05-25 12:47:582323 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012324 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132325
bnc87dcefc2017-05-25 12:47:582326 const HttpResponseInfo* response1 = trans->GetResponseInfo();
mmenke5f94fda2016-06-02 20:54:132327 ASSERT_TRUE(response1);
2328 ASSERT_TRUE(response1->headers);
2329 EXPECT_EQ(200, response1->headers->response_code());
2330 EXPECT_TRUE(response1->headers->IsKeepAlive());
2331
2332 // Deleting the transaction creates an HttpResponseBodyDrainer to read the
2333 // response body.
bnc87dcefc2017-05-25 12:47:582334 trans.reset();
mmenke5f94fda2016-06-02 20:54:132335
2336 // Let the HttpResponseBodyDrainer drain the socket. It should determine the
2337 // socket can't be reused, rather than returning it to the socket pool.
2338 base::RunLoop().RunUntilIdle();
2339
2340 // There should be no idle sockets in the pool.
2341 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2342}
2343
[email protected]038e9a32008-10-08 22:40:162344// Test the request-challenge-retry sequence for basic auth.
2345// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012346TEST_F(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:422347 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:162348 request.method = "GET";
bncce36dca22015-04-21 22:11:232349 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:102350 request.traffic_annotation =
2351 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]038e9a32008-10-08 22:40:162352
vishal.b62985ca92015-04-17 08:45:512353 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072354 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092355 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162356 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272357
[email protected]f9ee6b52008-11-08 06:46:232358 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232359 MockWrite(
2360 "GET / HTTP/1.1\r\n"
2361 "Host: www.example.org\r\n"
2362 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:232363 };
2364
[email protected]038e9a32008-10-08 22:40:162365 MockRead data_reads1[] = {
2366 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2367 // Give a couple authenticate options (only the middle one is actually
2368 // supported).
[email protected]22927ad2009-09-21 19:56:192369 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:162370 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2371 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2372 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2373 // Large content-length -- won't matter, as connection will be reset.
2374 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062375 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:162376 };
2377
2378 // After calling trans->RestartWithAuth(), this is the request we should
2379 // be issuing -- the final header line contains the credentials.
2380 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232381 MockWrite(
2382 "GET / HTTP/1.1\r\n"
2383 "Host: www.example.org\r\n"
2384 "Connection: keep-alive\r\n"
2385 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:162386 };
2387
2388 // Lastly, the server responds with the actual content.
2389 MockRead data_reads2[] = {
2390 MockRead("HTTP/1.0 200 OK\r\n"),
2391 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2392 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062393 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:162394 };
2395
Ryan Sleevib8d7ea02018-05-07 20:01:012396 StaticSocketDataProvider data1(data_reads1, data_writes1);
2397 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:072398 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2399 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:162400
[email protected]49639fa2011-12-20 23:22:412401 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:162402
tfarina42834112016-09-22 13:38:202403 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012404 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162405
2406 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012407 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162408
[email protected]58e32bb2013-01-21 18:23:252409 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162410 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
[email protected]58e32bb2013-01-21 18:23:252411 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2412
Ryan Sleevib8d7ea02018-05-07 20:01:012413 int64_t writes_size1 = CountWriteBytes(data_writes1);
bnc691fda62016-08-12 00:43:162414 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012415 int64_t reads_size1 = CountReadBytes(data_reads1);
bnc691fda62016-08-12 00:43:162416 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192417
bnc691fda62016-08-12 00:43:162418 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522419 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042420 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:162421
[email protected]49639fa2011-12-20 23:22:412422 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:162423
bnc691fda62016-08-12 00:43:162424 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012425 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162426
2427 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012428 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162429
[email protected]58e32bb2013-01-21 18:23:252430 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162431 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
[email protected]58e32bb2013-01-21 18:23:252432 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2433 // The load timing after restart should have a new socket ID, and times after
2434 // those of the first load timing.
2435 EXPECT_LE(load_timing_info1.receive_headers_end,
2436 load_timing_info2.connect_timing.connect_start);
2437 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2438
Ryan Sleevib8d7ea02018-05-07 20:01:012439 int64_t writes_size2 = CountWriteBytes(data_writes2);
bnc691fda62016-08-12 00:43:162440 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012441 int64_t reads_size2 = CountReadBytes(data_reads2);
bnc691fda62016-08-12 00:43:162442 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192443
bnc691fda62016-08-12 00:43:162444 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522445 ASSERT_TRUE(response);
2446 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:162447 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:162448}
2449
ttuttled9dbc652015-09-29 20:00:592450// Test the request-challenge-retry sequence for basic auth.
2451// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012452TEST_F(HttpNetworkTransactionTest, BasicAuthWithAddressChange) {
ttuttled9dbc652015-09-29 20:00:592453 HttpRequestInfo request;
2454 request.method = "GET";
2455 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:102456 request.traffic_annotation =
2457 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttled9dbc652015-09-29 20:00:592458
2459 TestNetLog log;
2460 MockHostResolver* resolver = new MockHostResolver();
2461 session_deps_.net_log = &log;
2462 session_deps_.host_resolver.reset(resolver);
danakj1fd259a02016-04-16 03:17:092463 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
bnc691fda62016-08-12 00:43:162464 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttled9dbc652015-09-29 20:00:592465
2466 resolver->rules()->ClearRules();
2467 resolver->rules()->AddRule("www.example.org", "127.0.0.1");
2468
2469 MockWrite data_writes1[] = {
2470 MockWrite("GET / HTTP/1.1\r\n"
2471 "Host: www.example.org\r\n"
2472 "Connection: keep-alive\r\n\r\n"),
2473 };
2474
2475 MockRead data_reads1[] = {
2476 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2477 // Give a couple authenticate options (only the middle one is actually
2478 // supported).
2479 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
2480 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2481 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2482 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2483 // Large content-length -- won't matter, as connection will be reset.
2484 MockRead("Content-Length: 10000\r\n\r\n"),
2485 MockRead(SYNCHRONOUS, ERR_FAILED),
2486 };
2487
2488 // After calling trans->RestartWithAuth(), this is the request we should
2489 // be issuing -- the final header line contains the credentials.
2490 MockWrite data_writes2[] = {
2491 MockWrite("GET / HTTP/1.1\r\n"
2492 "Host: www.example.org\r\n"
2493 "Connection: keep-alive\r\n"
2494 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2495 };
2496
2497 // Lastly, the server responds with the actual content.
2498 MockRead data_reads2[] = {
2499 MockRead("HTTP/1.0 200 OK\r\n"),
2500 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2501 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, OK),
2502 };
2503
Ryan Sleevib8d7ea02018-05-07 20:01:012504 StaticSocketDataProvider data1(data_reads1, data_writes1);
2505 StaticSocketDataProvider data2(data_reads2, data_writes2);
ttuttled9dbc652015-09-29 20:00:592506 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2507 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2508
2509 TestCompletionCallback callback1;
2510
bnc691fda62016-08-12 00:43:162511 EXPECT_EQ(OK, callback1.GetResult(trans.Start(&request, callback1.callback(),
tfarina42834112016-09-22 13:38:202512 NetLogWithSource())));
ttuttled9dbc652015-09-29 20:00:592513
2514 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162515 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
ttuttled9dbc652015-09-29 20:00:592516 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2517
Ryan Sleevib8d7ea02018-05-07 20:01:012518 int64_t writes_size1 = CountWriteBytes(data_writes1);
bnc691fda62016-08-12 00:43:162519 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012520 int64_t reads_size1 = CountReadBytes(data_reads1);
bnc691fda62016-08-12 00:43:162521 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592522
bnc691fda62016-08-12 00:43:162523 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592524 ASSERT_TRUE(response);
2525 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2526
2527 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:162528 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592529 ASSERT_FALSE(endpoint.address().empty());
2530 EXPECT_EQ("127.0.0.1:80", endpoint.ToString());
2531
2532 resolver->rules()->ClearRules();
2533 resolver->rules()->AddRule("www.example.org", "127.0.0.2");
2534
2535 TestCompletionCallback callback2;
2536
bnc691fda62016-08-12 00:43:162537 EXPECT_EQ(OK, callback2.GetResult(trans.RestartWithAuth(
ttuttled9dbc652015-09-29 20:00:592538 AuthCredentials(kFoo, kBar), callback2.callback())));
2539
2540 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162541 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
ttuttled9dbc652015-09-29 20:00:592542 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2543 // The load timing after restart should have a new socket ID, and times after
2544 // those of the first load timing.
2545 EXPECT_LE(load_timing_info1.receive_headers_end,
2546 load_timing_info2.connect_timing.connect_start);
2547 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2548
Ryan Sleevib8d7ea02018-05-07 20:01:012549 int64_t writes_size2 = CountWriteBytes(data_writes2);
bnc691fda62016-08-12 00:43:162550 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012551 int64_t reads_size2 = CountReadBytes(data_reads2);
bnc691fda62016-08-12 00:43:162552 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592553
bnc691fda62016-08-12 00:43:162554 response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592555 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:522556 EXPECT_FALSE(response->auth_challenge);
ttuttled9dbc652015-09-29 20:00:592557 EXPECT_EQ(100, response->headers->GetContentLength());
2558
bnc691fda62016-08-12 00:43:162559 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592560 ASSERT_FALSE(endpoint.address().empty());
2561 EXPECT_EQ("127.0.0.2:80", endpoint.ToString());
2562}
2563
David Benjamin83ddfb32018-03-30 01:07:522564// Test that, if the server requests auth indefinitely, HttpNetworkTransaction
2565// will eventually give up.
2566TEST_F(HttpNetworkTransactionTest, BasicAuthForever) {
2567 HttpRequestInfo request;
2568 request.method = "GET";
2569 request.url = GURL("http://www.example.org/");
2570 request.traffic_annotation =
2571 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2572
2573 TestNetLog log;
2574 session_deps_.net_log = &log;
2575 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2576 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
2577
2578 MockWrite data_writes[] = {
2579 MockWrite("GET / HTTP/1.1\r\n"
2580 "Host: www.example.org\r\n"
2581 "Connection: keep-alive\r\n\r\n"),
2582 };
2583
2584 MockRead data_reads[] = {
2585 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2586 // Give a couple authenticate options (only the middle one is actually
2587 // supported).
2588 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
2589 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2590 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2591 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2592 // Large content-length -- won't matter, as connection will be reset.
2593 MockRead("Content-Length: 10000\r\n\r\n"),
2594 MockRead(SYNCHRONOUS, ERR_FAILED),
2595 };
2596
2597 // After calling trans->RestartWithAuth(), this is the request we should
2598 // be issuing -- the final header line contains the credentials.
2599 MockWrite data_writes_restart[] = {
2600 MockWrite("GET / HTTP/1.1\r\n"
2601 "Host: www.example.org\r\n"
2602 "Connection: keep-alive\r\n"
2603 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2604 };
2605
Ryan Sleevib8d7ea02018-05-07 20:01:012606 StaticSocketDataProvider data(data_reads, data_writes);
David Benjamin83ddfb32018-03-30 01:07:522607 session_deps_.socket_factory->AddSocketDataProvider(&data);
2608
2609 TestCompletionCallback callback;
2610 int rv = callback.GetResult(
2611 trans.Start(&request, callback.callback(), NetLogWithSource()));
2612
2613 std::vector<std::unique_ptr<StaticSocketDataProvider>> data_restarts;
2614 for (int i = 0; i < 32; i++) {
2615 // Check the previous response was a 401.
2616 EXPECT_THAT(rv, IsOk());
2617 const HttpResponseInfo* response = trans.GetResponseInfo();
2618 ASSERT_TRUE(response);
2619 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2620
2621 data_restarts.push_back(std::make_unique<StaticSocketDataProvider>(
Ryan Sleevib8d7ea02018-05-07 20:01:012622 data_reads, data_writes_restart));
David Benjamin83ddfb32018-03-30 01:07:522623 session_deps_.socket_factory->AddSocketDataProvider(
2624 data_restarts.back().get());
2625 rv = callback.GetResult(trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
2626 callback.callback()));
2627 }
2628
2629 // After too many tries, the transaction should have given up.
2630 EXPECT_THAT(rv, IsError(ERR_TOO_MANY_RETRIES));
2631}
2632
bncd16676a2016-07-20 16:23:012633TEST_F(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:462634 HttpRequestInfo request;
2635 request.method = "GET";
bncce36dca22015-04-21 22:11:232636 request.url = GURL("http://www.example.org/");
ttuttle859dc7a2015-04-23 19:42:292637 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:102638 request.traffic_annotation =
2639 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]861fcd52009-08-26 02:33:462640
danakj1fd259a02016-04-16 03:17:092641 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162642 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272643
[email protected]861fcd52009-08-26 02:33:462644 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:232645 MockWrite(
2646 "GET / HTTP/1.1\r\n"
2647 "Host: www.example.org\r\n"
2648 "Connection: keep-alive\r\n\r\n"),
[email protected]861fcd52009-08-26 02:33:462649 };
2650
2651 MockRead data_reads[] = {
2652 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2653 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2654 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2655 // Large content-length -- won't matter, as connection will be reset.
2656 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062657 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:462658 };
2659
Ryan Sleevib8d7ea02018-05-07 20:01:012660 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:072661 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:412662 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:462663
tfarina42834112016-09-22 13:38:202664 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012665 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]861fcd52009-08-26 02:33:462666
2667 rv = callback.WaitForResult();
2668 EXPECT_EQ(0, rv);
2669
Ryan Sleevib8d7ea02018-05-07 20:01:012670 int64_t writes_size = CountWriteBytes(data_writes);
bnc691fda62016-08-12 00:43:162671 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012672 int64_t reads_size = CountReadBytes(data_reads);
bnc691fda62016-08-12 00:43:162673 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192674
bnc691fda62016-08-12 00:43:162675 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522676 ASSERT_TRUE(response);
2677 EXPECT_FALSE(response->auth_challenge);
[email protected]861fcd52009-08-26 02:33:462678}
2679
[email protected]2d2697f92009-02-18 21:00:322680// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2681// connection.
bncd16676a2016-07-20 16:23:012682TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
mmenkecc2298e2015-12-07 18:20:182683 // On the second pass, the body read of the auth challenge is synchronous, so
2684 // IsConnectedAndIdle returns false. The socket should still be drained and
2685 // reused. See http://crbug.com/544255.
2686 for (int i = 0; i < 2; ++i) {
2687 HttpRequestInfo request;
2688 request.method = "GET";
2689 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:102690 request.traffic_annotation =
2691 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:322692
mmenkecc2298e2015-12-07 18:20:182693 TestNetLog log;
2694 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092695 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272696
mmenkecc2298e2015-12-07 18:20:182697 MockWrite data_writes[] = {
2698 MockWrite(ASYNC, 0,
2699 "GET / HTTP/1.1\r\n"
2700 "Host: www.example.org\r\n"
2701 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322702
bnc691fda62016-08-12 00:43:162703 // After calling trans.RestartWithAuth(), this is the request we should
mmenkecc2298e2015-12-07 18:20:182704 // be issuing -- the final header line contains the credentials.
2705 MockWrite(ASYNC, 6,
2706 "GET / HTTP/1.1\r\n"
2707 "Host: www.example.org\r\n"
2708 "Connection: keep-alive\r\n"
2709 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2710 };
[email protected]2d2697f92009-02-18 21:00:322711
mmenkecc2298e2015-12-07 18:20:182712 MockRead data_reads[] = {
2713 MockRead(ASYNC, 1, "HTTP/1.1 401 Unauthorized\r\n"),
2714 MockRead(ASYNC, 2, "WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2715 MockRead(ASYNC, 3, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2716 MockRead(ASYNC, 4, "Content-Length: 14\r\n\r\n"),
2717 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 5, "Unauthorized\r\n"),
[email protected]2d2697f92009-02-18 21:00:322718
mmenkecc2298e2015-12-07 18:20:182719 // Lastly, the server responds with the actual content.
2720 MockRead(ASYNC, 7, "HTTP/1.1 200 OK\r\n"),
2721 MockRead(ASYNC, 8, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2722 MockRead(ASYNC, 9, "Content-Length: 5\r\n\r\n"),
2723 MockRead(ASYNC, 10, "Hello"),
2724 };
[email protected]2d2697f92009-02-18 21:00:322725
Ryan Sleevib8d7ea02018-05-07 20:01:012726 SequencedSocketData data(data_reads, data_writes);
mmenkecc2298e2015-12-07 18:20:182727 data.set_busy_before_sync_reads(true);
2728 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]2d0a4f92011-05-05 16:38:462729
mmenkecc2298e2015-12-07 18:20:182730 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322731
bnc691fda62016-08-12 00:43:162732 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202733 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012734 ASSERT_THAT(callback1.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322735
mmenkecc2298e2015-12-07 18:20:182736 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162737 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
mmenkecc2298e2015-12-07 18:20:182738 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
[email protected]2d2697f92009-02-18 21:00:322739
bnc691fda62016-08-12 00:43:162740 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182741 ASSERT_TRUE(response);
2742 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322743
mmenkecc2298e2015-12-07 18:20:182744 TestCompletionCallback callback2;
[email protected]58e32bb2013-01-21 18:23:252745
bnc691fda62016-08-12 00:43:162746 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
2747 callback2.callback());
robpercival214763f2016-07-01 23:27:012748 ASSERT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322749
mmenkecc2298e2015-12-07 18:20:182750 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162751 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
mmenkecc2298e2015-12-07 18:20:182752 TestLoadTimingReused(load_timing_info2);
2753 // The load timing after restart should have the same socket ID, and times
2754 // those of the first load timing.
2755 EXPECT_LE(load_timing_info1.receive_headers_end,
2756 load_timing_info2.send_start);
2757 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]2d2697f92009-02-18 21:00:322758
bnc691fda62016-08-12 00:43:162759 response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182760 ASSERT_TRUE(response);
2761 EXPECT_FALSE(response->auth_challenge);
2762 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322763
mmenkecc2298e2015-12-07 18:20:182764 std::string response_data;
bnc691fda62016-08-12 00:43:162765 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]2d2697f92009-02-18 21:00:322766
Ryan Sleevib8d7ea02018-05-07 20:01:012767 int64_t writes_size = CountWriteBytes(data_writes);
bnc691fda62016-08-12 00:43:162768 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012769 int64_t reads_size = CountReadBytes(data_reads);
bnc691fda62016-08-12 00:43:162770 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
mmenkecc2298e2015-12-07 18:20:182771 }
[email protected]2d2697f92009-02-18 21:00:322772}
2773
2774// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2775// connection and with no response body to drain.
bncd16676a2016-07-20 16:23:012776TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:422777 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322778 request.method = "GET";
bncce36dca22015-04-21 22:11:232779 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:102780 request.traffic_annotation =
2781 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:322782
danakj1fd259a02016-04-16 03:17:092783 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272784
[email protected]2d2697f92009-02-18 21:00:322785 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:162786 MockWrite("GET / HTTP/1.1\r\n"
2787 "Host: www.example.org\r\n"
2788 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322789
bnc691fda62016-08-12 00:43:162790 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:232791 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:162792 MockWrite("GET / HTTP/1.1\r\n"
2793 "Host: www.example.org\r\n"
2794 "Connection: keep-alive\r\n"
2795 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322796 };
2797
[email protected]2d2697f92009-02-18 21:00:322798 MockRead data_reads1[] = {
2799 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2800 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:312801 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:322802
2803 // Lastly, the server responds with the actual content.
2804 MockRead("HTTP/1.1 200 OK\r\n"),
2805 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502806 MockRead("Content-Length: 5\r\n\r\n"),
2807 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322808 };
2809
[email protected]2d0a4f92011-05-05 16:38:462810 // An incorrect reconnect would cause this to be read.
2811 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062812 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462813 };
2814
Ryan Sleevib8d7ea02018-05-07 20:01:012815 StaticSocketDataProvider data1(data_reads1, data_writes1);
2816 StaticSocketDataProvider data2(data_reads2, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:072817 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2818 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322819
[email protected]49639fa2011-12-20 23:22:412820 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322821
bnc691fda62016-08-12 00:43:162822 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202823 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012824 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322825
2826 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012827 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322828
bnc691fda62016-08-12 00:43:162829 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522830 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042831 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322832
[email protected]49639fa2011-12-20 23:22:412833 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322834
bnc691fda62016-08-12 00:43:162835 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012836 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322837
2838 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012839 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322840
bnc691fda62016-08-12 00:43:162841 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522842 ASSERT_TRUE(response);
2843 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502844 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322845}
2846
2847// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2848// connection and with a large response body to drain.
bncd16676a2016-07-20 16:23:012849TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:422850 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322851 request.method = "GET";
bncce36dca22015-04-21 22:11:232852 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:102853 request.traffic_annotation =
2854 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:322855
danakj1fd259a02016-04-16 03:17:092856 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272857
[email protected]2d2697f92009-02-18 21:00:322858 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:162859 MockWrite("GET / HTTP/1.1\r\n"
2860 "Host: www.example.org\r\n"
2861 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322862
bnc691fda62016-08-12 00:43:162863 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:232864 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:162865 MockWrite("GET / HTTP/1.1\r\n"
2866 "Host: www.example.org\r\n"
2867 "Connection: keep-alive\r\n"
2868 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322869 };
2870
2871 // Respond with 5 kb of response body.
2872 std::string large_body_string("Unauthorized");
2873 large_body_string.append(5 * 1024, ' ');
2874 large_body_string.append("\r\n");
2875
2876 MockRead data_reads1[] = {
2877 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2878 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2879 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2880 // 5134 = 12 + 5 * 1024 + 2
2881 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062882 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:322883
2884 // Lastly, the server responds with the actual content.
2885 MockRead("HTTP/1.1 200 OK\r\n"),
2886 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502887 MockRead("Content-Length: 5\r\n\r\n"),
2888 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322889 };
2890
[email protected]2d0a4f92011-05-05 16:38:462891 // An incorrect reconnect would cause this to be read.
2892 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062893 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462894 };
2895
Ryan Sleevib8d7ea02018-05-07 20:01:012896 StaticSocketDataProvider data1(data_reads1, data_writes1);
2897 StaticSocketDataProvider data2(data_reads2, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:072898 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2899 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322900
[email protected]49639fa2011-12-20 23:22:412901 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322902
bnc691fda62016-08-12 00:43:162903 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202904 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012905 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322906
2907 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012908 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322909
bnc691fda62016-08-12 00:43:162910 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522911 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042912 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322913
[email protected]49639fa2011-12-20 23:22:412914 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322915
bnc691fda62016-08-12 00:43:162916 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012917 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322918
2919 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012920 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322921
bnc691fda62016-08-12 00:43:162922 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522923 ASSERT_TRUE(response);
2924 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502925 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322926}
2927
2928// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:312929// connection, but the server gets impatient and closes the connection.
bncd16676a2016-07-20 16:23:012930TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:312931 HttpRequestInfo request;
2932 request.method = "GET";
bncce36dca22015-04-21 22:11:232933 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:102934 request.traffic_annotation =
2935 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]11203f012009-11-12 23:02:312936
danakj1fd259a02016-04-16 03:17:092937 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272938
[email protected]11203f012009-11-12 23:02:312939 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232940 MockWrite(
2941 "GET / HTTP/1.1\r\n"
2942 "Host: www.example.org\r\n"
2943 "Connection: keep-alive\r\n\r\n"),
2944 // This simulates the seemingly successful write to a closed connection
2945 // if the bug is not fixed.
2946 MockWrite(
2947 "GET / HTTP/1.1\r\n"
2948 "Host: www.example.org\r\n"
2949 "Connection: keep-alive\r\n"
2950 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312951 };
2952
2953 MockRead data_reads1[] = {
2954 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2955 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2956 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2957 MockRead("Content-Length: 14\r\n\r\n"),
2958 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:062959 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:312960 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:062961 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:312962 };
2963
bnc691fda62016-08-12 00:43:162964 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]11203f012009-11-12 23:02:312965 // be issuing -- the final header line contains the credentials.
2966 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232967 MockWrite(
2968 "GET / HTTP/1.1\r\n"
2969 "Host: www.example.org\r\n"
2970 "Connection: keep-alive\r\n"
2971 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312972 };
2973
2974 // Lastly, the server responds with the actual content.
2975 MockRead data_reads2[] = {
2976 MockRead("HTTP/1.1 200 OK\r\n"),
2977 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502978 MockRead("Content-Length: 5\r\n\r\n"),
2979 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:312980 };
2981
Ryan Sleevib8d7ea02018-05-07 20:01:012982 StaticSocketDataProvider data1(data_reads1, data_writes1);
2983 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:072984 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2985 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:312986
[email protected]49639fa2011-12-20 23:22:412987 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:312988
bnc691fda62016-08-12 00:43:162989 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202990 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012991 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:312992
2993 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012994 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:312995
bnc691fda62016-08-12 00:43:162996 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522997 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042998 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:312999
[email protected]49639fa2011-12-20 23:22:413000 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:313001
bnc691fda62016-08-12 00:43:163002 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013003 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:313004
3005 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013006 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:313007
bnc691fda62016-08-12 00:43:163008 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523009 ASSERT_TRUE(response);
3010 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503011 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:313012}
3013
[email protected]394816e92010-08-03 07:38:593014// Test the request-challenge-retry sequence for basic auth, over a connection
3015// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013016TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
ttuttle34f63b52015-03-05 04:33:013017 HttpRequestInfo request;
3018 request.method = "GET";
bncce36dca22015-04-21 22:11:233019 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:013020 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293021 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:103022 request.traffic_annotation =
3023 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle34f63b52015-03-05 04:33:013024
3025 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593026 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493027 ProxyResolutionService::CreateFixedFromPacResult(
3028 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513029 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:013030 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093031 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013032
3033 // Since we have proxy, should try to establish tunnel.
3034 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543035 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173036 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543037 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013038 };
3039
mmenkee71e15332015-10-07 16:39:543040 // The proxy responds to the connect with a 407, using a non-persistent
ttuttle34f63b52015-03-05 04:33:013041 // connection.
3042 MockRead data_reads1[] = {
3043 // No credentials.
3044 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
3045 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
mmenkee71e15332015-10-07 16:39:543046 };
ttuttle34f63b52015-03-05 04:33:013047
mmenkee71e15332015-10-07 16:39:543048 // Since the first connection couldn't be reused, need to establish another
3049 // once given credentials.
3050 MockWrite data_writes2[] = {
3051 // After calling trans->RestartWithAuth(), this is the request we should
3052 // be issuing -- the final header line contains the credentials.
3053 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173054 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543055 "Proxy-Connection: keep-alive\r\n"
3056 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3057
3058 MockWrite("GET / HTTP/1.1\r\n"
3059 "Host: www.example.org\r\n"
3060 "Connection: keep-alive\r\n\r\n"),
3061 };
3062
3063 MockRead data_reads2[] = {
ttuttle34f63b52015-03-05 04:33:013064 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3065
3066 MockRead("HTTP/1.1 200 OK\r\n"),
3067 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3068 MockRead("Content-Length: 5\r\n\r\n"),
3069 MockRead(SYNCHRONOUS, "hello"),
3070 };
3071
Ryan Sleevib8d7ea02018-05-07 20:01:013072 StaticSocketDataProvider data1(data_reads1, data_writes1);
ttuttle34f63b52015-03-05 04:33:013073 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:013074 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenkee71e15332015-10-07 16:39:543075 session_deps_.socket_factory->AddSocketDataProvider(&data2);
ttuttle34f63b52015-03-05 04:33:013076 SSLSocketDataProvider ssl(ASYNC, OK);
3077 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3078
3079 TestCompletionCallback callback1;
3080
bnc87dcefc2017-05-25 12:47:583081 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193082 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013083
3084 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013085 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:013086
3087 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013088 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463089 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:013090 log.GetEntries(&entries);
3091 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003092 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3093 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013094 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003095 entries, pos,
3096 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3097 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013098
3099 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523100 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013101 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523102 ASSERT_TRUE(response->headers);
ttuttle34f63b52015-03-05 04:33:013103 EXPECT_EQ(407, response->headers->response_code());
3104 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3105 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3106
3107 LoadTimingInfo load_timing_info;
3108 // CONNECT requests and responses are handled at the connect job level, so
3109 // the transaction does not yet have a connection.
3110 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3111
3112 TestCompletionCallback callback2;
3113
3114 rv =
3115 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013116 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:013117
3118 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013119 EXPECT_THAT(rv, IsOk());
ttuttle34f63b52015-03-05 04:33:013120
3121 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523122 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013123
3124 EXPECT_TRUE(response->headers->IsKeepAlive());
3125 EXPECT_EQ(200, response->headers->response_code());
3126 EXPECT_EQ(5, response->headers->GetContentLength());
3127 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3128
3129 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523130 EXPECT_FALSE(response->auth_challenge);
ttuttle34f63b52015-03-05 04:33:013131
3132 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3133 TestLoadTimingNotReusedWithPac(load_timing_info,
3134 CONNECT_TIMING_HAS_SSL_TIMES);
3135
3136 trans.reset();
3137 session->CloseAllConnections();
3138}
3139
3140// Test the request-challenge-retry sequence for basic auth, over a connection
3141// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013142TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) {
[email protected]394816e92010-08-03 07:38:593143 HttpRequestInfo request;
3144 request.method = "GET";
bncce36dca22015-04-21 22:11:233145 request.url = GURL("https://www.example.org/");
[email protected]394816e92010-08-03 07:38:593146 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293147 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:103148 request.traffic_annotation =
3149 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]394816e92010-08-03 07:38:593150
[email protected]cb9bf6ca2011-01-28 13:15:273151 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593152 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493153 ProxyResolutionService::CreateFixedFromPacResult(
3154 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513155 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073156 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093157 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273158
[email protected]394816e92010-08-03 07:38:593159 // Since we have proxy, should try to establish tunnel.
3160 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543161 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173162 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543163 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenkee0b5c882015-08-26 20:29:113164 };
3165
mmenkee71e15332015-10-07 16:39:543166 // The proxy responds to the connect with a 407, using a non-persistent
mmenke0fd148d2015-09-30 23:00:083167 // connection.
3168 MockRead data_reads1[] = {
mmenkee71e15332015-10-07 16:39:543169 // No credentials.
3170 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3171 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3172 MockRead("Proxy-Connection: close\r\n\r\n"),
3173 };
mmenkee0b5c882015-08-26 20:29:113174
mmenkee71e15332015-10-07 16:39:543175 MockWrite data_writes2[] = {
3176 // After calling trans->RestartWithAuth(), this is the request we should
3177 // be issuing -- the final header line contains the credentials.
3178 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173179 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543180 "Proxy-Connection: keep-alive\r\n"
3181 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
mmenke0fd148d2015-09-30 23:00:083182
mmenkee71e15332015-10-07 16:39:543183 MockWrite("GET / HTTP/1.1\r\n"
3184 "Host: www.example.org\r\n"
3185 "Connection: keep-alive\r\n\r\n"),
3186 };
3187
3188 MockRead data_reads2[] = {
3189 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3190
3191 MockRead("HTTP/1.1 200 OK\r\n"),
3192 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3193 MockRead("Content-Length: 5\r\n\r\n"),
3194 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:593195 };
3196
Ryan Sleevib8d7ea02018-05-07 20:01:013197 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:073198 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:013199 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenkee71e15332015-10-07 16:39:543200 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8ddf8322012-02-23 18:08:063201 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073202 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:593203
[email protected]49639fa2011-12-20 23:22:413204 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:593205
bnc87dcefc2017-05-25 12:47:583206 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193207 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:503208
[email protected]49639fa2011-12-20 23:22:413209 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013210 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593211
3212 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013213 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463214 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403215 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:593216 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003217 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3218 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593219 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403220 entries, pos,
mikecirone8b85c432016-09-08 19:11:003221 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3222 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593223
3224 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523225 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013226 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523227 ASSERT_TRUE(response->headers);
[email protected]394816e92010-08-03 07:38:593228 EXPECT_EQ(407, response->headers->response_code());
3229 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043230 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:593231
[email protected]029c83b62013-01-24 05:28:203232 LoadTimingInfo load_timing_info;
3233 // CONNECT requests and responses are handled at the connect job level, so
3234 // the transaction does not yet have a connection.
3235 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3236
[email protected]49639fa2011-12-20 23:22:413237 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:593238
[email protected]49639fa2011-12-20 23:22:413239 rv = trans->RestartWithAuth(
3240 AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013241 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593242
3243 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013244 EXPECT_THAT(rv, IsOk());
[email protected]394816e92010-08-03 07:38:593245
3246 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523247 ASSERT_TRUE(response);
[email protected]394816e92010-08-03 07:38:593248
3249 EXPECT_TRUE(response->headers->IsKeepAlive());
3250 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:503251 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:593252 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3253
3254 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523255 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503256
[email protected]029c83b62013-01-24 05:28:203257 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3258 TestLoadTimingNotReusedWithPac(load_timing_info,
3259 CONNECT_TIMING_HAS_SSL_TIMES);
3260
[email protected]0b0bf032010-09-21 18:08:503261 trans.reset();
[email protected]102e27c2011-02-23 01:01:313262 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:593263}
3264
[email protected]11203f012009-11-12 23:02:313265// Test the request-challenge-retry sequence for basic auth, over a keep-alive
ttuttle34f63b52015-03-05 04:33:013266// proxy connection with HTTP/1.0 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013267TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
mmenked39192ee2015-12-09 00:57:233268 // On the second pass, the body read of the auth challenge is synchronous, so
3269 // IsConnectedAndIdle returns false. The socket should still be drained and
3270 // reused. See http://crbug.com/544255.
3271 for (int i = 0; i < 2; ++i) {
3272 HttpRequestInfo request;
3273 request.method = "GET";
3274 request.url = GURL("https://www.example.org/");
3275 // Ensure that proxy authentication is attempted even
3276 // when the no authentication data flag is set.
3277 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:103278 request.traffic_annotation =
3279 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle34f63b52015-03-05 04:33:013280
mmenked39192ee2015-12-09 00:57:233281 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593282 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493283 ProxyResolutionService::CreateFixed("myproxy:70",
3284 TRAFFIC_ANNOTATION_FOR_TESTS);
mmenked39192ee2015-12-09 00:57:233285 BoundTestNetLog log;
3286 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093287 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013288
bnc691fda62016-08-12 00:43:163289 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013290
mmenked39192ee2015-12-09 00:57:233291 // Since we have proxy, should try to establish tunnel.
3292 MockWrite data_writes1[] = {
3293 MockWrite(ASYNC, 0,
3294 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3295 "Host: www.example.org:443\r\n"
3296 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013297
bnc691fda62016-08-12 00:43:163298 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233299 // be issuing -- the final header line contains the credentials.
3300 MockWrite(ASYNC, 3,
3301 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3302 "Host: www.example.org:443\r\n"
3303 "Proxy-Connection: keep-alive\r\n"
3304 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3305 };
ttuttle34f63b52015-03-05 04:33:013306
mmenked39192ee2015-12-09 00:57:233307 // The proxy responds to the connect with a 407, using a persistent
3308 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3309 MockRead data_reads1[] = {
3310 // No credentials.
3311 MockRead(ASYNC, 1,
3312 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3313 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3314 "Proxy-Connection: keep-alive\r\n"
3315 "Content-Length: 10\r\n\r\n"),
3316 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
ttuttle34f63b52015-03-05 04:33:013317
mmenked39192ee2015-12-09 00:57:233318 // Wrong credentials (wrong password).
3319 MockRead(ASYNC, 4,
3320 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3321 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3322 "Proxy-Connection: keep-alive\r\n"
3323 "Content-Length: 10\r\n\r\n"),
3324 // No response body because the test stops reading here.
3325 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3326 };
ttuttle34f63b52015-03-05 04:33:013327
Ryan Sleevib8d7ea02018-05-07 20:01:013328 SequencedSocketData data1(data_reads1, data_writes1);
mmenked39192ee2015-12-09 00:57:233329 data1.set_busy_before_sync_reads(true);
3330 session_deps_.socket_factory->AddSocketDataProvider(&data1);
ttuttle34f63b52015-03-05 04:33:013331
mmenked39192ee2015-12-09 00:57:233332 TestCompletionCallback callback1;
ttuttle34f63b52015-03-05 04:33:013333
bnc691fda62016-08-12 00:43:163334 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013335 EXPECT_THAT(callback1.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013336
mmenked39192ee2015-12-09 00:57:233337 TestNetLogEntry::List entries;
3338 log.GetEntries(&entries);
3339 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003340 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3341 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233342 ExpectLogContainsSomewhere(
3343 entries, pos,
mikecirone8b85c432016-09-08 19:11:003344 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3345 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013346
bnc691fda62016-08-12 00:43:163347 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233348 ASSERT_TRUE(response);
3349 ASSERT_TRUE(response->headers);
3350 EXPECT_TRUE(response->headers->IsKeepAlive());
3351 EXPECT_EQ(407, response->headers->response_code());
3352 EXPECT_EQ(10, response->headers->GetContentLength());
3353 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3354 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013355
mmenked39192ee2015-12-09 00:57:233356 TestCompletionCallback callback2;
ttuttle34f63b52015-03-05 04:33:013357
mmenked39192ee2015-12-09 00:57:233358 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163359 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3360 callback2.callback());
robpercival214763f2016-07-01 23:27:013361 EXPECT_THAT(callback2.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013362
bnc691fda62016-08-12 00:43:163363 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233364 ASSERT_TRUE(response);
3365 ASSERT_TRUE(response->headers);
3366 EXPECT_TRUE(response->headers->IsKeepAlive());
3367 EXPECT_EQ(407, response->headers->response_code());
3368 EXPECT_EQ(10, response->headers->GetContentLength());
3369 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3370 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013371
mmenked39192ee2015-12-09 00:57:233372 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3373 // out of scope.
3374 session->CloseAllConnections();
3375 }
ttuttle34f63b52015-03-05 04:33:013376}
3377
3378// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3379// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013380TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
mmenked39192ee2015-12-09 00:57:233381 // On the second pass, the body read of the auth challenge is synchronous, so
3382 // IsConnectedAndIdle returns false. The socket should still be drained and
3383 // reused. See http://crbug.com/544255.
3384 for (int i = 0; i < 2; ++i) {
3385 HttpRequestInfo request;
3386 request.method = "GET";
3387 request.url = GURL("https://www.example.org/");
3388 // Ensure that proxy authentication is attempted even
3389 // when the no authentication data flag is set.
3390 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:103391 request.traffic_annotation =
3392 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenked39192ee2015-12-09 00:57:233393
3394 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593395 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493396 ProxyResolutionService::CreateFixed("myproxy:70",
3397 TRAFFIC_ANNOTATION_FOR_TESTS);
mmenked39192ee2015-12-09 00:57:233398 BoundTestNetLog log;
3399 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093400 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenked39192ee2015-12-09 00:57:233401
bnc691fda62016-08-12 00:43:163402 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenked39192ee2015-12-09 00:57:233403
3404 // Since we have proxy, should try to establish tunnel.
3405 MockWrite data_writes1[] = {
3406 MockWrite(ASYNC, 0,
3407 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3408 "Host: www.example.org:443\r\n"
3409 "Proxy-Connection: keep-alive\r\n\r\n"),
3410
bnc691fda62016-08-12 00:43:163411 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233412 // be issuing -- the final header line contains the credentials.
3413 MockWrite(ASYNC, 3,
3414 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3415 "Host: www.example.org:443\r\n"
3416 "Proxy-Connection: keep-alive\r\n"
3417 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3418 };
3419
3420 // The proxy responds to the connect with a 407, using a persistent
3421 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3422 MockRead data_reads1[] = {
3423 // No credentials.
3424 MockRead(ASYNC, 1,
3425 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3426 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3427 "Content-Length: 10\r\n\r\n"),
3428 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
3429
3430 // Wrong credentials (wrong password).
3431 MockRead(ASYNC, 4,
3432 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3433 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3434 "Content-Length: 10\r\n\r\n"),
3435 // No response body because the test stops reading here.
3436 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3437 };
3438
Ryan Sleevib8d7ea02018-05-07 20:01:013439 SequencedSocketData data1(data_reads1, data_writes1);
mmenked39192ee2015-12-09 00:57:233440 data1.set_busy_before_sync_reads(true);
3441 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3442
3443 TestCompletionCallback callback1;
3444
bnc691fda62016-08-12 00:43:163445 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013446 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233447
3448 TestNetLogEntry::List entries;
3449 log.GetEntries(&entries);
3450 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003451 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3452 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233453 ExpectLogContainsSomewhere(
3454 entries, pos,
mikecirone8b85c432016-09-08 19:11:003455 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3456 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233457
bnc691fda62016-08-12 00:43:163458 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233459 ASSERT_TRUE(response);
3460 ASSERT_TRUE(response->headers);
3461 EXPECT_TRUE(response->headers->IsKeepAlive());
3462 EXPECT_EQ(407, response->headers->response_code());
3463 EXPECT_EQ(10, response->headers->GetContentLength());
3464 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3465 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3466
3467 TestCompletionCallback callback2;
3468
3469 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163470 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3471 callback2.callback());
robpercival214763f2016-07-01 23:27:013472 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233473
bnc691fda62016-08-12 00:43:163474 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233475 ASSERT_TRUE(response);
3476 ASSERT_TRUE(response->headers);
3477 EXPECT_TRUE(response->headers->IsKeepAlive());
3478 EXPECT_EQ(407, response->headers->response_code());
3479 EXPECT_EQ(10, response->headers->GetContentLength());
3480 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3481 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3482
3483 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3484 // out of scope.
3485 session->CloseAllConnections();
3486 }
3487}
3488
3489// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3490// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel, in
3491// the case the server sends extra data on the original socket, so it can't be
3492// reused.
bncd16676a2016-07-20 16:23:013493TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveExtraData) {
[email protected]cb9bf6ca2011-01-28 13:15:273494 HttpRequestInfo request;
3495 request.method = "GET";
bncce36dca22015-04-21 22:11:233496 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273497 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293498 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:103499 request.traffic_annotation =
3500 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:273501
[email protected]2d2697f92009-02-18 21:00:323502 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593503 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493504 ProxyResolutionService::CreateFixedFromPacResult(
3505 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513506 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073507 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093508 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:323509
[email protected]2d2697f92009-02-18 21:00:323510 // Since we have proxy, should try to establish tunnel.
3511 MockWrite data_writes1[] = {
mmenked39192ee2015-12-09 00:57:233512 MockWrite(ASYNC, 0,
3513 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173514 "Host: www.example.org:443\r\n"
3515 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233516 };
[email protected]2d2697f92009-02-18 21:00:323517
mmenked39192ee2015-12-09 00:57:233518 // The proxy responds to the connect with a 407, using a persistent, but sends
3519 // extra data, so the socket cannot be reused.
3520 MockRead data_reads1[] = {
3521 // No credentials.
3522 MockRead(ASYNC, 1,
3523 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3524 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3525 "Content-Length: 10\r\n\r\n"),
3526 MockRead(SYNCHRONOUS, 2, "0123456789"),
3527 MockRead(SYNCHRONOUS, 3, "I'm broken!"),
3528 };
3529
3530 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:233531 // After calling trans->RestartWithAuth(), this is the request we should
3532 // be issuing -- the final header line contains the credentials.
mmenked39192ee2015-12-09 00:57:233533 MockWrite(ASYNC, 0,
3534 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173535 "Host: www.example.org:443\r\n"
3536 "Proxy-Connection: keep-alive\r\n"
mmenked39192ee2015-12-09 00:57:233537 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3538
3539 MockWrite(ASYNC, 2,
3540 "GET / HTTP/1.1\r\n"
3541 "Host: www.example.org\r\n"
3542 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323543 };
3544
mmenked39192ee2015-12-09 00:57:233545 MockRead data_reads2[] = {
3546 MockRead(ASYNC, 1, "HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323547
mmenked39192ee2015-12-09 00:57:233548 MockRead(ASYNC, 3,
3549 "HTTP/1.1 200 OK\r\n"
3550 "Content-Type: text/html; charset=iso-8859-1\r\n"
3551 "Content-Length: 5\r\n\r\n"),
3552 // No response body because the test stops reading here.
3553 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 4),
[email protected]2d2697f92009-02-18 21:00:323554 };
3555
Ryan Sleevib8d7ea02018-05-07 20:01:013556 SequencedSocketData data1(data_reads1, data_writes1);
mmenked39192ee2015-12-09 00:57:233557 data1.set_busy_before_sync_reads(true);
[email protected]bb88e1d32013-05-03 23:11:073558 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:013559 SequencedSocketData data2(data_reads2, data_writes2);
mmenked39192ee2015-12-09 00:57:233560 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3561 SSLSocketDataProvider ssl(ASYNC, OK);
3562 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d2697f92009-02-18 21:00:323563
[email protected]49639fa2011-12-20 23:22:413564 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323565
bnc87dcefc2017-05-25 12:47:583566 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193567 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d2697f92009-02-18 21:00:323568
mmenked39192ee2015-12-09 00:57:233569 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013570 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233571
mmenke43758e62015-05-04 21:09:463572 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403573 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:393574 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003575 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3576 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:393577 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403578 entries, pos,
mikecirone8b85c432016-09-08 19:11:003579 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3580 NetLogEventPhase::NONE);
[email protected]2d2697f92009-02-18 21:00:323581
[email protected]1c773ea12009-04-28 19:58:423582 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243583 ASSERT_TRUE(response);
3584 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:323585 EXPECT_TRUE(response->headers->IsKeepAlive());
3586 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423587 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043588 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:323589
mmenked39192ee2015-12-09 00:57:233590 LoadTimingInfo load_timing_info;
3591 // CONNECT requests and responses are handled at the connect job level, so
3592 // the transaction does not yet have a connection.
3593 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3594
[email protected]49639fa2011-12-20 23:22:413595 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323596
mmenked39192ee2015-12-09 00:57:233597 rv =
3598 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013599 EXPECT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:323600
[email protected]2d2697f92009-02-18 21:00:323601 EXPECT_TRUE(response->headers->IsKeepAlive());
mmenked39192ee2015-12-09 00:57:233602 EXPECT_EQ(200, response->headers->response_code());
3603 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:423604 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]e772db3f2010-07-12 18:11:133605
mmenked39192ee2015-12-09 00:57:233606 // The password prompt info should not be set.
3607 EXPECT_FALSE(response->auth_challenge);
3608
3609 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3610 TestLoadTimingNotReusedWithPac(load_timing_info,
3611 CONNECT_TIMING_HAS_SSL_TIMES);
3612
3613 trans.reset();
[email protected]102e27c2011-02-23 01:01:313614 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:323615}
3616
mmenkee71e15332015-10-07 16:39:543617// Test the case a proxy closes a socket while the challenge body is being
3618// drained.
bncd16676a2016-07-20 16:23:013619TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHangupDuringBody) {
mmenkee71e15332015-10-07 16:39:543620 HttpRequestInfo request;
3621 request.method = "GET";
3622 request.url = GURL("https://www.example.org/");
3623 // Ensure that proxy authentication is attempted even
3624 // when the no authentication data flag is set.
3625 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:103626 request.traffic_annotation =
3627 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenkee71e15332015-10-07 16:39:543628
3629 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:493630 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
3631 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:093632 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenkee71e15332015-10-07 16:39:543633
bnc691fda62016-08-12 00:43:163634 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkee71e15332015-10-07 16:39:543635
3636 // Since we have proxy, should try to establish tunnel.
3637 MockWrite data_writes1[] = {
3638 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173639 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543640 "Proxy-Connection: keep-alive\r\n\r\n"),
3641 };
3642
3643 // The proxy responds to the connect with a 407, using a persistent
3644 // connection.
3645 MockRead data_reads1[] = {
3646 // No credentials.
3647 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3648 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3649 MockRead("Content-Length: 10\r\n\r\n"), MockRead("spam!"),
3650 // Server hands up in the middle of the body.
3651 MockRead(ASYNC, ERR_CONNECTION_CLOSED),
3652 };
3653
3654 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:163655 // After calling trans.RestartWithAuth(), this is the request we should
mmenkee71e15332015-10-07 16:39:543656 // be issuing -- the final header line contains the credentials.
3657 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173658 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543659 "Proxy-Connection: keep-alive\r\n"
3660 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3661
3662 MockWrite("GET / HTTP/1.1\r\n"
3663 "Host: www.example.org\r\n"
3664 "Connection: keep-alive\r\n\r\n"),
3665 };
3666
3667 MockRead data_reads2[] = {
3668 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3669
3670 MockRead("HTTP/1.1 200 OK\r\n"),
3671 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3672 MockRead("Content-Length: 5\r\n\r\n"),
3673 MockRead(SYNCHRONOUS, "hello"),
3674 };
3675
Ryan Sleevib8d7ea02018-05-07 20:01:013676 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenkee71e15332015-10-07 16:39:543677 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:013678 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenkee71e15332015-10-07 16:39:543679 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3680 SSLSocketDataProvider ssl(ASYNC, OK);
3681 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3682
3683 TestCompletionCallback callback;
3684
tfarina42834112016-09-22 13:38:203685 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013686 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543687
bnc691fda62016-08-12 00:43:163688 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543689 ASSERT_TRUE(response);
3690 ASSERT_TRUE(response->headers);
3691 EXPECT_TRUE(response->headers->IsKeepAlive());
3692 EXPECT_EQ(407, response->headers->response_code());
3693 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3694
bnc691fda62016-08-12 00:43:163695 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
robpercival214763f2016-07-01 23:27:013696 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543697
bnc691fda62016-08-12 00:43:163698 response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543699 ASSERT_TRUE(response);
3700 ASSERT_TRUE(response->headers);
3701 EXPECT_TRUE(response->headers->IsKeepAlive());
3702 EXPECT_EQ(200, response->headers->response_code());
3703 std::string body;
bnc691fda62016-08-12 00:43:163704 EXPECT_THAT(ReadTransaction(&trans, &body), IsOk());
mmenkee71e15332015-10-07 16:39:543705 EXPECT_EQ("hello", body);
3706}
3707
[email protected]a8e9b162009-03-12 00:06:443708// Test that we don't read the response body when we fail to establish a tunnel,
3709// even if the user cancels the proxy's auth attempt.
bncd16676a2016-07-20 16:23:013710TEST_F(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:273711 HttpRequestInfo request;
3712 request.method = "GET";
bncce36dca22015-04-21 22:11:233713 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:103714 request.traffic_annotation =
3715 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:273716
[email protected]a8e9b162009-03-12 00:06:443717 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:493718 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
3719 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]a8e9b162009-03-12 00:06:443720
danakj1fd259a02016-04-16 03:17:093721 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:443722
bnc691fda62016-08-12 00:43:163723 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a8e9b162009-03-12 00:06:443724
[email protected]a8e9b162009-03-12 00:06:443725 // Since we have proxy, should try to establish tunnel.
3726 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173727 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3728 "Host: www.example.org:443\r\n"
3729 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:443730 };
3731
3732 // The proxy responds to the connect with a 407.
3733 MockRead data_reads[] = {
ttuttle7933c112015-01-06 00:55:243734 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3735 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3736 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233737 MockRead("0123456789"),
ttuttle7933c112015-01-06 00:55:243738 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]a8e9b162009-03-12 00:06:443739 };
3740
Ryan Sleevib8d7ea02018-05-07 20:01:013741 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:073742 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:443743
[email protected]49639fa2011-12-20 23:22:413744 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:443745
tfarina42834112016-09-22 13:38:203746 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013747 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a8e9b162009-03-12 00:06:443748
3749 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013750 EXPECT_THAT(rv, IsOk());
[email protected]a8e9b162009-03-12 00:06:443751
bnc691fda62016-08-12 00:43:163752 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243753 ASSERT_TRUE(response);
3754 ASSERT_TRUE(response->headers);
[email protected]a8e9b162009-03-12 00:06:443755 EXPECT_TRUE(response->headers->IsKeepAlive());
3756 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423757 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:443758
3759 std::string response_data;
bnc691fda62016-08-12 00:43:163760 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:013761 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]e60e47a2010-07-14 03:37:183762
3763 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:313764 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:443765}
3766
ttuttle7933c112015-01-06 00:55:243767// Test that we don't pass extraneous headers from the proxy's response to the
3768// caller when the proxy responds to CONNECT with 407.
bncd16676a2016-07-20 16:23:013769TEST_F(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
ttuttle7933c112015-01-06 00:55:243770 HttpRequestInfo request;
3771 request.method = "GET";
bncce36dca22015-04-21 22:11:233772 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:103773 request.traffic_annotation =
3774 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle7933c112015-01-06 00:55:243775
3776 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:493777 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
3778 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle7933c112015-01-06 00:55:243779
danakj1fd259a02016-04-16 03:17:093780 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle7933c112015-01-06 00:55:243781
bnc691fda62016-08-12 00:43:163782 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle7933c112015-01-06 00:55:243783
3784 // Since we have proxy, should try to establish tunnel.
3785 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173786 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3787 "Host: www.example.org:443\r\n"
3788 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle7933c112015-01-06 00:55:243789 };
3790
3791 // The proxy responds to the connect with a 407.
3792 MockRead data_reads[] = {
3793 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3794 MockRead("X-Foo: bar\r\n"),
3795 MockRead("Set-Cookie: foo=bar\r\n"),
3796 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3797 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233798 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
ttuttle7933c112015-01-06 00:55:243799 };
3800
Ryan Sleevib8d7ea02018-05-07 20:01:013801 StaticSocketDataProvider data(data_reads, data_writes);
ttuttle7933c112015-01-06 00:55:243802 session_deps_.socket_factory->AddSocketDataProvider(&data);
3803
3804 TestCompletionCallback callback;
3805
tfarina42834112016-09-22 13:38:203806 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013807 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle7933c112015-01-06 00:55:243808
3809 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013810 EXPECT_THAT(rv, IsOk());
ttuttle7933c112015-01-06 00:55:243811
bnc691fda62016-08-12 00:43:163812 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243813 ASSERT_TRUE(response);
3814 ASSERT_TRUE(response->headers);
3815 EXPECT_TRUE(response->headers->IsKeepAlive());
3816 EXPECT_EQ(407, response->headers->response_code());
3817 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3818 EXPECT_FALSE(response->headers->HasHeader("X-Foo"));
3819 EXPECT_FALSE(response->headers->HasHeader("Set-Cookie"));
3820
3821 std::string response_data;
bnc691fda62016-08-12 00:43:163822 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:013823 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
ttuttle7933c112015-01-06 00:55:243824
3825 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
3826 session->CloseAllConnections();
3827}
3828
[email protected]8fdbcd22010-05-05 02:54:523829// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
3830// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
bncd16676a2016-07-20 16:23:013831TEST_F(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:523832 HttpRequestInfo request;
3833 request.method = "GET";
bncce36dca22015-04-21 22:11:233834 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:103835 request.traffic_annotation =
3836 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8fdbcd22010-05-05 02:54:523837
[email protected]cb9bf6ca2011-01-28 13:15:273838 // We are using a DIRECT connection (i.e. no proxy) for this session.
danakj1fd259a02016-04-16 03:17:093839 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:163840 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:273841
[email protected]8fdbcd22010-05-05 02:54:523842 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233843 MockWrite(
3844 "GET / HTTP/1.1\r\n"
3845 "Host: www.example.org\r\n"
3846 "Connection: keep-alive\r\n\r\n"),
[email protected]8fdbcd22010-05-05 02:54:523847 };
3848
3849 MockRead data_reads1[] = {
3850 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
3851 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3852 // Large content-length -- won't matter, as connection will be reset.
3853 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063854 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:523855 };
3856
Ryan Sleevib8d7ea02018-05-07 20:01:013857 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:073858 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:523859
[email protected]49639fa2011-12-20 23:22:413860 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:523861
tfarina42834112016-09-22 13:38:203862 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013863 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8fdbcd22010-05-05 02:54:523864
3865 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013866 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
[email protected]8fdbcd22010-05-05 02:54:523867}
3868
[email protected]7a67a8152010-11-05 18:31:103869// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
3870// through a non-authenticating proxy. The request should fail with
3871// ERR_UNEXPECTED_PROXY_AUTH.
3872// Note that it is impossible to detect if an HTTP server returns a 407 through
3873// a non-authenticating proxy - there is nothing to indicate whether the
3874// response came from the proxy or the server, so it is treated as if the proxy
3875// issued the challenge.
bncd16676a2016-07-20 16:23:013876TEST_F(HttpNetworkTransactionTest, HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:273877 HttpRequestInfo request;
3878 request.method = "GET";
bncce36dca22015-04-21 22:11:233879 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:103880 request.traffic_annotation =
3881 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:273882
Ramin Halavatica8d5252018-03-12 05:33:493883 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
3884 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513885 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073886 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093887 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:103888
[email protected]7a67a8152010-11-05 18:31:103889 // Since we have proxy, should try to establish tunnel.
3890 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:173891 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3892 "Host: www.example.org:443\r\n"
3893 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103894
rsleevidb16bb02015-11-12 23:47:173895 MockWrite("GET / HTTP/1.1\r\n"
3896 "Host: www.example.org\r\n"
3897 "Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103898 };
3899
3900 MockRead data_reads1[] = {
3901 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3902
3903 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
3904 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3905 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:063906 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:103907 };
3908
Ryan Sleevib8d7ea02018-05-07 20:01:013909 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:073910 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063911 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073912 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:103913
[email protected]49639fa2011-12-20 23:22:413914 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:103915
bnc691fda62016-08-12 00:43:163916 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]7a67a8152010-11-05 18:31:103917
bnc691fda62016-08-12 00:43:163918 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013919 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a67a8152010-11-05 18:31:103920
3921 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013922 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
mmenke43758e62015-05-04 21:09:463923 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403924 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:103925 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003926 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3927 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:103928 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403929 entries, pos,
mikecirone8b85c432016-09-08 19:11:003930 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3931 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:103932}
[email protected]2df19bb2010-08-25 20:13:463933
mmenke2a1781d2015-10-07 19:25:333934// Test a proxy auth scheme that allows default credentials and a proxy server
3935// that uses non-persistent connections.
bncd16676a2016-07-20 16:23:013936TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:333937 AuthAllowsDefaultCredentialsTunnelConnectionClose) {
3938 HttpRequestInfo request;
3939 request.method = "GET";
3940 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:103941 request.traffic_annotation =
3942 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:333943
3944 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593945 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493946 ProxyResolutionService::CreateFixedFromPacResult(
3947 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:333948
Jeremy Roman0579ed62017-08-29 15:56:193949 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:333950 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:193951 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:333952 mock_handler->set_allows_default_credentials(true);
3953 auth_handler_factory->AddMockHandler(mock_handler.release(),
3954 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:483955 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:333956
3957 // Add NetLog just so can verify load timing information gets a NetLog ID.
3958 NetLog net_log;
3959 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:093960 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:333961
3962 // Since we have proxy, should try to establish tunnel.
3963 MockWrite data_writes1[] = {
3964 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173965 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333966 "Proxy-Connection: keep-alive\r\n\r\n"),
3967 };
3968
3969 // The proxy responds to the connect with a 407, using a non-persistent
3970 // connection.
3971 MockRead data_reads1[] = {
3972 // No credentials.
3973 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3974 MockRead("Proxy-Authenticate: Mock\r\n"),
3975 MockRead("Proxy-Connection: close\r\n\r\n"),
3976 };
3977
3978 // Since the first connection couldn't be reused, need to establish another
3979 // once given credentials.
3980 MockWrite data_writes2[] = {
3981 // After calling trans->RestartWithAuth(), this is the request we should
3982 // be issuing -- the final header line contains the credentials.
3983 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173984 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333985 "Proxy-Connection: keep-alive\r\n"
3986 "Proxy-Authorization: auth_token\r\n\r\n"),
3987
3988 MockWrite("GET / HTTP/1.1\r\n"
3989 "Host: www.example.org\r\n"
3990 "Connection: keep-alive\r\n\r\n"),
3991 };
3992
3993 MockRead data_reads2[] = {
3994 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3995
3996 MockRead("HTTP/1.1 200 OK\r\n"),
3997 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3998 MockRead("Content-Length: 5\r\n\r\n"),
3999 MockRead(SYNCHRONOUS, "hello"),
4000 };
4001
Ryan Sleevib8d7ea02018-05-07 20:01:014002 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke2a1781d2015-10-07 19:25:334003 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:014004 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke2a1781d2015-10-07 19:25:334005 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4006 SSLSocketDataProvider ssl(ASYNC, OK);
4007 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4008
bnc87dcefc2017-05-25 12:47:584009 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194010 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334011
4012 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204013 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014014 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334015
4016 const HttpResponseInfo* response = trans->GetResponseInfo();
4017 ASSERT_TRUE(response);
4018 ASSERT_TRUE(response->headers);
4019 EXPECT_FALSE(response->headers->IsKeepAlive());
4020 EXPECT_EQ(407, response->headers->response_code());
4021 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4022 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
wezca1070932016-05-26 20:30:524023 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:334024
4025 LoadTimingInfo load_timing_info;
4026 // CONNECT requests and responses are handled at the connect job level, so
4027 // the transaction does not yet have a connection.
4028 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4029
4030 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014031 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334032 response = trans->GetResponseInfo();
4033 ASSERT_TRUE(response);
4034 ASSERT_TRUE(response->headers);
4035 EXPECT_TRUE(response->headers->IsKeepAlive());
4036 EXPECT_EQ(200, response->headers->response_code());
4037 EXPECT_EQ(5, response->headers->GetContentLength());
4038 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4039
4040 // The password prompt info should not be set.
4041 EXPECT_FALSE(response->auth_challenge);
4042
4043 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4044 TestLoadTimingNotReusedWithPac(load_timing_info,
4045 CONNECT_TIMING_HAS_SSL_TIMES);
4046
4047 trans.reset();
4048 session->CloseAllConnections();
4049}
4050
4051// Test a proxy auth scheme that allows default credentials and a proxy server
4052// that hangs up when credentials are initially sent.
bncd16676a2016-07-20 16:23:014053TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334054 AuthAllowsDefaultCredentialsTunnelServerClosesConnection) {
4055 HttpRequestInfo request;
4056 request.method = "GET";
4057 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104058 request.traffic_annotation =
4059 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334060
4061 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594062 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494063 ProxyResolutionService::CreateFixedFromPacResult(
4064 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334065
Jeremy Roman0579ed62017-08-29 15:56:194066 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334067 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194068 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334069 mock_handler->set_allows_default_credentials(true);
4070 auth_handler_factory->AddMockHandler(mock_handler.release(),
4071 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484072 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334073
4074 // Add NetLog just so can verify load timing information gets a NetLog ID.
4075 NetLog net_log;
4076 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094077 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334078
4079 // Should try to establish tunnel.
4080 MockWrite data_writes1[] = {
4081 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174082 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334083 "Proxy-Connection: keep-alive\r\n\r\n"),
4084
4085 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174086 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334087 "Proxy-Connection: keep-alive\r\n"
4088 "Proxy-Authorization: auth_token\r\n\r\n"),
4089 };
4090
4091 // The proxy responds to the connect with a 407, using a non-persistent
4092 // connection.
4093 MockRead data_reads1[] = {
4094 // No credentials.
4095 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4096 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4097 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4098 };
4099
4100 // Since the first connection was closed, need to establish another once given
4101 // credentials.
4102 MockWrite data_writes2[] = {
4103 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174104 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334105 "Proxy-Connection: keep-alive\r\n"
4106 "Proxy-Authorization: auth_token\r\n\r\n"),
4107
4108 MockWrite("GET / HTTP/1.1\r\n"
4109 "Host: www.example.org\r\n"
4110 "Connection: keep-alive\r\n\r\n"),
4111 };
4112
4113 MockRead data_reads2[] = {
4114 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
4115
4116 MockRead("HTTP/1.1 200 OK\r\n"),
4117 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4118 MockRead("Content-Length: 5\r\n\r\n"),
4119 MockRead(SYNCHRONOUS, "hello"),
4120 };
4121
Ryan Sleevib8d7ea02018-05-07 20:01:014122 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke2a1781d2015-10-07 19:25:334123 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:014124 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke2a1781d2015-10-07 19:25:334125 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4126 SSLSocketDataProvider ssl(ASYNC, OK);
4127 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4128
bnc87dcefc2017-05-25 12:47:584129 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194130 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334131
4132 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204133 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014134 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334135
4136 const HttpResponseInfo* response = trans->GetResponseInfo();
4137 ASSERT_TRUE(response);
4138 ASSERT_TRUE(response->headers);
4139 EXPECT_TRUE(response->headers->IsKeepAlive());
4140 EXPECT_EQ(407, response->headers->response_code());
4141 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4142 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4143 EXPECT_FALSE(response->auth_challenge);
4144
4145 LoadTimingInfo load_timing_info;
4146 // CONNECT requests and responses are handled at the connect job level, so
4147 // the transaction does not yet have a connection.
4148 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4149
4150 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014151 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334152
4153 response = trans->GetResponseInfo();
4154 ASSERT_TRUE(response);
4155 ASSERT_TRUE(response->headers);
4156 EXPECT_TRUE(response->headers->IsKeepAlive());
4157 EXPECT_EQ(200, response->headers->response_code());
4158 EXPECT_EQ(5, response->headers->GetContentLength());
4159 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4160
4161 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524162 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:334163
4164 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4165 TestLoadTimingNotReusedWithPac(load_timing_info,
4166 CONNECT_TIMING_HAS_SSL_TIMES);
4167
4168 trans.reset();
4169 session->CloseAllConnections();
4170}
4171
4172// Test a proxy auth scheme that allows default credentials and a proxy server
4173// that hangs up when credentials are initially sent, and hangs up again when
4174// they are retried.
bncd16676a2016-07-20 16:23:014175TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334176 AuthAllowsDefaultCredentialsTunnelServerClosesConnectionTwice) {
4177 HttpRequestInfo request;
4178 request.method = "GET";
4179 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104180 request.traffic_annotation =
4181 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334182
4183 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594184 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494185 ProxyResolutionService::CreateFixedFromPacResult(
4186 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334187
Jeremy Roman0579ed62017-08-29 15:56:194188 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334189 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194190 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334191 mock_handler->set_allows_default_credentials(true);
4192 auth_handler_factory->AddMockHandler(mock_handler.release(),
4193 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484194 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334195
4196 // Add NetLog just so can verify load timing information gets a NetLog ID.
4197 NetLog net_log;
4198 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094199 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334200
4201 // Should try to establish tunnel.
4202 MockWrite data_writes1[] = {
4203 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174204 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334205 "Proxy-Connection: keep-alive\r\n\r\n"),
4206
4207 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174208 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334209 "Proxy-Connection: keep-alive\r\n"
4210 "Proxy-Authorization: auth_token\r\n\r\n"),
4211 };
4212
4213 // The proxy responds to the connect with a 407, and then hangs up after the
4214 // second request is sent.
4215 MockRead data_reads1[] = {
4216 // No credentials.
4217 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4218 MockRead("Content-Length: 0\r\n"),
4219 MockRead("Proxy-Connection: keep-alive\r\n"),
4220 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4221 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4222 };
4223
4224 // HttpNetworkTransaction sees a reused connection that was closed with
4225 // ERR_CONNECTION_CLOSED, realized it might have been a race, so retries the
4226 // request.
4227 MockWrite data_writes2[] = {
4228 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174229 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334230 "Proxy-Connection: keep-alive\r\n\r\n"),
4231 };
4232
4233 // The proxy, having had more than enough of us, just hangs up.
4234 MockRead data_reads2[] = {
4235 // No credentials.
4236 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4237 };
4238
Ryan Sleevib8d7ea02018-05-07 20:01:014239 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke2a1781d2015-10-07 19:25:334240 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:014241 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke2a1781d2015-10-07 19:25:334242 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4243
bnc87dcefc2017-05-25 12:47:584244 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194245 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334246
4247 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204248 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014249 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334250
4251 const HttpResponseInfo* response = trans->GetResponseInfo();
4252 ASSERT_TRUE(response);
4253 ASSERT_TRUE(response->headers);
4254 EXPECT_TRUE(response->headers->IsKeepAlive());
4255 EXPECT_EQ(407, response->headers->response_code());
4256 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4257 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4258 EXPECT_FALSE(response->auth_challenge);
4259
4260 LoadTimingInfo load_timing_info;
4261 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4262
4263 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014264 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_EMPTY_RESPONSE));
mmenke2a1781d2015-10-07 19:25:334265
4266 trans.reset();
4267 session->CloseAllConnections();
4268}
4269
4270// Test a proxy auth scheme that allows default credentials and a proxy server
4271// that hangs up when credentials are initially sent, and sends a challenge
4272// again they are retried.
bncd16676a2016-07-20 16:23:014273TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334274 AuthAllowsDefaultCredentialsTunnelServerChallengesTwice) {
4275 HttpRequestInfo request;
4276 request.method = "GET";
4277 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104278 request.traffic_annotation =
4279 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334280
4281 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594282 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494283 ProxyResolutionService::CreateFixedFromPacResult(
4284 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334285
Jeremy Roman0579ed62017-08-29 15:56:194286 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334287 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194288 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334289 mock_handler->set_allows_default_credentials(true);
4290 auth_handler_factory->AddMockHandler(mock_handler.release(),
4291 HttpAuth::AUTH_PROXY);
4292 // Add another handler for the second challenge. It supports default
4293 // credentials, but they shouldn't be used, since they were already tried.
Jeremy Roman0579ed62017-08-29 15:56:194294 mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334295 mock_handler->set_allows_default_credentials(true);
4296 auth_handler_factory->AddMockHandler(mock_handler.release(),
4297 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484298 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334299
4300 // Add NetLog just so can verify load timing information gets a NetLog ID.
4301 NetLog net_log;
4302 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094303 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334304
4305 // Should try to establish tunnel.
4306 MockWrite data_writes1[] = {
4307 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174308 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334309 "Proxy-Connection: keep-alive\r\n\r\n"),
4310 };
4311
4312 // The proxy responds to the connect with a 407, using a non-persistent
4313 // connection.
4314 MockRead data_reads1[] = {
4315 // No credentials.
4316 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4317 MockRead("Proxy-Authenticate: Mock\r\n"),
4318 MockRead("Proxy-Connection: close\r\n\r\n"),
4319 };
4320
4321 // Since the first connection was closed, need to establish another once given
4322 // credentials.
4323 MockWrite data_writes2[] = {
4324 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174325 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334326 "Proxy-Connection: keep-alive\r\n"
4327 "Proxy-Authorization: auth_token\r\n\r\n"),
4328 };
4329
4330 MockRead data_reads2[] = {
4331 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4332 MockRead("Proxy-Authenticate: Mock\r\n"),
4333 MockRead("Proxy-Connection: close\r\n\r\n"),
4334 };
4335
Ryan Sleevib8d7ea02018-05-07 20:01:014336 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke2a1781d2015-10-07 19:25:334337 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:014338 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke2a1781d2015-10-07 19:25:334339 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4340 SSLSocketDataProvider ssl(ASYNC, OK);
4341 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4342
bnc87dcefc2017-05-25 12:47:584343 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194344 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334345
4346 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204347 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014348 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334349
4350 const HttpResponseInfo* response = trans->GetResponseInfo();
4351 ASSERT_TRUE(response);
4352 ASSERT_TRUE(response->headers);
4353 EXPECT_EQ(407, response->headers->response_code());
4354 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4355 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4356 EXPECT_FALSE(response->auth_challenge);
4357
4358 LoadTimingInfo load_timing_info;
4359 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4360
4361 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014362 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334363 response = trans->GetResponseInfo();
4364 ASSERT_TRUE(response);
4365 ASSERT_TRUE(response->headers);
4366 EXPECT_EQ(407, response->headers->response_code());
4367 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4368 EXPECT_TRUE(response->auth_challenge);
4369
4370 trans.reset();
4371 session->CloseAllConnections();
4372}
4373
asankae2257db2016-10-11 22:03:164374// A more nuanced test than GenerateAuthToken test which asserts that
4375// ERR_INVALID_AUTH_CREDENTIALS does not cause the auth scheme to be
4376// unnecessarily invalidated, and that if the server co-operates, the
4377// authentication handshake can continue with the same scheme but with a
4378// different identity.
4379TEST_F(HttpNetworkTransactionTest, NonPermanentGenerateAuthTokenError) {
4380 HttpRequestInfo request;
4381 request.method = "GET";
4382 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104383 request.traffic_annotation =
4384 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
asankae2257db2016-10-11 22:03:164385
Jeremy Roman0579ed62017-08-29 15:56:194386 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
asankae2257db2016-10-11 22:03:164387 auth_handler_factory->set_do_init_from_challenge(true);
4388
4389 // First handler. Uses default credentials, but barfs at generate auth token.
Jeremy Roman0579ed62017-08-29 15:56:194390 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164391 mock_handler->set_allows_default_credentials(true);
4392 mock_handler->set_allows_explicit_credentials(true);
4393 mock_handler->set_connection_based(true);
4394 mock_handler->SetGenerateExpectation(true, ERR_INVALID_AUTH_CREDENTIALS);
4395 auth_handler_factory->AddMockHandler(mock_handler.release(),
4396 HttpAuth::AUTH_SERVER);
4397
4398 // Add another handler for the second challenge. It supports default
4399 // credentials, but they shouldn't be used, since they were already tried.
Jeremy Roman0579ed62017-08-29 15:56:194400 mock_handler = std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164401 mock_handler->set_allows_default_credentials(true);
4402 mock_handler->set_allows_explicit_credentials(true);
4403 mock_handler->set_connection_based(true);
4404 auth_handler_factory->AddMockHandler(mock_handler.release(),
4405 HttpAuth::AUTH_SERVER);
4406 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
4407
4408 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4409
4410 MockWrite data_writes1[] = {
4411 MockWrite("GET / HTTP/1.1\r\n"
4412 "Host: www.example.org\r\n"
4413 "Connection: keep-alive\r\n\r\n"),
4414 };
4415
4416 MockRead data_reads1[] = {
4417 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4418 "WWW-Authenticate: Mock\r\n"
4419 "Connection: keep-alive\r\n\r\n"),
4420 };
4421
4422 // Identical to data_writes1[]. The AuthHandler encounters a
4423 // ERR_INVALID_AUTH_CREDENTIALS during the GenerateAuthToken stage, so the
4424 // transaction procceds without an authorization header.
4425 MockWrite data_writes2[] = {
4426 MockWrite("GET / HTTP/1.1\r\n"
4427 "Host: www.example.org\r\n"
4428 "Connection: keep-alive\r\n\r\n"),
4429 };
4430
4431 MockRead data_reads2[] = {
4432 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4433 "WWW-Authenticate: Mock\r\n"
4434 "Connection: keep-alive\r\n\r\n"),
4435 };
4436
4437 MockWrite data_writes3[] = {
4438 MockWrite("GET / HTTP/1.1\r\n"
4439 "Host: www.example.org\r\n"
4440 "Connection: keep-alive\r\n"
4441 "Authorization: auth_token\r\n\r\n"),
4442 };
4443
4444 MockRead data_reads3[] = {
4445 MockRead("HTTP/1.1 200 OK\r\n"
4446 "Content-Length: 5\r\n"
4447 "Content-Type: text/plain\r\n"
4448 "Connection: keep-alive\r\n\r\n"
4449 "Hello"),
4450 };
4451
Ryan Sleevib8d7ea02018-05-07 20:01:014452 StaticSocketDataProvider data1(data_reads1, data_writes1);
asankae2257db2016-10-11 22:03:164453 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4454
Ryan Sleevib8d7ea02018-05-07 20:01:014455 StaticSocketDataProvider data2(data_reads2, data_writes2);
asankae2257db2016-10-11 22:03:164456 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4457
Ryan Sleevib8d7ea02018-05-07 20:01:014458 StaticSocketDataProvider data3(data_reads3, data_writes3);
asankae2257db2016-10-11 22:03:164459 session_deps_.socket_factory->AddSocketDataProvider(&data3);
4460
bnc87dcefc2017-05-25 12:47:584461 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194462 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
asankae2257db2016-10-11 22:03:164463
4464 TestCompletionCallback callback;
4465 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4466 EXPECT_THAT(callback.GetResult(rv), IsOk());
4467
4468 const HttpResponseInfo* response = trans->GetResponseInfo();
4469 ASSERT_TRUE(response);
4470 ASSERT_TRUE(response->headers);
4471 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4472
4473 // The following three tests assert that an authentication challenge was
4474 // received and that the stack is ready to respond to the challenge using
4475 // ambient credentials.
4476 EXPECT_EQ(401, response->headers->response_code());
4477 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4478 EXPECT_FALSE(response->auth_challenge);
4479
4480 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4481 EXPECT_THAT(callback.GetResult(rv), IsOk());
4482 response = trans->GetResponseInfo();
4483 ASSERT_TRUE(response);
4484 ASSERT_TRUE(response->headers);
4485
4486 // The following three tests assert that an authentication challenge was
4487 // received and that the stack needs explicit credentials before it is ready
4488 // to respond to the challenge.
4489 EXPECT_EQ(401, response->headers->response_code());
4490 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4491 EXPECT_TRUE(response->auth_challenge);
4492
4493 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4494 EXPECT_THAT(callback.GetResult(rv), IsOk());
4495 response = trans->GetResponseInfo();
4496 ASSERT_TRUE(response);
4497 ASSERT_TRUE(response->headers);
4498 EXPECT_EQ(200, response->headers->response_code());
4499
4500 trans.reset();
4501 session->CloseAllConnections();
4502}
4503
Matt Menked1eb6d42018-01-17 04:54:064504// Proxy resolver that returns a proxy with the same host and port for different
4505// schemes, based on the path of the URL being requests.
4506class SameProxyWithDifferentSchemesProxyResolver : public ProxyResolver {
4507 public:
4508 SameProxyWithDifferentSchemesProxyResolver() {}
4509 ~SameProxyWithDifferentSchemesProxyResolver() override {}
4510
4511 static std::string ProxyHostPortPairAsString() { return "proxy.test:10000"; }
4512
4513 static HostPortPair ProxyHostPortPair() {
4514 return HostPortPair::FromString(ProxyHostPortPairAsString());
4515 }
4516
4517 // ProxyResolver implementation.
4518 int GetProxyForURL(const GURL& url,
4519 ProxyInfo* results,
Bence Békycc5b88a2018-05-25 20:24:174520 CompletionOnceCallback callback,
Matt Menked1eb6d42018-01-17 04:54:064521 std::unique_ptr<Request>* request,
4522 const NetLogWithSource& /*net_log*/) override {
4523 *results = ProxyInfo();
Ramin Halavati921731ea2018-03-16 08:24:574524 results->set_traffic_annotation(
4525 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
Matt Menked1eb6d42018-01-17 04:54:064526 if (url.path() == "/socks4") {
4527 results->UsePacString("SOCKS " + ProxyHostPortPairAsString());
4528 return OK;
4529 }
4530 if (url.path() == "/socks5") {
4531 results->UsePacString("SOCKS5 " + ProxyHostPortPairAsString());
4532 return OK;
4533 }
4534 if (url.path() == "/http") {
4535 results->UsePacString("PROXY " + ProxyHostPortPairAsString());
4536 return OK;
4537 }
4538 if (url.path() == "/https") {
4539 results->UsePacString("HTTPS " + ProxyHostPortPairAsString());
4540 return OK;
4541 }
4542 NOTREACHED();
4543 return ERR_NOT_IMPLEMENTED;
4544 }
4545
4546 private:
4547 DISALLOW_COPY_AND_ASSIGN(SameProxyWithDifferentSchemesProxyResolver);
4548};
4549
4550class SameProxyWithDifferentSchemesProxyResolverFactory
4551 : public ProxyResolverFactory {
4552 public:
4553 SameProxyWithDifferentSchemesProxyResolverFactory()
4554 : ProxyResolverFactory(false) {}
4555
Lily Houghton99597862018-03-07 16:40:424556 int CreateProxyResolver(const scoped_refptr<PacFileData>& pac_script,
4557 std::unique_ptr<ProxyResolver>* resolver,
Bence Békycc5b88a2018-05-25 20:24:174558 CompletionOnceCallback callback,
Lily Houghton99597862018-03-07 16:40:424559 std::unique_ptr<Request>* request) override {
Matt Menked1eb6d42018-01-17 04:54:064560 *resolver = std::make_unique<SameProxyWithDifferentSchemesProxyResolver>();
4561 return OK;
4562 }
4563
4564 private:
4565 DISALLOW_COPY_AND_ASSIGN(SameProxyWithDifferentSchemesProxyResolverFactory);
4566};
4567
4568// Check that when different proxy schemes are all applied to a proxy at the
4569// same address, the sonnections are not grouped together. i.e., a request to
4570// foo.com using proxy.com as an HTTPS proxy won't use the same socket as a
4571// request to foo.com using proxy.com as an HTTP proxy.
4572TEST_F(HttpNetworkTransactionTest, SameDestinationForDifferentProxyTypes) {
Ramin Halavatica8d5252018-03-12 05:33:494573 session_deps_.proxy_resolution_service =
4574 std::make_unique<ProxyResolutionService>(
4575 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
4576 ProxyConfig::CreateAutoDetect(), TRAFFIC_ANNOTATION_FOR_TESTS)),
4577 std::make_unique<SameProxyWithDifferentSchemesProxyResolverFactory>(),
4578 nullptr);
Matt Menked1eb6d42018-01-17 04:54:064579
4580 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4581
4582 MockWrite socks_writes[] = {
4583 MockWrite(SYNCHRONOUS, kSOCKS4OkRequestLocalHostPort80,
4584 kSOCKS4OkRequestLocalHostPort80Length),
4585 MockWrite(SYNCHRONOUS,
4586 "GET /socks4 HTTP/1.1\r\n"
4587 "Host: test\r\n"
4588 "Connection: keep-alive\r\n\r\n"),
4589 };
4590 MockRead socks_reads[] = {
4591 MockRead(SYNCHRONOUS, kSOCKS4OkReply, kSOCKS4OkReplyLength),
4592 MockRead("HTTP/1.0 200 OK\r\n"
4593 "Connection: keep-alive\r\n"
4594 "Content-Length: 15\r\n\r\n"
4595 "SOCKS4 Response"),
4596 };
Ryan Sleevib8d7ea02018-05-07 20:01:014597 StaticSocketDataProvider socks_data(socks_reads, socks_writes);
Matt Menked1eb6d42018-01-17 04:54:064598 session_deps_.socket_factory->AddSocketDataProvider(&socks_data);
4599
4600 const char kSOCKS5Request[] = {
4601 0x05, // Version
4602 0x01, // Command (CONNECT)
4603 0x00, // Reserved
4604 0x03, // Address type (DOMAINNAME)
4605 0x04, // Length of domain (4)
4606 't', 'e', 's', 't', // Domain string
4607 0x00, 0x50, // 16-bit port (80)
4608 };
4609 MockWrite socks5_writes[] = {
4610 MockWrite(ASYNC, kSOCKS5GreetRequest, kSOCKS5GreetRequestLength),
4611 MockWrite(ASYNC, kSOCKS5Request, arraysize(kSOCKS5Request)),
4612 MockWrite(SYNCHRONOUS,
4613 "GET /socks5 HTTP/1.1\r\n"
4614 "Host: test\r\n"
4615 "Connection: keep-alive\r\n\r\n"),
4616 };
4617 MockRead socks5_reads[] = {
4618 MockRead(ASYNC, kSOCKS5GreetResponse, kSOCKS5GreetResponseLength),
4619 MockRead(ASYNC, kSOCKS5OkResponse, kSOCKS5OkResponseLength),
4620 MockRead("HTTP/1.0 200 OK\r\n"
4621 "Connection: keep-alive\r\n"
4622 "Content-Length: 15\r\n\r\n"
4623 "SOCKS5 Response"),
4624 };
Ryan Sleevib8d7ea02018-05-07 20:01:014625 StaticSocketDataProvider socks5_data(socks5_reads, socks5_writes);
Matt Menked1eb6d42018-01-17 04:54:064626 session_deps_.socket_factory->AddSocketDataProvider(&socks5_data);
4627
4628 MockWrite http_writes[] = {
4629 MockWrite(SYNCHRONOUS,
4630 "GET http://test/http HTTP/1.1\r\n"
4631 "Host: test\r\n"
4632 "Proxy-Connection: keep-alive\r\n\r\n"),
4633 };
4634 MockRead http_reads[] = {
4635 MockRead("HTTP/1.1 200 OK\r\n"
4636 "Proxy-Connection: keep-alive\r\n"
4637 "Content-Length: 13\r\n\r\n"
4638 "HTTP Response"),
4639 };
Ryan Sleevib8d7ea02018-05-07 20:01:014640 StaticSocketDataProvider http_data(http_reads, http_writes);
Matt Menked1eb6d42018-01-17 04:54:064641 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
4642
4643 MockWrite https_writes[] = {
4644 MockWrite(SYNCHRONOUS,
4645 "GET http://test/https HTTP/1.1\r\n"
4646 "Host: test\r\n"
4647 "Proxy-Connection: keep-alive\r\n\r\n"),
4648 };
4649 MockRead https_reads[] = {
4650 MockRead("HTTP/1.1 200 OK\r\n"
4651 "Proxy-Connection: keep-alive\r\n"
4652 "Content-Length: 14\r\n\r\n"
4653 "HTTPS Response"),
4654 };
Ryan Sleevib8d7ea02018-05-07 20:01:014655 StaticSocketDataProvider https_data(https_reads, https_writes);
Matt Menked1eb6d42018-01-17 04:54:064656 session_deps_.socket_factory->AddSocketDataProvider(&https_data);
4657 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
4658 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4659
4660 struct TestCase {
4661 GURL url;
4662 std::string expected_response;
4663 // How many idle sockets there should be in the SOCKS proxy socket pool
4664 // after the test.
4665 int expected_idle_socks_sockets;
4666 // How many idle sockets there should be in the HTTP proxy socket pool after
4667 // the test.
4668 int expected_idle_http_sockets;
4669 } const kTestCases[] = {
4670 {GURL("http://test/socks4"), "SOCKS4 Response", 1, 0},
4671 {GURL("http://test/socks5"), "SOCKS5 Response", 2, 0},
4672 {GURL("http://test/http"), "HTTP Response", 2, 1},
4673 {GURL("http://test/https"), "HTTPS Response", 2, 2},
4674 };
4675
4676 for (const auto& test_case : kTestCases) {
4677 HttpRequestInfo request;
4678 request.method = "GET";
4679 request.url = test_case.url;
Ramin Halavatib5e433e62018-02-07 07:41:104680 request.traffic_annotation =
4681 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Matt Menked1eb6d42018-01-17 04:54:064682 std::unique_ptr<HttpNetworkTransaction> trans =
4683 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
4684 session.get());
4685 TestCompletionCallback callback;
4686 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4687 EXPECT_THAT(callback.GetResult(rv), IsOk());
4688
4689 const HttpResponseInfo* response = trans->GetResponseInfo();
4690 ASSERT_TRUE(response);
4691 ASSERT_TRUE(response->headers);
4692 EXPECT_EQ(200, response->headers->response_code());
4693 std::string response_data;
4694 EXPECT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
4695 EXPECT_EQ(test_case.expected_response, response_data);
4696
4697 // Return the socket to the socket pool, so can make sure it's not used for
4698 // the next requests.
4699 trans.reset();
4700 base::RunLoop().RunUntilIdle();
4701
4702 // Check the number of idle sockets in the pool, to make sure that used
4703 // sockets are indeed being returned to the socket pool. If each request
4704 // doesn't return an idle socket to the pool, the test would incorrectly
4705 // pass.
4706 EXPECT_EQ(
4707 test_case.expected_idle_socks_sockets,
4708 session
4709 ->GetSocketPoolForSOCKSProxy(
4710 HttpNetworkSession::NORMAL_SOCKET_POOL,
4711 SameProxyWithDifferentSchemesProxyResolver::ProxyHostPortPair())
4712 ->IdleSocketCount());
4713 EXPECT_EQ(
4714 test_case.expected_idle_http_sockets,
4715 session
4716 ->GetSocketPoolForHTTPProxy(
4717 HttpNetworkSession::NORMAL_SOCKET_POOL,
4718 SameProxyWithDifferentSchemesProxyResolver::ProxyHostPortPair())
4719 ->IdleSocketCount());
4720 }
4721}
4722
[email protected]029c83b62013-01-24 05:28:204723// Test the load timing for HTTPS requests with an HTTP proxy.
bncd16676a2016-07-20 16:23:014724TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:204725 HttpRequestInfo request1;
4726 request1.method = "GET";
bncce36dca22015-04-21 22:11:234727 request1.url = GURL("https://www.example.org/1");
Ramin Halavatib5e433e62018-02-07 07:41:104728 request1.traffic_annotation =
4729 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:204730
4731 HttpRequestInfo request2;
4732 request2.method = "GET";
bncce36dca22015-04-21 22:11:234733 request2.url = GURL("https://www.example.org/2");
Ramin Halavatib5e433e62018-02-07 07:41:104734 request2.traffic_annotation =
4735 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:204736
4737 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:494738 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
4739 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:514740 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074741 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094742 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:204743
4744 // Since we have proxy, should try to establish tunnel.
4745 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174746 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4747 "Host: www.example.org:443\r\n"
4748 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204749
rsleevidb16bb02015-11-12 23:47:174750 MockWrite("GET /1 HTTP/1.1\r\n"
4751 "Host: www.example.org\r\n"
4752 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204753
rsleevidb16bb02015-11-12 23:47:174754 MockWrite("GET /2 HTTP/1.1\r\n"
4755 "Host: www.example.org\r\n"
4756 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204757 };
4758
4759 // The proxy responds to the connect with a 407, using a persistent
4760 // connection.
4761 MockRead data_reads1[] = {
4762 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4763
4764 MockRead("HTTP/1.1 200 OK\r\n"),
4765 MockRead("Content-Length: 1\r\n\r\n"),
4766 MockRead(SYNCHRONOUS, "1"),
4767
4768 MockRead("HTTP/1.1 200 OK\r\n"),
4769 MockRead("Content-Length: 2\r\n\r\n"),
4770 MockRead(SYNCHRONOUS, "22"),
4771 };
4772
Ryan Sleevib8d7ea02018-05-07 20:01:014773 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:074774 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:204775 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074776 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:204777
4778 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:584779 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:194780 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204781
4782 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014783 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204784
4785 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014786 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204787
4788 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:524789 ASSERT_TRUE(response1);
tbansal2ecbbc72016-10-06 17:15:474790 EXPECT_TRUE(response1->proxy_server.is_http());
wezca1070932016-05-26 20:30:524791 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:204792 EXPECT_EQ(1, response1->headers->GetContentLength());
4793
4794 LoadTimingInfo load_timing_info1;
4795 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4796 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
4797
4798 trans1.reset();
4799
4800 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:584801 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:194802 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204803
4804 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014805 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204806
4807 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:014808 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204809
4810 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:524811 ASSERT_TRUE(response2);
tbansal2ecbbc72016-10-06 17:15:474812 EXPECT_TRUE(response2->proxy_server.is_http());
wezca1070932016-05-26 20:30:524813 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:204814 EXPECT_EQ(2, response2->headers->GetContentLength());
4815
4816 LoadTimingInfo load_timing_info2;
4817 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4818 TestLoadTimingReused(load_timing_info2);
4819
4820 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
4821
4822 trans2.reset();
4823 session->CloseAllConnections();
4824}
4825
4826// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
bncd16676a2016-07-20 16:23:014827TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:204828 HttpRequestInfo request1;
4829 request1.method = "GET";
bncce36dca22015-04-21 22:11:234830 request1.url = GURL("https://www.example.org/1");
Ramin Halavatib5e433e62018-02-07 07:41:104831 request1.traffic_annotation =
4832 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:204833
4834 HttpRequestInfo request2;
4835 request2.method = "GET";
bncce36dca22015-04-21 22:11:234836 request2.url = GURL("https://www.example.org/2");
Ramin Halavatib5e433e62018-02-07 07:41:104837 request2.traffic_annotation =
4838 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:204839
4840 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594841 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494842 ProxyResolutionService::CreateFixedFromPacResult(
4843 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:514844 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074845 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094846 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:204847
4848 // Since we have proxy, should try to establish tunnel.
4849 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174850 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4851 "Host: www.example.org:443\r\n"
4852 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204853
rsleevidb16bb02015-11-12 23:47:174854 MockWrite("GET /1 HTTP/1.1\r\n"
4855 "Host: www.example.org\r\n"
4856 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204857
rsleevidb16bb02015-11-12 23:47:174858 MockWrite("GET /2 HTTP/1.1\r\n"
4859 "Host: www.example.org\r\n"
4860 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204861 };
4862
4863 // The proxy responds to the connect with a 407, using a persistent
4864 // connection.
4865 MockRead data_reads1[] = {
4866 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4867
4868 MockRead("HTTP/1.1 200 OK\r\n"),
4869 MockRead("Content-Length: 1\r\n\r\n"),
4870 MockRead(SYNCHRONOUS, "1"),
4871
4872 MockRead("HTTP/1.1 200 OK\r\n"),
4873 MockRead("Content-Length: 2\r\n\r\n"),
4874 MockRead(SYNCHRONOUS, "22"),
4875 };
4876
Ryan Sleevib8d7ea02018-05-07 20:01:014877 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:074878 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:204879 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074880 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:204881
4882 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:584883 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:194884 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204885
4886 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014887 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204888
4889 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014890 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204891
4892 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:524893 ASSERT_TRUE(response1);
4894 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:204895 EXPECT_EQ(1, response1->headers->GetContentLength());
4896
4897 LoadTimingInfo load_timing_info1;
4898 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4899 TestLoadTimingNotReusedWithPac(load_timing_info1,
4900 CONNECT_TIMING_HAS_SSL_TIMES);
4901
4902 trans1.reset();
4903
4904 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:584905 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:194906 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204907
4908 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014909 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204910
4911 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:014912 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204913
4914 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:524915 ASSERT_TRUE(response2);
4916 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:204917 EXPECT_EQ(2, response2->headers->GetContentLength());
4918
4919 LoadTimingInfo load_timing_info2;
4920 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4921 TestLoadTimingReusedWithPac(load_timing_info2);
4922
4923 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
4924
4925 trans2.reset();
4926 session->CloseAllConnections();
4927}
4928
[email protected]2df19bb2010-08-25 20:13:464929// Test a simple get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:014930TEST_F(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:274931 HttpRequestInfo request;
4932 request.method = "GET";
bncce36dca22015-04-21 22:11:234933 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104934 request.traffic_annotation =
4935 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:274936
[email protected]2df19bb2010-08-25 20:13:464937 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:494938 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
4939 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:514940 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074941 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094942 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:464943
[email protected]2df19bb2010-08-25 20:13:464944 // Since we have proxy, should use full url
4945 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:234946 MockWrite(
4947 "GET http://www.example.org/ HTTP/1.1\r\n"
4948 "Host: www.example.org\r\n"
4949 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:464950 };
4951
4952 MockRead data_reads1[] = {
4953 MockRead("HTTP/1.1 200 OK\r\n"),
4954 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4955 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064956 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:464957 };
4958
Ryan Sleevib8d7ea02018-05-07 20:01:014959 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:074960 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:064961 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074962 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:464963
[email protected]49639fa2011-12-20 23:22:414964 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:464965
bnc691fda62016-08-12 00:43:164966 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:504967
bnc691fda62016-08-12 00:43:164968 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014969 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:464970
4971 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014972 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:464973
[email protected]58e32bb2013-01-21 18:23:254974 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:164975 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:254976 TestLoadTimingNotReused(load_timing_info,
4977 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4978
bnc691fda62016-08-12 00:43:164979 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:524980 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:464981
tbansal2ecbbc72016-10-06 17:15:474982 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:464983 EXPECT_TRUE(response->headers->IsKeepAlive());
4984 EXPECT_EQ(200, response->headers->response_code());
4985 EXPECT_EQ(100, response->headers->GetContentLength());
4986 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4987
4988 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524989 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:464990}
4991
[email protected]7642b5ae2010-09-01 20:55:174992// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:014993TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:274994 HttpRequestInfo request;
4995 request.method = "GET";
bncce36dca22015-04-21 22:11:234996 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104997 request.traffic_annotation =
4998 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:274999
[email protected]7642b5ae2010-09-01 20:55:175000 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495001 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5002 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515003 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075004 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095005 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:175006
bncce36dca22015-04-21 22:11:235007 // fetch http://www.example.org/ via SPDY
Ryan Hamilton0239aac2018-05-19 00:03:135008 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:455009 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415010 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]7642b5ae2010-09-01 20:55:175011
Ryan Hamilton0239aac2018-05-19 00:03:135012 spdy::SpdySerializedFrame resp(
5013 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
5014 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:175015 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415016 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]7642b5ae2010-09-01 20:55:175017 };
5018
Ryan Sleevib8d7ea02018-05-07 20:01:015019 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075020 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:175021
[email protected]8ddf8322012-02-23 18:08:065022 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365023 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075024 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:175025
[email protected]49639fa2011-12-20 23:22:415026 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:175027
bnc691fda62016-08-12 00:43:165028 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505029
bnc691fda62016-08-12 00:43:165030 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015031 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7642b5ae2010-09-01 20:55:175032
5033 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015034 EXPECT_THAT(rv, IsOk());
[email protected]7642b5ae2010-09-01 20:55:175035
[email protected]58e32bb2013-01-21 18:23:255036 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165037 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255038 TestLoadTimingNotReused(load_timing_info,
5039 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5040
bnc691fda62016-08-12 00:43:165041 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525042 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:475043 EXPECT_TRUE(response->proxy_server.is_https());
wezca1070932016-05-26 20:30:525044 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025045 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]7642b5ae2010-09-01 20:55:175046
5047 std::string response_data;
bnc691fda62016-08-12 00:43:165048 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235049 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:175050}
5051
[email protected]1c173852014-06-19 12:51:505052// Verifies that a session which races and wins against the owning transaction
5053// (completing prior to host resolution), doesn't fail the transaction.
5054// Regression test for crbug.com/334413.
bncd16676a2016-07-20 16:23:015055TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
[email protected]1c173852014-06-19 12:51:505056 HttpRequestInfo request;
5057 request.method = "GET";
bncce36dca22015-04-21 22:11:235058 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105059 request.traffic_annotation =
5060 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c173852014-06-19 12:51:505061
5062 // Configure SPDY proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495063 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5064 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515065 BoundTestNetLog log;
[email protected]1c173852014-06-19 12:51:505066 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095067 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1c173852014-06-19 12:51:505068
bncce36dca22015-04-21 22:11:235069 // Fetch http://www.example.org/ through the SPDY proxy.
Ryan Hamilton0239aac2018-05-19 00:03:135070 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:455071 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415072 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]1c173852014-06-19 12:51:505073
Ryan Hamilton0239aac2018-05-19 00:03:135074 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
5075 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]1c173852014-06-19 12:51:505076 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415077 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]1c173852014-06-19 12:51:505078 };
5079
Ryan Sleevib8d7ea02018-05-07 20:01:015080 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]1c173852014-06-19 12:51:505081 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
5082
5083 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365084 ssl.next_proto = kProtoHTTP2;
[email protected]1c173852014-06-19 12:51:505085 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5086
5087 TestCompletionCallback callback1;
5088
bnc691fda62016-08-12 00:43:165089 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1c173852014-06-19 12:51:505090
5091 // Stall the hostname resolution begun by the transaction.
[email protected]1c173852014-06-19 12:51:505092 session_deps_.host_resolver->set_ondemand_mode(true);
5093
bnc691fda62016-08-12 00:43:165094 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015095 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c173852014-06-19 12:51:505096
5097 // Race a session to the proxy, which completes first.
5098 session_deps_.host_resolver->set_ondemand_mode(false);
Paul Jensena457017a2018-01-19 23:52:045099 SpdySessionKey key(HostPortPair("proxy", 70), ProxyServer::Direct(),
5100 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]1c173852014-06-19 12:51:505101 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:525102 CreateSpdySession(session.get(), key, log.bound());
[email protected]1c173852014-06-19 12:51:505103
5104 // Unstall the resolution begun by the transaction.
5105 session_deps_.host_resolver->set_ondemand_mode(true);
5106 session_deps_.host_resolver->ResolveAllPending();
5107
5108 EXPECT_FALSE(callback1.have_result());
5109 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015110 EXPECT_THAT(rv, IsOk());
[email protected]1c173852014-06-19 12:51:505111
bnc691fda62016-08-12 00:43:165112 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525113 ASSERT_TRUE(response);
5114 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025115 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]1c173852014-06-19 12:51:505116
5117 std::string response_data;
bnc691fda62016-08-12 00:43:165118 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]1c173852014-06-19 12:51:505119 EXPECT_EQ(kUploadData, response_data);
5120}
5121
[email protected]dc7bd1c52010-11-12 00:01:135122// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015123TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:275124 HttpRequestInfo request;
5125 request.method = "GET";
bncce36dca22015-04-21 22:11:235126 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105127 request.traffic_annotation =
5128 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275129
[email protected]79cb5c12011-09-12 13:12:045130 // Configure against https proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495131 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5132 "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515133 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075134 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095135 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:135136
[email protected]dc7bd1c52010-11-12 00:01:135137 // The first request will be a bare GET, the second request will be a
5138 // GET with a Proxy-Authorization header.
bncb26024382016-06-29 02:39:455139 spdy_util_.set_default_url(request.url);
Ryan Hamilton0239aac2018-05-19 00:03:135140 spdy::SpdySerializedFrame req_get(
Bence Béky27ad0a12018-02-08 00:35:485141 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:385142 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]dc7bd1c52010-11-12 00:01:135143 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:465144 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:135145 };
Ryan Hamilton0239aac2018-05-19 00:03:135146 spdy::SpdySerializedFrame req_get_authorization(spdy_util_.ConstructSpdyGet(
bncdf80d44fd2016-07-15 20:27:415147 kExtraAuthorizationHeaders, arraysize(kExtraAuthorizationHeaders) / 2, 3,
Bence Béky27ad0a12018-02-08 00:35:485148 LOWEST));
[email protected]dc7bd1c52010-11-12 00:01:135149 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415150 CreateMockWrite(req_get, 0), CreateMockWrite(req_get_authorization, 3),
[email protected]dc7bd1c52010-11-12 00:01:135151 };
5152
5153 // The first response is a 407 proxy authentication challenge, and the second
5154 // response will be a 200 response since the second request includes a valid
5155 // Authorization header.
5156 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:465157 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:135158 };
Ryan Hamilton0239aac2018-05-19 00:03:135159 spdy::SpdySerializedFrame resp_authentication(
5160 spdy_util_.ConstructSpdyReplyError(
5161 "407", kExtraAuthenticationHeaders,
5162 arraysize(kExtraAuthenticationHeaders) / 2, 1));
5163 spdy::SpdySerializedFrame body_authentication(
bncdf80d44fd2016-07-15 20:27:415164 spdy_util_.ConstructSpdyDataFrame(1, true));
Ryan Hamilton0239aac2018-05-19 00:03:135165 spdy::SpdySerializedFrame resp_data(
5166 spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
5167 spdy::SpdySerializedFrame body_data(
5168 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:135169 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415170 CreateMockRead(resp_authentication, 1),
bnceb9aa7112017-01-05 01:03:465171 CreateMockRead(body_authentication, 2, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415172 CreateMockRead(resp_data, 4),
5173 CreateMockRead(body_data, 5),
rch8e6c6c42015-05-01 14:05:135174 MockRead(ASYNC, 0, 6),
[email protected]dc7bd1c52010-11-12 00:01:135175 };
5176
Ryan Sleevib8d7ea02018-05-07 20:01:015177 SequencedSocketData data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075178 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:135179
[email protected]8ddf8322012-02-23 18:08:065180 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365181 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075182 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:135183
[email protected]49639fa2011-12-20 23:22:415184 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:135185
bnc691fda62016-08-12 00:43:165186 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]dc7bd1c52010-11-12 00:01:135187
bnc691fda62016-08-12 00:43:165188 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015189 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:135190
5191 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015192 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:135193
bnc691fda62016-08-12 00:43:165194 const HttpResponseInfo* const response = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:135195
wezca1070932016-05-26 20:30:525196 ASSERT_TRUE(response);
5197 ASSERT_TRUE(response->headers);
[email protected]dc7bd1c52010-11-12 00:01:135198 EXPECT_EQ(407, response->headers->response_code());
5199 EXPECT_TRUE(response->was_fetched_via_spdy);
asanka098c0092016-06-16 20:18:435200 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:135201
[email protected]49639fa2011-12-20 23:22:415202 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:135203
bnc691fda62016-08-12 00:43:165204 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015205 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:135206
5207 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015208 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:135209
bnc691fda62016-08-12 00:43:165210 const HttpResponseInfo* const response_restart = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:135211
wezca1070932016-05-26 20:30:525212 ASSERT_TRUE(response_restart);
5213 ASSERT_TRUE(response_restart->headers);
[email protected]dc7bd1c52010-11-12 00:01:135214 EXPECT_EQ(200, response_restart->headers->response_code());
5215 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525216 EXPECT_FALSE(response_restart->auth_challenge);
[email protected]dc7bd1c52010-11-12 00:01:135217}
5218
[email protected]d9da5fe2010-10-13 22:37:165219// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
bncd16676a2016-07-20 16:23:015220TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:275221 HttpRequestInfo request;
5222 request.method = "GET";
bncce36dca22015-04-21 22:11:235223 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105224 request.traffic_annotation =
5225 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275226
[email protected]d9da5fe2010-10-13 22:37:165227 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495228 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5229 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515230 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075231 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095232 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165233
bnc691fda62016-08-12 00:43:165234 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165235
bncce36dca22015-04-21 22:11:235236 // CONNECT to www.example.org:443 via SPDY
Ryan Hamilton0239aac2018-05-19 00:03:135237 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235238 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
5239 // fetch https://www.example.org/ via HTTP
[email protected]d9da5fe2010-10-13 22:37:165240
bncce36dca22015-04-21 22:11:235241 const char get[] =
5242 "GET / HTTP/1.1\r\n"
5243 "Host: www.example.org\r\n"
5244 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:135245 spdy::SpdySerializedFrame wrapped_get(
Bence Békyd74f4382018-02-20 18:26:195246 spdy_util_.ConstructSpdyDataFrame(1, get, false));
Ryan Hamilton0239aac2018-05-19 00:03:135247 spdy::SpdySerializedFrame conn_resp(
5248 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:165249 const char resp[] = "HTTP/1.1 200 OK\r\n"
5250 "Content-Length: 10\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:135251 spdy::SpdySerializedFrame wrapped_get_resp(
Bence Békyd74f4382018-02-20 18:26:195252 spdy_util_.ConstructSpdyDataFrame(1, resp, false));
Ryan Hamilton0239aac2018-05-19 00:03:135253 spdy::SpdySerializedFrame wrapped_body(
Bence Békyd74f4382018-02-20 18:26:195254 spdy_util_.ConstructSpdyDataFrame(1, "1234567890", false));
Ryan Hamilton0239aac2018-05-19 00:03:135255 spdy::SpdySerializedFrame window_update(
bncdf80d44fd2016-07-15 20:27:415256 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
[email protected]8d2f7012012-02-16 00:08:045257
5258 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415259 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
5260 CreateMockWrite(window_update, 6),
[email protected]8d2f7012012-02-16 00:08:045261 };
5262
[email protected]d9da5fe2010-10-13 22:37:165263 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415264 CreateMockRead(conn_resp, 1, ASYNC),
5265 CreateMockRead(wrapped_get_resp, 3, ASYNC),
5266 CreateMockRead(wrapped_body, 4, ASYNC),
5267 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:135268 MockRead(ASYNC, 0, 7),
[email protected]d9da5fe2010-10-13 22:37:165269 };
5270
Ryan Sleevib8d7ea02018-05-07 20:01:015271 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075272 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165273
[email protected]8ddf8322012-02-23 18:08:065274 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365275 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075276 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065277 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075278 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165279
[email protected]49639fa2011-12-20 23:22:415280 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165281
bnc691fda62016-08-12 00:43:165282 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015283 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165284
5285 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015286 ASSERT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:165287
[email protected]58e32bb2013-01-21 18:23:255288 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165289 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255290 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5291
bnc691fda62016-08-12 00:43:165292 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525293 ASSERT_TRUE(response);
5294 ASSERT_TRUE(response->headers);
[email protected]d9da5fe2010-10-13 22:37:165295 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5296
5297 std::string response_data;
bnc691fda62016-08-12 00:43:165298 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]d9da5fe2010-10-13 22:37:165299 EXPECT_EQ("1234567890", response_data);
5300}
5301
5302// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
bncd16676a2016-07-20 16:23:015303TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
5304 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:385305
[email protected]cb9bf6ca2011-01-28 13:15:275306 HttpRequestInfo request;
5307 request.method = "GET";
bncce36dca22015-04-21 22:11:235308 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105309 request.traffic_annotation =
5310 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275311
[email protected]d9da5fe2010-10-13 22:37:165312 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495313 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5314 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515315 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075316 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095317 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165318
bnc691fda62016-08-12 00:43:165319 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165320
bncce36dca22015-04-21 22:11:235321 // CONNECT to www.example.org:443 via SPDY
Ryan Hamilton0239aac2018-05-19 00:03:135322 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235323 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
5324 // fetch https://www.example.org/ via SPDY
5325 const char kMyUrl[] = "https://www.example.org/";
Ryan Hamilton0239aac2018-05-19 00:03:135326 spdy::SpdySerializedFrame get(
bnc38dcd392016-02-09 23:19:495327 spdy_util_wrapped.ConstructSpdyGet(kMyUrl, 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:135328 spdy::SpdySerializedFrame wrapped_get(
5329 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
5330 spdy::SpdySerializedFrame conn_resp(
5331 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
5332 spdy::SpdySerializedFrame get_resp(
bnc42331402016-07-25 13:36:155333 spdy_util_wrapped.ConstructSpdyGetReply(NULL, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135334 spdy::SpdySerializedFrame wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:025335 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135336 spdy::SpdySerializedFrame body(
5337 spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
5338 spdy::SpdySerializedFrame wrapped_body(
[email protected]23e482282013-06-14 16:08:025339 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135340 spdy::SpdySerializedFrame window_update_get_resp(
bncdf80d44fd2016-07-15 20:27:415341 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
Ryan Hamilton0239aac2018-05-19 00:03:135342 spdy::SpdySerializedFrame window_update_body(
bncdf80d44fd2016-07-15 20:27:415343 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
[email protected]8d2f7012012-02-16 00:08:045344
5345 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415346 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
5347 CreateMockWrite(window_update_get_resp, 6),
5348 CreateMockWrite(window_update_body, 7),
[email protected]8d2f7012012-02-16 00:08:045349 };
5350
[email protected]d9da5fe2010-10-13 22:37:165351 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415352 CreateMockRead(conn_resp, 1, ASYNC),
rch32320842015-05-16 15:57:095353 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:415354 CreateMockRead(wrapped_get_resp, 4, ASYNC),
5355 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:135356 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:165357 };
5358
Ryan Sleevib8d7ea02018-05-07 20:01:015359 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075360 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165361
[email protected]8ddf8322012-02-23 18:08:065362 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365363 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075364 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065365 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365366 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075367 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165368
[email protected]49639fa2011-12-20 23:22:415369 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165370
bnc691fda62016-08-12 00:43:165371 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015372 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165373
rch32320842015-05-16 15:57:095374 // Allow the SpdyProxyClientSocket's write callback to complete.
fdoray92e35a72016-06-10 15:54:555375 base::RunLoop().RunUntilIdle();
rch32320842015-05-16 15:57:095376 // Now allow the read of the response to complete.
mmenkee24011922015-12-17 22:12:595377 spdy_data.Resume();
[email protected]d9da5fe2010-10-13 22:37:165378 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015379 EXPECT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:165380
[email protected]58e32bb2013-01-21 18:23:255381 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165382 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255383 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5384
bnc691fda62016-08-12 00:43:165385 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525386 ASSERT_TRUE(response);
5387 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025388 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d9da5fe2010-10-13 22:37:165389
5390 std::string response_data;
bnc691fda62016-08-12 00:43:165391 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235392 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:165393}
5394
5395// Test a SPDY CONNECT failure through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015396TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:275397 HttpRequestInfo request;
5398 request.method = "GET";
bncce36dca22015-04-21 22:11:235399 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105400 request.traffic_annotation =
5401 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275402
[email protected]d9da5fe2010-10-13 22:37:165403 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495404 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5405 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515406 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075407 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095408 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165409
bnc691fda62016-08-12 00:43:165410 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165411
bncce36dca22015-04-21 22:11:235412 // CONNECT to www.example.org:443 via SPDY
Ryan Hamilton0239aac2018-05-19 00:03:135413 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235414 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:135415 spdy::SpdySerializedFrame get(
5416 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:165417
5418 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415419 CreateMockWrite(connect, 0), CreateMockWrite(get, 2),
[email protected]d9da5fe2010-10-13 22:37:165420 };
5421
Ryan Hamilton0239aac2018-05-19 00:03:135422 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(1));
5423 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:165424 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415425 CreateMockRead(resp, 1, ASYNC), MockRead(ASYNC, 0, 3),
[email protected]d9da5fe2010-10-13 22:37:165426 };
5427
Ryan Sleevib8d7ea02018-05-07 20:01:015428 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075429 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165430
[email protected]8ddf8322012-02-23 18:08:065431 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365432 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075433 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065434 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365435 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075436 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165437
[email protected]49639fa2011-12-20 23:22:415438 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165439
bnc691fda62016-08-12 00:43:165440 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015441 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165442
5443 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015444 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]d9da5fe2010-10-13 22:37:165445
ttuttle960fcbf2016-04-19 13:26:325446 // TODO(juliatuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:165447}
5448
[email protected]f6c63db52013-02-02 00:35:225449// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
5450// HTTPS Proxy to different servers.
bncd16676a2016-07-20 16:23:015451TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:225452 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
5453 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495454 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5455 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515456 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075457 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095458 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505459 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225460
5461 HttpRequestInfo request1;
5462 request1.method = "GET";
bncce36dca22015-04-21 22:11:235463 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225464 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:105465 request1.traffic_annotation =
5466 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225467
5468 HttpRequestInfo request2;
5469 request2.method = "GET";
bncce36dca22015-04-21 22:11:235470 request2.url = GURL("https://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:225471 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:105472 request2.traffic_annotation =
5473 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225474
bncce36dca22015-04-21 22:11:235475 // CONNECT to www.example.org:443 via SPDY.
Ryan Hamilton0239aac2018-05-19 00:03:135476 spdy::SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235477 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:135478 spdy::SpdySerializedFrame conn_resp1(
5479 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:225480
bncce36dca22015-04-21 22:11:235481 // Fetch https://www.example.org/ via HTTP.
5482 const char get1[] =
5483 "GET / HTTP/1.1\r\n"
5484 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225485 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:135486 spdy::SpdySerializedFrame wrapped_get1(
Bence Békyd74f4382018-02-20 18:26:195487 spdy_util_.ConstructSpdyDataFrame(1, get1, false));
[email protected]f6c63db52013-02-02 00:35:225488 const char resp1[] = "HTTP/1.1 200 OK\r\n"
5489 "Content-Length: 1\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:135490 spdy::SpdySerializedFrame wrapped_get_resp1(
Bence Békyd74f4382018-02-20 18:26:195491 spdy_util_.ConstructSpdyDataFrame(1, resp1, false));
Ryan Hamilton0239aac2018-05-19 00:03:135492 spdy::SpdySerializedFrame wrapped_body1(
Bence Békyd74f4382018-02-20 18:26:195493 spdy_util_.ConstructSpdyDataFrame(1, "1", false));
Ryan Hamilton0239aac2018-05-19 00:03:135494 spdy::SpdySerializedFrame window_update(
bncdf80d44fd2016-07-15 20:27:415495 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:225496
bncce36dca22015-04-21 22:11:235497 // CONNECT to mail.example.org:443 via SPDY.
Ryan Hamilton0239aac2018-05-19 00:03:135498 spdy::SpdyHeaderBlock connect2_block;
5499 connect2_block[spdy::kHttp2MethodHeader] = "CONNECT";
5500 connect2_block[spdy::kHttp2AuthorityHeader] = "mail.example.org:443";
5501 spdy::SpdySerializedFrame connect2(spdy_util_.ConstructSpdyHeaders(
bnc42331402016-07-25 13:36:155502 3, std::move(connect2_block), LOWEST, false));
[email protected]601e03f12014-04-06 16:26:395503
Ryan Hamilton0239aac2018-05-19 00:03:135504 spdy::SpdySerializedFrame conn_resp2(
5505 spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:225506
bncce36dca22015-04-21 22:11:235507 // Fetch https://mail.example.org/ via HTTP.
5508 const char get2[] =
5509 "GET / HTTP/1.1\r\n"
5510 "Host: mail.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225511 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:135512 spdy::SpdySerializedFrame wrapped_get2(
Bence Békyd74f4382018-02-20 18:26:195513 spdy_util_.ConstructSpdyDataFrame(3, get2, false));
[email protected]f6c63db52013-02-02 00:35:225514 const char resp2[] = "HTTP/1.1 200 OK\r\n"
5515 "Content-Length: 2\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:135516 spdy::SpdySerializedFrame wrapped_get_resp2(
Bence Békyd74f4382018-02-20 18:26:195517 spdy_util_.ConstructSpdyDataFrame(3, resp2, false));
Ryan Hamilton0239aac2018-05-19 00:03:135518 spdy::SpdySerializedFrame wrapped_body2(
Bence Békyd74f4382018-02-20 18:26:195519 spdy_util_.ConstructSpdyDataFrame(3, "22", false));
[email protected]f6c63db52013-02-02 00:35:225520
5521 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415522 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
5523 CreateMockWrite(connect2, 5), CreateMockWrite(wrapped_get2, 7),
[email protected]f6c63db52013-02-02 00:35:225524 };
5525
5526 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415527 CreateMockRead(conn_resp1, 1, ASYNC),
5528 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
5529 CreateMockRead(wrapped_body1, 4, ASYNC),
5530 CreateMockRead(conn_resp2, 6, ASYNC),
5531 CreateMockRead(wrapped_get_resp2, 8, ASYNC),
5532 CreateMockRead(wrapped_body2, 9, ASYNC),
5533 MockRead(ASYNC, 0, 10),
[email protected]f6c63db52013-02-02 00:35:225534 };
5535
Ryan Sleevib8d7ea02018-05-07 20:01:015536 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
mmenke11eb5152015-06-09 14:50:505537 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225538
5539 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365540 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505541 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225542 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505543 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:225544 SSLSocketDataProvider ssl3(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505545 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:225546
5547 TestCompletionCallback callback;
5548
bnc691fda62016-08-12 00:43:165549 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205550 int rv = trans.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015551 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225552
5553 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165554 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]f6c63db52013-02-02 00:35:225555 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5556
bnc691fda62016-08-12 00:43:165557 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525558 ASSERT_TRUE(response);
5559 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:225560 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5561
5562 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295563 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
bnc691fda62016-08-12 00:43:165564 rv = trans.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505565 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225566
bnc691fda62016-08-12 00:43:165567 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205568 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015569 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225570
5571 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:165572 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:225573 // Even though the SPDY connection is reused, a new tunnelled connection has
5574 // to be created, so the socket's load timing looks like a fresh connection.
5575 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
5576
5577 // The requests should have different IDs, since they each are using their own
5578 // separate stream.
5579 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5580
bnc691fda62016-08-12 00:43:165581 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505582 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225583}
5584
5585// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
5586// HTTPS Proxy to the same server.
bncd16676a2016-07-20 16:23:015587TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:225588 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
5589 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495590 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5591 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515592 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075593 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095594 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505595 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225596
5597 HttpRequestInfo request1;
5598 request1.method = "GET";
bncce36dca22015-04-21 22:11:235599 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225600 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:105601 request1.traffic_annotation =
5602 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225603
5604 HttpRequestInfo request2;
5605 request2.method = "GET";
bncce36dca22015-04-21 22:11:235606 request2.url = GURL("https://www.example.org/2");
[email protected]f6c63db52013-02-02 00:35:225607 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:105608 request2.traffic_annotation =
5609 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225610
bncce36dca22015-04-21 22:11:235611 // CONNECT to www.example.org:443 via SPDY.
Ryan Hamilton0239aac2018-05-19 00:03:135612 spdy::SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235613 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:135614 spdy::SpdySerializedFrame conn_resp1(
5615 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:225616
bncce36dca22015-04-21 22:11:235617 // Fetch https://www.example.org/ via HTTP.
5618 const char get1[] =
5619 "GET / HTTP/1.1\r\n"
5620 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225621 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:135622 spdy::SpdySerializedFrame wrapped_get1(
Bence Békyd74f4382018-02-20 18:26:195623 spdy_util_.ConstructSpdyDataFrame(1, get1, false));
[email protected]f6c63db52013-02-02 00:35:225624 const char resp1[] = "HTTP/1.1 200 OK\r\n"
5625 "Content-Length: 1\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:135626 spdy::SpdySerializedFrame wrapped_get_resp1(
Bence Békyd74f4382018-02-20 18:26:195627 spdy_util_.ConstructSpdyDataFrame(1, resp1, false));
Ryan Hamilton0239aac2018-05-19 00:03:135628 spdy::SpdySerializedFrame wrapped_body1(
Bence Békyd74f4382018-02-20 18:26:195629 spdy_util_.ConstructSpdyDataFrame(1, "1", false));
Ryan Hamilton0239aac2018-05-19 00:03:135630 spdy::SpdySerializedFrame window_update(
bncdf80d44fd2016-07-15 20:27:415631 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:225632
bncce36dca22015-04-21 22:11:235633 // Fetch https://www.example.org/2 via HTTP.
5634 const char get2[] =
5635 "GET /2 HTTP/1.1\r\n"
5636 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225637 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:135638 spdy::SpdySerializedFrame wrapped_get2(
Bence Békyd74f4382018-02-20 18:26:195639 spdy_util_.ConstructSpdyDataFrame(1, get2, false));
[email protected]f6c63db52013-02-02 00:35:225640 const char resp2[] = "HTTP/1.1 200 OK\r\n"
5641 "Content-Length: 2\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:135642 spdy::SpdySerializedFrame wrapped_get_resp2(
Bence Békyd74f4382018-02-20 18:26:195643 spdy_util_.ConstructSpdyDataFrame(1, resp2, false));
Ryan Hamilton0239aac2018-05-19 00:03:135644 spdy::SpdySerializedFrame wrapped_body2(
Bence Békyd74f4382018-02-20 18:26:195645 spdy_util_.ConstructSpdyDataFrame(1, "22", false));
[email protected]f6c63db52013-02-02 00:35:225646
5647 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415648 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
5649 CreateMockWrite(wrapped_get2, 5),
[email protected]f6c63db52013-02-02 00:35:225650 };
5651
5652 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415653 CreateMockRead(conn_resp1, 1, ASYNC),
5654 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
bnceb9aa7112017-01-05 01:03:465655 CreateMockRead(wrapped_body1, 4, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415656 CreateMockRead(wrapped_get_resp2, 6, ASYNC),
bnceb9aa7112017-01-05 01:03:465657 CreateMockRead(wrapped_body2, 7, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415658 MockRead(ASYNC, 0, 8),
[email protected]f6c63db52013-02-02 00:35:225659 };
5660
Ryan Sleevib8d7ea02018-05-07 20:01:015661 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
mmenke11eb5152015-06-09 14:50:505662 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225663
5664 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365665 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505666 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225667 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505668 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:225669
5670 TestCompletionCallback callback;
5671
bnc87dcefc2017-05-25 12:47:585672 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:195673 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205674 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015675 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:225676
5677 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:015678 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:225679
5680 LoadTimingInfo load_timing_info;
5681 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5682 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5683
5684 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525685 ASSERT_TRUE(response);
5686 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:225687 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5688
5689 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295690 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]90499482013-06-01 00:39:505691 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:225692 trans.reset();
5693
bnc87dcefc2017-05-25 12:47:585694 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:195695 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205696 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015697 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:225698
[email protected]f6c63db52013-02-02 00:35:225699 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:015700 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:225701
5702 LoadTimingInfo load_timing_info2;
5703 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5704 TestLoadTimingReused(load_timing_info2);
5705
5706 // The requests should have the same ID.
5707 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5708
[email protected]90499482013-06-01 00:39:505709 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:225710}
5711
5712// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
5713// Proxy to different servers.
bncd16676a2016-07-20 16:23:015714TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) {
[email protected]f6c63db52013-02-02 00:35:225715 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495716 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5717 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515718 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075719 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095720 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505721 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225722
5723 HttpRequestInfo request1;
5724 request1.method = "GET";
bncce36dca22015-04-21 22:11:235725 request1.url = GURL("http://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225726 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:105727 request1.traffic_annotation =
5728 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225729
5730 HttpRequestInfo request2;
5731 request2.method = "GET";
bncce36dca22015-04-21 22:11:235732 request2.url = GURL("http://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:225733 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:105734 request2.traffic_annotation =
5735 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225736
bncce36dca22015-04-21 22:11:235737 // http://www.example.org/
Ryan Hamilton0239aac2018-05-19 00:03:135738 spdy::SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:235739 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
Ryan Hamilton0239aac2018-05-19 00:03:135740 spdy::SpdySerializedFrame get1(
bnc42331402016-07-25 13:36:155741 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
Ryan Hamilton0239aac2018-05-19 00:03:135742 spdy::SpdySerializedFrame get_resp1(
5743 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
5744 spdy::SpdySerializedFrame body1(
5745 spdy_util_.ConstructSpdyDataFrame(1, "1", true));
rdsmithebb50aa2015-11-12 03:44:385746 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]f6c63db52013-02-02 00:35:225747
bncce36dca22015-04-21 22:11:235748 // http://mail.example.org/
Ryan Hamilton0239aac2018-05-19 00:03:135749 spdy::SpdyHeaderBlock headers2(
bncce36dca22015-04-21 22:11:235750 spdy_util_.ConstructGetHeaderBlockForProxy("http://mail.example.org/"));
Ryan Hamilton0239aac2018-05-19 00:03:135751 spdy::SpdySerializedFrame get2(
bnc42331402016-07-25 13:36:155752 spdy_util_.ConstructSpdyHeaders(3, std::move(headers2), LOWEST, true));
Ryan Hamilton0239aac2018-05-19 00:03:135753 spdy::SpdySerializedFrame get_resp2(
5754 spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
5755 spdy::SpdySerializedFrame body2(
5756 spdy_util_.ConstructSpdyDataFrame(3, "22", true));
[email protected]f6c63db52013-02-02 00:35:225757
5758 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415759 CreateMockWrite(get1, 0), CreateMockWrite(get2, 3),
[email protected]f6c63db52013-02-02 00:35:225760 };
5761
5762 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415763 CreateMockRead(get_resp1, 1, ASYNC),
5764 CreateMockRead(body1, 2, ASYNC),
5765 CreateMockRead(get_resp2, 4, ASYNC),
5766 CreateMockRead(body2, 5, ASYNC),
5767 MockRead(ASYNC, 0, 6),
[email protected]f6c63db52013-02-02 00:35:225768 };
5769
Ryan Sleevib8d7ea02018-05-07 20:01:015770 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
mmenke11eb5152015-06-09 14:50:505771 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225772
5773 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365774 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505775 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225776
5777 TestCompletionCallback callback;
5778
bnc87dcefc2017-05-25 12:47:585779 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:195780 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205781 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015782 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225783
5784 LoadTimingInfo load_timing_info;
5785 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5786 TestLoadTimingNotReused(load_timing_info,
5787 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5788
5789 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525790 ASSERT_TRUE(response);
5791 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025792 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]f6c63db52013-02-02 00:35:225793
5794 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295795 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
mmenke11eb5152015-06-09 14:50:505796 rv = trans->Read(buf.get(), 256, callback.callback());
5797 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225798 // Delete the first request, so the second one can reuse the socket.
5799 trans.reset();
5800
bnc691fda62016-08-12 00:43:165801 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205802 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015803 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225804
5805 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:165806 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:225807 TestLoadTimingReused(load_timing_info2);
5808
5809 // The requests should have the same ID.
5810 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5811
bnc691fda62016-08-12 00:43:165812 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505813 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225814}
5815
[email protected]2df19bb2010-08-25 20:13:465816// Test the challenge-response-retry sequence through an HTTPS Proxy
bncd16676a2016-07-20 16:23:015817TEST_F(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:465818 HttpRequestInfo request;
5819 request.method = "GET";
bncce36dca22015-04-21 22:11:235820 request.url = GURL("http://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:465821 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:295822 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:105823 request.traffic_annotation =
5824 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:465825
[email protected]79cb5c12011-09-12 13:12:045826 // Configure against https proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495827 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5828 "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515829 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075830 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095831 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275832
[email protected]2df19bb2010-08-25 20:13:465833 // Since we have proxy, should use full url
5834 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:165835 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
5836 "Host: www.example.org\r\n"
5837 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465838
bnc691fda62016-08-12 00:43:165839 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:235840 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:165841 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
5842 "Host: www.example.org\r\n"
5843 "Proxy-Connection: keep-alive\r\n"
5844 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465845 };
5846
5847 // The proxy responds to the GET with a 407, using a persistent
5848 // connection.
5849 MockRead data_reads1[] = {
5850 // No credentials.
5851 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
5852 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5853 MockRead("Proxy-Connection: keep-alive\r\n"),
5854 MockRead("Content-Length: 0\r\n\r\n"),
5855
5856 MockRead("HTTP/1.1 200 OK\r\n"),
5857 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5858 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065859 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:465860 };
5861
Ryan Sleevib8d7ea02018-05-07 20:01:015862 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:075863 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:065864 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075865 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:465866
[email protected]49639fa2011-12-20 23:22:415867 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:465868
bnc691fda62016-08-12 00:43:165869 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505870
bnc691fda62016-08-12 00:43:165871 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015872 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465873
5874 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015875 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465876
[email protected]58e32bb2013-01-21 18:23:255877 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165878 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255879 TestLoadTimingNotReused(load_timing_info,
5880 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5881
bnc691fda62016-08-12 00:43:165882 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525883 ASSERT_TRUE(response);
5884 ASSERT_TRUE(response->headers);
[email protected]2df19bb2010-08-25 20:13:465885 EXPECT_EQ(407, response->headers->response_code());
5886 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
asanka098c0092016-06-16 20:18:435887 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:465888
[email protected]49639fa2011-12-20 23:22:415889 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:465890
bnc691fda62016-08-12 00:43:165891 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015892 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465893
5894 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015895 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465896
[email protected]58e32bb2013-01-21 18:23:255897 load_timing_info = LoadTimingInfo();
bnc691fda62016-08-12 00:43:165898 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255899 // Retrying with HTTP AUTH is considered to be reusing a socket.
5900 TestLoadTimingReused(load_timing_info);
5901
bnc691fda62016-08-12 00:43:165902 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525903 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:465904
5905 EXPECT_TRUE(response->headers->IsKeepAlive());
5906 EXPECT_EQ(200, response->headers->response_code());
5907 EXPECT_EQ(100, response->headers->GetContentLength());
5908 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5909
5910 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525911 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:465912}
5913
[email protected]23e482282013-06-14 16:08:025914void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:085915 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:425916 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:085917 request.method = "GET";
bncce36dca22015-04-21 22:11:235918 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105919 request.traffic_annotation =
5920 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]c744cf22009-02-27 07:28:085921
[email protected]cb9bf6ca2011-01-28 13:15:275922 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495923 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5924 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:095925 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275926
[email protected]c744cf22009-02-27 07:28:085927 // Since we have proxy, should try to establish tunnel.
5928 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:175929 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5930 "Host: www.example.org:443\r\n"
5931 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:085932 };
5933
5934 MockRead data_reads[] = {
mmenked39192ee2015-12-09 00:57:235935 status, MockRead("Content-Length: 10\r\n\r\n"),
5936 // No response body because the test stops reading here.
5937 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]c744cf22009-02-27 07:28:085938 };
5939
Ryan Sleevib8d7ea02018-05-07 20:01:015940 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:075941 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:085942
[email protected]49639fa2011-12-20 23:22:415943 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:085944
bnc691fda62016-08-12 00:43:165945 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505946
tfarina42834112016-09-22 13:38:205947 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015948 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]c744cf22009-02-27 07:28:085949
5950 rv = callback.WaitForResult();
5951 EXPECT_EQ(expected_status, rv);
5952}
5953
[email protected]23e482282013-06-14 16:08:025954void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:235955 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:085956 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:425957 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:085958}
5959
bncd16676a2016-07-20 16:23:015960TEST_F(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:085961 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
5962}
5963
bncd16676a2016-07-20 16:23:015964TEST_F(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:085965 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
5966}
5967
bncd16676a2016-07-20 16:23:015968TEST_F(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:085969 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
5970}
5971
bncd16676a2016-07-20 16:23:015972TEST_F(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:085973 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
5974}
5975
bncd16676a2016-07-20 16:23:015976TEST_F(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:085977 ConnectStatusHelper(
5978 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
5979}
5980
bncd16676a2016-07-20 16:23:015981TEST_F(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:085982 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
5983}
5984
bncd16676a2016-07-20 16:23:015985TEST_F(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:085986 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
5987}
5988
bncd16676a2016-07-20 16:23:015989TEST_F(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:085990 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
5991}
5992
bncd16676a2016-07-20 16:23:015993TEST_F(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:085994 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
5995}
5996
bncd16676a2016-07-20 16:23:015997TEST_F(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:085998 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
5999}
6000
bncd16676a2016-07-20 16:23:016001TEST_F(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:086002 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
6003}
6004
bncd16676a2016-07-20 16:23:016005TEST_F(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:086006 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
6007}
6008
bncd16676a2016-07-20 16:23:016009TEST_F(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:086010 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
6011}
6012
bncd16676a2016-07-20 16:23:016013TEST_F(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:086014 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
6015}
6016
bncd16676a2016-07-20 16:23:016017TEST_F(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:086018 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
6019}
6020
bncd16676a2016-07-20 16:23:016021TEST_F(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:086022 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
6023}
6024
bncd16676a2016-07-20 16:23:016025TEST_F(HttpNetworkTransactionTest, ConnectStatus308) {
[email protected]0a17aab32014-04-24 03:32:376026 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
6027}
6028
bncd16676a2016-07-20 16:23:016029TEST_F(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:086030 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
6031}
6032
bncd16676a2016-07-20 16:23:016033TEST_F(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:086034 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
6035}
6036
bncd16676a2016-07-20 16:23:016037TEST_F(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:086038 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
6039}
6040
bncd16676a2016-07-20 16:23:016041TEST_F(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:086042 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
6043}
6044
bncd16676a2016-07-20 16:23:016045TEST_F(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:086046 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
6047}
6048
bncd16676a2016-07-20 16:23:016049TEST_F(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:086050 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
6051}
6052
bncd16676a2016-07-20 16:23:016053TEST_F(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:086054 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
6055}
6056
bncd16676a2016-07-20 16:23:016057TEST_F(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:086058 ConnectStatusHelperWithExpectedStatus(
6059 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:546060 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:086061}
6062
bncd16676a2016-07-20 16:23:016063TEST_F(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:086064 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
6065}
6066
bncd16676a2016-07-20 16:23:016067TEST_F(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:086068 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
6069}
6070
bncd16676a2016-07-20 16:23:016071TEST_F(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:086072 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
6073}
6074
bncd16676a2016-07-20 16:23:016075TEST_F(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:086076 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
6077}
6078
bncd16676a2016-07-20 16:23:016079TEST_F(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:086080 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
6081}
6082
bncd16676a2016-07-20 16:23:016083TEST_F(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:086084 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
6085}
6086
bncd16676a2016-07-20 16:23:016087TEST_F(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:086088 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
6089}
6090
bncd16676a2016-07-20 16:23:016091TEST_F(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:086092 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
6093}
6094
bncd16676a2016-07-20 16:23:016095TEST_F(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:086096 ConnectStatusHelper(
6097 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
6098}
6099
bncd16676a2016-07-20 16:23:016100TEST_F(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:086101 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
6102}
6103
bncd16676a2016-07-20 16:23:016104TEST_F(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:086105 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
6106}
6107
bncd16676a2016-07-20 16:23:016108TEST_F(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:086109 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
6110}
6111
bncd16676a2016-07-20 16:23:016112TEST_F(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:086113 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
6114}
6115
bncd16676a2016-07-20 16:23:016116TEST_F(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:086117 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
6118}
6119
bncd16676a2016-07-20 16:23:016120TEST_F(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:086121 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
6122}
6123
bncd16676a2016-07-20 16:23:016124TEST_F(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:086125 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
6126}
6127
[email protected]038e9a32008-10-08 22:40:166128// Test the flow when both the proxy server AND origin server require
6129// authentication. Again, this uses basic auth for both since that is
6130// the simplest to mock.
bncd16676a2016-07-20 16:23:016131TEST_F(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:276132 HttpRequestInfo request;
6133 request.method = "GET";
bncce36dca22015-04-21 22:11:236134 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:106135 request.traffic_annotation =
6136 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:276137
[email protected]038e9a32008-10-08 22:40:166138 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496139 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6140 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:096141 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:076142
bnc691fda62016-08-12 00:43:166143 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]038e9a32008-10-08 22:40:166144
[email protected]f9ee6b52008-11-08 06:46:236145 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236146 MockWrite(
6147 "GET http://www.example.org/ HTTP/1.1\r\n"
6148 "Host: www.example.org\r\n"
6149 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236150 };
6151
[email protected]038e9a32008-10-08 22:40:166152 MockRead data_reads1[] = {
6153 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
6154 // Give a couple authenticate options (only the middle one is actually
6155 // supported).
[email protected]22927ad2009-09-21 19:56:196156 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:166157 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6158 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
6159 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6160 // Large content-length -- won't matter, as connection will be reset.
6161 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066162 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:166163 };
6164
bnc691fda62016-08-12 00:43:166165 // After calling trans.RestartWithAuth() the first time, this is the
[email protected]038e9a32008-10-08 22:40:166166 // request we should be issuing -- the final header line contains the
6167 // proxy's credentials.
6168 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236169 MockWrite(
6170 "GET http://www.example.org/ HTTP/1.1\r\n"
6171 "Host: www.example.org\r\n"
6172 "Proxy-Connection: keep-alive\r\n"
6173 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:166174 };
6175
6176 // Now the proxy server lets the request pass through to origin server.
6177 // The origin server responds with a 401.
6178 MockRead data_reads2[] = {
6179 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6180 // Note: We are using the same realm-name as the proxy server. This is
6181 // completely valid, as realms are unique across hosts.
6182 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6183 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6184 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066185 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:166186 };
6187
bnc691fda62016-08-12 00:43:166188 // After calling trans.RestartWithAuth() the second time, we should send
[email protected]038e9a32008-10-08 22:40:166189 // the credentials for both the proxy and origin server.
6190 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236191 MockWrite(
6192 "GET http://www.example.org/ HTTP/1.1\r\n"
6193 "Host: www.example.org\r\n"
6194 "Proxy-Connection: keep-alive\r\n"
6195 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
6196 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:166197 };
6198
6199 // Lastly we get the desired content.
6200 MockRead data_reads3[] = {
6201 MockRead("HTTP/1.0 200 OK\r\n"),
6202 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6203 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066204 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:166205 };
6206
Ryan Sleevib8d7ea02018-05-07 20:01:016207 StaticSocketDataProvider data1(data_reads1, data_writes1);
6208 StaticSocketDataProvider data2(data_reads2, data_writes2);
6209 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]bb88e1d32013-05-03 23:11:076210 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6211 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6212 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:166213
[email protected]49639fa2011-12-20 23:22:416214 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:166215
tfarina42834112016-09-22 13:38:206216 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016217 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:166218
6219 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016220 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:166221
bnc691fda62016-08-12 00:43:166222 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526223 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046224 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:166225
[email protected]49639fa2011-12-20 23:22:416226 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:166227
bnc691fda62016-08-12 00:43:166228 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:016229 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:166230
6231 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016232 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:166233
bnc691fda62016-08-12 00:43:166234 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526235 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046236 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:166237
[email protected]49639fa2011-12-20 23:22:416238 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:166239
bnc691fda62016-08-12 00:43:166240 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
6241 callback3.callback());
robpercival214763f2016-07-01 23:27:016242 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:166243
6244 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016245 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:166246
bnc691fda62016-08-12 00:43:166247 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526248 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:166249 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:166250}
[email protected]4ddaf2502008-10-23 18:26:196251
[email protected]ea9dc9a2009-09-05 00:43:326252// For the NTLM implementation using SSPI, we skip the NTLM tests since we
6253// can't hook into its internals to cause it to generate predictable NTLM
6254// authorization headers.
6255#if defined(NTLM_PORTABLE)
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376256// The NTLM authentication unit tests are based on known test data from the
6257// [MS-NLMP] Specification [1]. These tests are primarily of the authentication
6258// flow rather than the implementation of the NTLM protocol. See net/ntlm
6259// for the implementation and testing of the protocol.
6260//
6261// [1] https://msdn.microsoft.com/en-us/library/cc236621.aspx
[email protected]385a4672009-03-11 22:21:296262
6263// Enter the correct password and authenticate successfully.
Zentaro Kavanagh1890a3d2018-01-29 19:52:556264TEST_F(HttpNetworkTransactionTest, NTLMAuthV2) {
[email protected]1c773ea12009-04-28 19:58:426265 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:246266 request.method = "GET";
Zentaro Kavanagh1890a3d2018-01-29 19:52:556267 request.url = GURL("https://server/kids/login.aspx");
Ramin Halavatib5e433e62018-02-07 07:41:106268 request.traffic_annotation =
6269 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2217aa22013-10-11 03:03:546270
6271 // Ensure load is not disrupted by flags which suppress behaviour specific
6272 // to other auth schemes.
6273 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:246274
Zentaro Kavanagh6ccee512017-09-28 18:34:096275 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
6276 MockGetMSTime, MockGenerateRandom, MockGetHostName);
danakj1fd259a02016-04-16 03:17:096277 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276278
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376279 // Generate the NTLM messages based on known test data.
6280 std::string negotiate_msg;
6281 std::string challenge_msg;
6282 std::string authenticate_msg;
6283 base::Base64Encode(
6284 base::StringPiece(
6285 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
6286 arraysize(ntlm::test::kExpectedNegotiateMsg)),
6287 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:556288 base::Base64Encode(
6289 base::StringPiece(
6290 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
6291 arraysize(ntlm::test::kChallengeMsgFromSpecV2)),
6292 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376293 base::Base64Encode(
6294 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:096295 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:556296 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
6297 arraysize(
6298 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376299 &authenticate_msg);
6300
[email protected]3f918782009-02-28 01:29:246301 MockWrite data_writes1[] = {
Zentaro Kavanagh1890a3d2018-01-29 19:52:556302 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6303 "Host: server\r\n"
6304 "Connection: keep-alive\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246305 };
6306
6307 MockRead data_reads1[] = {
6308 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:046309 // Negotiate and NTLM are often requested together. However, we only want
6310 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
6311 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:246312 MockRead("WWW-Authenticate: NTLM\r\n"),
6313 MockRead("Connection: close\r\n"),
6314 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366315 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246316 // Missing content -- won't matter, as connection will be reset.
[email protected]3f918782009-02-28 01:29:246317 };
6318
6319 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:166320 // After restarting with a null identity, this is the
6321 // request we should be issuing -- the final header line contains a Type
6322 // 1 message.
6323 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556324 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166325 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376326 "Authorization: NTLM "),
6327 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246328
bnc691fda62016-08-12 00:43:166329 // After calling trans.RestartWithAuth(), we should send a Type 3 message
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376330 // (using correct credentials). The second request continues on the
6331 // same connection.
bnc691fda62016-08-12 00:43:166332 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556333 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166334 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376335 "Authorization: NTLM "),
6336 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246337 };
6338
6339 MockRead data_reads2[] = {
Bence Béky1e4ef192017-09-18 19:58:026340 // The origin server responds with a Type 2 message.
6341 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376342 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6343 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky1e4ef192017-09-18 19:58:026344 MockRead("Content-Type: text/html\r\n\r\n"),
6345 MockRead("You are not authorized to view this page\r\n"),
[email protected]3f918782009-02-28 01:29:246346
Bence Béky1e4ef192017-09-18 19:58:026347 // Lastly we get the desired content.
6348 MockRead("HTTP/1.1 200 OK\r\n"),
6349 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
6350 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
[email protected]3f918782009-02-28 01:29:246351 };
6352
Ryan Sleevib8d7ea02018-05-07 20:01:016353 StaticSocketDataProvider data1(data_reads1, data_writes1);
6354 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:076355 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6356 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:246357
Bence Béky83eb3512017-09-05 12:56:096358 SSLSocketDataProvider ssl1(ASYNC, OK);
6359 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
6360 SSLSocketDataProvider ssl2(ASYNC, OK);
6361 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6362
[email protected]49639fa2011-12-20 23:22:416363 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:246364
bnc691fda62016-08-12 00:43:166365 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506366
tfarina42834112016-09-22 13:38:206367 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016368 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:246369
6370 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016371 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:246372
bnc691fda62016-08-12 00:43:166373 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:226374
bnc691fda62016-08-12 00:43:166375 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526376 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046377 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:246378
[email protected]49639fa2011-12-20 23:22:416379 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:256380
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376381 rv = trans.RestartWithAuth(
6382 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
6383 callback2.callback());
robpercival214763f2016-07-01 23:27:016384 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256385
6386 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016387 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:256388
bnc691fda62016-08-12 00:43:166389 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:256390
bnc691fda62016-08-12 00:43:166391 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526392 ASSERT_TRUE(response);
6393 EXPECT_FALSE(response->auth_challenge);
[email protected]10af5fe72011-01-31 16:17:256394
[email protected]49639fa2011-12-20 23:22:416395 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:246396
bnc691fda62016-08-12 00:43:166397 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:016398 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:246399
[email protected]0757e7702009-03-27 04:00:226400 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016401 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:246402
bnc691fda62016-08-12 00:43:166403 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526404 ASSERT_TRUE(response);
6405 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:026406 EXPECT_EQ(14, response->headers->GetContentLength());
6407
6408 std::string response_data;
6409 rv = ReadTransaction(&trans, &response_data);
6410 EXPECT_THAT(rv, IsOk());
6411 EXPECT_EQ("Please Login\r\n", response_data);
6412
6413 EXPECT_TRUE(data1.AllReadDataConsumed());
6414 EXPECT_TRUE(data1.AllWriteDataConsumed());
6415 EXPECT_TRUE(data2.AllReadDataConsumed());
6416 EXPECT_TRUE(data2.AllWriteDataConsumed());
[email protected]3f918782009-02-28 01:29:246417}
6418
[email protected]385a4672009-03-11 22:21:296419// Enter a wrong password, and then the correct one.
Zentaro Kavanagh1890a3d2018-01-29 19:52:556420TEST_F(HttpNetworkTransactionTest, NTLMAuthV2WrongThenRightPassword) {
[email protected]1c773ea12009-04-28 19:58:426421 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:296422 request.method = "GET";
Zentaro Kavanagh1890a3d2018-01-29 19:52:556423 request.url = GURL("https://server/kids/login.aspx");
Ramin Halavatib5e433e62018-02-07 07:41:106424 request.traffic_annotation =
6425 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]385a4672009-03-11 22:21:296426
Zentaro Kavanagh6ccee512017-09-28 18:34:096427 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
6428 MockGetMSTime, MockGenerateRandom, MockGetHostName);
danakj1fd259a02016-04-16 03:17:096429 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276430
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376431 // Generate the NTLM messages based on known test data.
6432 std::string negotiate_msg;
6433 std::string challenge_msg;
6434 std::string authenticate_msg;
6435 base::Base64Encode(
6436 base::StringPiece(
6437 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
6438 arraysize(ntlm::test::kExpectedNegotiateMsg)),
6439 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:556440 base::Base64Encode(
6441 base::StringPiece(
6442 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
6443 arraysize(ntlm::test::kChallengeMsgFromSpecV2)),
6444 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376445 base::Base64Encode(
6446 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:096447 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:556448 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
6449 arraysize(
6450 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376451 &authenticate_msg);
6452
6453 // The authenticate message when |kWrongPassword| is sent.
6454 std::string wrong_password_authenticate_msg(
Zentaro Kavanagh1890a3d2018-01-29 19:52:556455 "TlRMTVNTUAADAAAAGAAYAFgAAACKAIoAcAAAAAwADAD6AAAACAAIAAYBAAAQABAADgEAAAAA"
6456 "AABYAAAAA4IIAAAAAAAAAAAAAPknEYqtJQtusopDRSfYzAAAAAAAAAAAAAAAAAAAAAAAAAAA"
6457 "AAAAAOtVz38osnFdRRggUQHUJ3EBAQAAAAAAAIALyP0A1NIBqqqqqqqqqqoAAAAAAgAMAEQA"
6458 "bwBtAGEAaQBuAAEADABTAGUAcgB2AGUAcgAGAAQAAgAAAAoAEAAAAAAAAAAAAAAAAAAAAAAA"
6459 "CQAWAEgAVABUAFAALwBzAGUAcgB2AGUAcgAAAAAAAAAAAEQAbwBtAGEAaQBuAFUAcwBlAHIA"
6460 "QwBPAE0AUABVAFQARQBSAA==");
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376461
Zentaro Kavanagh1890a3d2018-01-29 19:52:556462 // Sanity check that it's the same length as the correct authenticate message
6463 // and that it's different.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376464 ASSERT_EQ(authenticate_msg.length(),
6465 wrong_password_authenticate_msg.length());
Zentaro Kavanagh1890a3d2018-01-29 19:52:556466 ASSERT_NE(authenticate_msg, wrong_password_authenticate_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376467
[email protected]385a4672009-03-11 22:21:296468 MockWrite data_writes1[] = {
Zentaro Kavanagh1890a3d2018-01-29 19:52:556469 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6470 "Host: server\r\n"
6471 "Connection: keep-alive\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296472 };
6473
6474 MockRead data_reads1[] = {
6475 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:046476 // Negotiate and NTLM are often requested together. However, we only want
6477 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
6478 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:296479 MockRead("WWW-Authenticate: NTLM\r\n"),
6480 MockRead("Connection: close\r\n"),
6481 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366482 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296483 // Missing content -- won't matter, as connection will be reset.
[email protected]385a4672009-03-11 22:21:296484 };
6485
6486 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:166487 // After restarting with a null identity, this is the
6488 // request we should be issuing -- the final header line contains a Type
6489 // 1 message.
6490 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556491 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166492 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376493 "Authorization: NTLM "),
6494 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296495
bnc691fda62016-08-12 00:43:166496 // After calling trans.RestartWithAuth(), we should send a Type 3 message
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376497 // (using incorrect credentials). The second request continues on the
6498 // same connection.
bnc691fda62016-08-12 00:43:166499 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556500 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166501 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376502 "Authorization: NTLM "),
6503 MockWrite(wrong_password_authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296504 };
6505
6506 MockRead data_reads2[] = {
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376507 // The origin server responds with a Type 2 message.
6508 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6509 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6510 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
6511 MockRead("Content-Type: text/html\r\n\r\n"),
6512 MockRead("You are not authorized to view this page\r\n"),
[email protected]385a4672009-03-11 22:21:296513
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376514 // Wrong password.
6515 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6516 MockRead("WWW-Authenticate: NTLM\r\n"), MockRead("Connection: close\r\n"),
6517 MockRead("Content-Length: 42\r\n"),
6518 MockRead("Content-Type: text/html\r\n\r\n"),
6519 // Missing content -- won't matter, as connection will be reset.
[email protected]385a4672009-03-11 22:21:296520 };
6521
6522 MockWrite data_writes3[] = {
bnc691fda62016-08-12 00:43:166523 // After restarting with a null identity, this is the
6524 // request we should be issuing -- the final header line contains a Type
6525 // 1 message.
6526 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556527 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166528 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376529 "Authorization: NTLM "),
6530 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296531
bnc691fda62016-08-12 00:43:166532 // After calling trans.RestartWithAuth(), we should send a Type 3 message
6533 // (the credentials for the origin server). The second request continues
6534 // on the same connection.
6535 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556536 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166537 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376538 "Authorization: NTLM "),
6539 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296540 };
6541
6542 MockRead data_reads3[] = {
Bence Béky1e4ef192017-09-18 19:58:026543 // The origin server responds with a Type 2 message.
6544 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376545 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6546 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky1e4ef192017-09-18 19:58:026547 MockRead("Content-Type: text/html\r\n\r\n"),
6548 MockRead("You are not authorized to view this page\r\n"),
[email protected]385a4672009-03-11 22:21:296549
Bence Béky1e4ef192017-09-18 19:58:026550 // Lastly we get the desired content.
6551 MockRead("HTTP/1.1 200 OK\r\n"),
6552 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
6553 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
[email protected]385a4672009-03-11 22:21:296554 };
6555
Ryan Sleevib8d7ea02018-05-07 20:01:016556 StaticSocketDataProvider data1(data_reads1, data_writes1);
6557 StaticSocketDataProvider data2(data_reads2, data_writes2);
6558 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]bb88e1d32013-05-03 23:11:076559 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6560 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6561 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:296562
Bence Béky83eb3512017-09-05 12:56:096563 SSLSocketDataProvider ssl1(ASYNC, OK);
6564 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
6565 SSLSocketDataProvider ssl2(ASYNC, OK);
6566 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6567 SSLSocketDataProvider ssl3(ASYNC, OK);
6568 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
6569
[email protected]49639fa2011-12-20 23:22:416570 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:296571
bnc691fda62016-08-12 00:43:166572 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506573
tfarina42834112016-09-22 13:38:206574 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016575 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:296576
6577 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016578 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:296579
bnc691fda62016-08-12 00:43:166580 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:296581
bnc691fda62016-08-12 00:43:166582 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526583 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046584 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:296585
[email protected]49639fa2011-12-20 23:22:416586 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:296587
[email protected]0757e7702009-03-27 04:00:226588 // Enter the wrong password.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376589 rv = trans.RestartWithAuth(
6590 AuthCredentials(ntlm::test::kDomainUserCombined, kWrongPassword),
6591 callback2.callback());
robpercival214763f2016-07-01 23:27:016592 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:296593
[email protected]10af5fe72011-01-31 16:17:256594 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016595 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:296596
bnc691fda62016-08-12 00:43:166597 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:416598 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:166599 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:016600 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256601 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016602 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166603 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:226604
bnc691fda62016-08-12 00:43:166605 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526606 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046607 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:226608
[email protected]49639fa2011-12-20 23:22:416609 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:226610
6611 // Now enter the right password.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376612 rv = trans.RestartWithAuth(
6613 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
6614 callback4.callback());
robpercival214763f2016-07-01 23:27:016615 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256616
6617 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:016618 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:256619
bnc691fda62016-08-12 00:43:166620 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:256621
[email protected]49639fa2011-12-20 23:22:416622 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:256623
6624 // One more roundtrip
bnc691fda62016-08-12 00:43:166625 rv = trans.RestartWithAuth(AuthCredentials(), callback5.callback());
robpercival214763f2016-07-01 23:27:016626 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:226627
6628 rv = callback5.WaitForResult();
robpercival214763f2016-07-01 23:27:016629 EXPECT_THAT(rv, IsOk());
[email protected]0757e7702009-03-27 04:00:226630
bnc691fda62016-08-12 00:43:166631 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526632 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:026633 EXPECT_EQ(14, response->headers->GetContentLength());
6634
6635 std::string response_data;
6636 rv = ReadTransaction(&trans, &response_data);
6637 EXPECT_THAT(rv, IsOk());
6638 EXPECT_EQ("Please Login\r\n", response_data);
6639
6640 EXPECT_TRUE(data1.AllReadDataConsumed());
6641 EXPECT_TRUE(data1.AllWriteDataConsumed());
6642 EXPECT_TRUE(data2.AllReadDataConsumed());
6643 EXPECT_TRUE(data2.AllWriteDataConsumed());
6644 EXPECT_TRUE(data3.AllReadDataConsumed());
6645 EXPECT_TRUE(data3.AllWriteDataConsumed());
[email protected]385a4672009-03-11 22:21:296646}
Bence Béky83eb3512017-09-05 12:56:096647
Bence Béky3238f2e12017-09-22 22:44:496648// Server requests NTLM authentication, which is not supported over HTTP/2.
6649// Subsequent request with authorization header should be sent over HTTP/1.1.
Bence Béky83eb3512017-09-05 12:56:096650TEST_F(HttpNetworkTransactionTest, NTLMOverHttp2) {
Zentaro Kavanagh6ccee512017-09-28 18:34:096651 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
6652 MockGetMSTime, MockGenerateRandom, MockGetHostName);
Bence Béky83eb3512017-09-05 12:56:096653
Zentaro Kavanagh1890a3d2018-01-29 19:52:556654 const char* kUrl = "https://server/kids/login.aspx";
Bence Béky83eb3512017-09-05 12:56:096655
6656 HttpRequestInfo request;
6657 request.method = "GET";
6658 request.url = GURL(kUrl);
Ramin Halavatib5e433e62018-02-07 07:41:106659 request.traffic_annotation =
6660 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Béky83eb3512017-09-05 12:56:096661
6662 // First request without credentials.
Ryan Hamilton0239aac2018-05-19 00:03:136663 spdy::SpdyHeaderBlock request_headers0(
6664 spdy_util_.ConstructGetHeaderBlock(kUrl));
6665 spdy::SpdySerializedFrame request0(spdy_util_.ConstructSpdyHeaders(
Bence Béky83eb3512017-09-05 12:56:096666 1, std::move(request_headers0), LOWEST, true));
6667
Ryan Hamilton0239aac2018-05-19 00:03:136668 spdy::SpdyHeaderBlock response_headers0;
6669 response_headers0[spdy::kHttp2StatusHeader] = "401";
Bence Béky83eb3512017-09-05 12:56:096670 response_headers0["www-authenticate"] = "NTLM";
Ryan Hamilton0239aac2018-05-19 00:03:136671 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyResponseHeaders(
Bence Béky83eb3512017-09-05 12:56:096672 1, std::move(response_headers0), true));
6673
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376674 // Stream 1 is closed.
6675 spdy_util_.UpdateWithStreamDestruction(1);
6676
6677 // Generate the NTLM messages based on known test data.
6678 std::string negotiate_msg;
6679 std::string challenge_msg;
6680 std::string authenticate_msg;
6681 base::Base64Encode(
6682 base::StringPiece(
6683 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
6684 arraysize(ntlm::test::kExpectedNegotiateMsg)),
6685 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:556686 base::Base64Encode(
6687 base::StringPiece(
6688 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
6689 arraysize(ntlm::test::kChallengeMsgFromSpecV2)),
6690 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376691 base::Base64Encode(
6692 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:096693 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:556694 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
6695 arraysize(
6696 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376697 &authenticate_msg);
6698
6699 // Retry with authorization header.
Ryan Hamilton0239aac2018-05-19 00:03:136700 spdy::SpdyHeaderBlock request_headers1(
6701 spdy_util_.ConstructGetHeaderBlock(kUrl));
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376702 request_headers1["authorization"] = std::string("NTLM ") + negotiate_msg;
Ryan Hamilton0239aac2018-05-19 00:03:136703 spdy::SpdySerializedFrame request1(spdy_util_.ConstructSpdyHeaders(
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376704 3, std::move(request_headers1), LOWEST, true));
6705
Ryan Hamilton0239aac2018-05-19 00:03:136706 spdy::SpdySerializedFrame rst(
6707 spdy_util_.ConstructSpdyRstStream(3, spdy::ERROR_CODE_HTTP_1_1_REQUIRED));
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376708
Bence Béky3238f2e12017-09-22 22:44:496709 MockWrite writes0[] = {CreateMockWrite(request0, 0)};
6710 MockRead reads0[] = {CreateMockRead(resp, 1), MockRead(ASYNC, 0, 2)};
Bence Béky83eb3512017-09-05 12:56:096711
6712 // Retry yet again using HTTP/1.1.
6713 MockWrite writes1[] = {
6714 // After restarting with a null identity, this is the
6715 // request we should be issuing -- the final header line contains a Type
6716 // 1 message.
6717 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556718 "Host: server\r\n"
Bence Béky83eb3512017-09-05 12:56:096719 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376720 "Authorization: NTLM "),
6721 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
Bence Béky83eb3512017-09-05 12:56:096722
6723 // After calling trans.RestartWithAuth(), we should send a Type 3 message
6724 // (the credentials for the origin server). The second request continues
6725 // on the same connection.
6726 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556727 "Host: server\r\n"
Bence Béky83eb3512017-09-05 12:56:096728 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376729 "Authorization: NTLM "),
6730 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
Bence Béky83eb3512017-09-05 12:56:096731 };
6732
6733 MockRead reads1[] = {
6734 // The origin server responds with a Type 2 message.
6735 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376736 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6737 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky83eb3512017-09-05 12:56:096738 MockRead("Content-Type: text/html\r\n\r\n"),
6739 MockRead("You are not authorized to view this page\r\n"),
6740
6741 // Lastly we get the desired content.
6742 MockRead("HTTP/1.1 200 OK\r\n"),
6743 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
Bence Béky1e4ef192017-09-18 19:58:026744 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
Bence Béky83eb3512017-09-05 12:56:096745 };
Ryan Sleevib8d7ea02018-05-07 20:01:016746 SequencedSocketData data0(reads0, writes0);
6747 StaticSocketDataProvider data1(reads1, writes1);
Bence Béky83eb3512017-09-05 12:56:096748 session_deps_.socket_factory->AddSocketDataProvider(&data0);
6749 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6750
6751 SSLSocketDataProvider ssl0(ASYNC, OK);
6752 ssl0.next_proto = kProtoHTTP2;
6753 SSLSocketDataProvider ssl1(ASYNC, OK);
6754 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl0);
6755 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
6756
6757 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6758 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
6759
6760 TestCompletionCallback callback1;
6761 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
6762 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6763
6764 rv = callback1.WaitForResult();
6765 EXPECT_THAT(rv, IsOk());
6766
6767 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
6768
6769 const HttpResponseInfo* response = trans.GetResponseInfo();
6770 ASSERT_TRUE(response);
6771 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
6772
6773 TestCompletionCallback callback2;
6774
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376775 rv = trans.RestartWithAuth(
6776 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
6777 callback2.callback());
Bence Béky83eb3512017-09-05 12:56:096778 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6779
6780 rv = callback2.WaitForResult();
6781 EXPECT_THAT(rv, IsOk());
6782
6783 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
6784
6785 response = trans.GetResponseInfo();
6786 ASSERT_TRUE(response);
6787 EXPECT_FALSE(response->auth_challenge);
6788
6789 TestCompletionCallback callback3;
6790
6791 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
6792 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6793
6794 rv = callback3.WaitForResult();
6795 EXPECT_THAT(rv, IsOk());
6796
6797 response = trans.GetResponseInfo();
6798 ASSERT_TRUE(response);
6799 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:026800 EXPECT_EQ(14, response->headers->GetContentLength());
6801
6802 std::string response_data;
6803 rv = ReadTransaction(&trans, &response_data);
6804 EXPECT_THAT(rv, IsOk());
6805 EXPECT_EQ("Please Login\r\n", response_data);
6806
6807 EXPECT_TRUE(data0.AllReadDataConsumed());
6808 EXPECT_TRUE(data0.AllWriteDataConsumed());
6809 EXPECT_TRUE(data1.AllReadDataConsumed());
6810 EXPECT_TRUE(data1.AllWriteDataConsumed());
Bence Béky83eb3512017-09-05 12:56:096811}
David Benjamin5cb91132018-04-06 05:54:496812
6813// Test that, if we have an NTLM proxy and the origin resets the connection, we
6814// do no retry forever checking for TLS version interference. This is a
6815// regression test for https://crbug.com/823387.
6816TEST_F(HttpNetworkTransactionTest, NTLMProxyTLSHandshakeReset) {
6817 // The NTLM test data expects the proxy to be named 'server'. The origin is
6818 // https://origin/.
6819 session_deps_.proxy_resolution_service =
6820 ProxyResolutionService::CreateFixedFromPacResult(
6821 "PROXY server", TRAFFIC_ANNOTATION_FOR_TESTS);
6822
6823 SSLConfig config;
6824 config.version_max = SSL_PROTOCOL_VERSION_TLS1_3;
6825 session_deps_.ssl_config_service =
Ryan Sleevib8449e02018-07-15 04:31:076826 std::make_unique<TestSSLConfigService>(config);
David Benjamin5cb91132018-04-06 05:54:496827
6828 HttpRequestInfo request;
6829 request.method = "GET";
6830 request.url = GURL("https://origin/");
6831 request.traffic_annotation =
6832 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6833
6834 // Ensure load is not disrupted by flags which suppress behaviour specific
6835 // to other auth schemes.
6836 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
6837
6838 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
6839 MockGetMSTime, MockGenerateRandom, MockGetHostName);
6840 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6841
6842 // Generate the NTLM messages based on known test data.
6843 std::string negotiate_msg;
6844 std::string challenge_msg;
6845 std::string authenticate_msg;
6846 base::Base64Encode(
6847 base::StringPiece(
6848 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
6849 arraysize(ntlm::test::kExpectedNegotiateMsg)),
6850 &negotiate_msg);
6851 base::Base64Encode(
6852 base::StringPiece(
6853 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
6854 arraysize(ntlm::test::kChallengeMsgFromSpecV2)),
6855 &challenge_msg);
6856 base::Base64Encode(
6857 base::StringPiece(
6858 reinterpret_cast<const char*>(
6859 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
6860 arraysize(
6861 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
6862 &authenticate_msg);
6863
6864 MockWrite data_writes[] = {
6865 // The initial CONNECT request.
6866 MockWrite("CONNECT origin:443 HTTP/1.1\r\n"
6867 "Host: origin:443\r\n"
6868 "Proxy-Connection: keep-alive\r\n\r\n"),
6869
6870 // After restarting with an identity.
6871 MockWrite("CONNECT origin:443 HTTP/1.1\r\n"
6872 "Host: origin:443\r\n"
6873 "Proxy-Connection: keep-alive\r\n"
6874 "Proxy-Authorization: NTLM "),
6875 MockWrite(negotiate_msg.c_str()),
6876 // End headers.
6877 MockWrite("\r\n\r\n"),
6878
6879 // The second restart.
6880 MockWrite("CONNECT origin:443 HTTP/1.1\r\n"
6881 "Host: origin:443\r\n"
6882 "Proxy-Connection: keep-alive\r\n"
6883 "Proxy-Authorization: NTLM "),
6884 MockWrite(authenticate_msg.c_str()),
6885 // End headers.
6886 MockWrite("\r\n\r\n"),
6887 };
6888
6889 MockRead data_reads[] = {
6890 // The initial NTLM response.
6891 MockRead("HTTP/1.1 407 Access Denied\r\n"
6892 "Content-Length: 0\r\n"
6893 "Proxy-Authenticate: NTLM\r\n\r\n"),
6894
6895 // The NTLM challenge message.
6896 MockRead("HTTP/1.1 407 Access Denied\r\n"
6897 "Content-Length: 0\r\n"
6898 "Proxy-Authenticate: NTLM "),
6899 MockRead(challenge_msg.c_str()),
6900 // End headers.
6901 MockRead("\r\n\r\n"),
6902
6903 // Finally the tunnel is established.
6904 MockRead("HTTP/1.1 200 Connected\r\n\r\n"),
6905 };
6906
Ryan Sleevib8d7ea02018-05-07 20:01:016907 StaticSocketDataProvider data(data_reads, data_writes);
David Benjamin5cb91132018-04-06 05:54:496908 SSLSocketDataProvider data_ssl(ASYNC, ERR_CONNECTION_RESET);
Helen Li48f117e2018-05-29 20:38:406909 data_ssl.expected_ssl_version_max = SSL_PROTOCOL_VERSION_TLS1_3;
Ryan Sleevib8d7ea02018-05-07 20:01:016910 StaticSocketDataProvider data2(data_reads, data_writes);
David Benjamin5cb91132018-04-06 05:54:496911 SSLSocketDataProvider data_ssl2(ASYNC, ERR_CONNECTION_RESET);
6912 session_deps_.socket_factory->AddSocketDataProvider(&data);
6913 session_deps_.socket_factory->AddSSLSocketDataProvider(&data_ssl);
6914 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6915 session_deps_.socket_factory->AddSSLSocketDataProvider(&data_ssl2);
6916
6917 // Start the transaction. The proxy responds with an NTLM authentication
6918 // request.
6919 TestCompletionCallback callback;
6920 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
6921 int rv = callback.GetResult(
6922 trans.Start(&request, callback.callback(), NetLogWithSource()));
6923
6924 EXPECT_THAT(rv, IsOk());
6925 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
6926 const HttpResponseInfo* response = trans.GetResponseInfo();
6927 ASSERT_TRUE(response);
6928 EXPECT_TRUE(CheckNTLMProxyAuth(response->auth_challenge.get()));
6929
6930 // Configure credentials. The proxy responds with the challenge message.
6931 rv = callback.GetResult(trans.RestartWithAuth(
6932 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
6933 callback.callback()));
6934 EXPECT_THAT(rv, IsOk());
6935 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
6936 response = trans.GetResponseInfo();
6937 ASSERT_TRUE(response);
6938 EXPECT_FALSE(response->auth_challenge);
6939
6940 // Restart once more. The tunnel will be established and the the SSL handshake
6941 // will reset. The TLS 1.3 version interference probe will then kick in and
6942 // restart the process. The proxy responds with another NTLM authentiation
6943 // request, but we don't need to provide credentials as the cached ones work/
6944 rv = callback.GetResult(
6945 trans.RestartWithAuth(AuthCredentials(), callback.callback()));
6946 EXPECT_THAT(rv, IsOk());
6947 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
6948 response = trans.GetResponseInfo();
6949 ASSERT_TRUE(response);
6950 EXPECT_FALSE(response->auth_challenge);
6951
6952 // The proxy responds with the NTLM challenge message.
6953 rv = callback.GetResult(
6954 trans.RestartWithAuth(AuthCredentials(), callback.callback()));
6955 EXPECT_THAT(rv, IsOk());
6956 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
6957 response = trans.GetResponseInfo();
6958 ASSERT_TRUE(response);
6959 EXPECT_FALSE(response->auth_challenge);
6960
6961 // Send the NTLM authenticate message. The tunnel is established and the
6962 // handshake resets again. We should not retry again.
6963 rv = callback.GetResult(
6964 trans.RestartWithAuth(AuthCredentials(), callback.callback()));
6965 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
6966}
6967
[email protected]ea9dc9a2009-09-05 00:43:326968#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:296969
[email protected]4ddaf2502008-10-23 18:26:196970// Test reading a server response which has only headers, and no body.
6971// After some maximum number of bytes is consumed, the transaction should
6972// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
bncd16676a2016-07-20 16:23:016973TEST_F(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:426974 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:196975 request.method = "GET";
bncce36dca22015-04-21 22:11:236976 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:106977 request.traffic_annotation =
6978 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]4ddaf2502008-10-23 18:26:196979
danakj1fd259a02016-04-16 03:17:096980 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166981 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:276982
[email protected]b75b7b2f2009-10-06 00:54:536983 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:436984 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:536985 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:196986
6987 MockRead data_reads[] = {
6988 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:066989 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:196990 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:066991 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:196992 };
Ryan Sleevib8d7ea02018-05-07 20:01:016993 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:076994 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:196995
[email protected]49639fa2011-12-20 23:22:416996 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:196997
tfarina42834112016-09-22 13:38:206998 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016999 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]4ddaf2502008-10-23 18:26:197000
7001 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017002 EXPECT_THAT(rv, IsError(ERR_RESPONSE_HEADERS_TOO_BIG));
[email protected]4ddaf2502008-10-23 18:26:197003}
[email protected]f4e426b2008-11-05 00:24:497004
7005// Make sure that we don't try to reuse a TCPClientSocket when failing to
7006// establish tunnel.
7007// http://code.google.com/p/chromium/issues/detail?id=3772
bncd16676a2016-07-20 16:23:017008TEST_F(HttpNetworkTransactionTest, DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:277009 HttpRequestInfo request;
7010 request.method = "GET";
bncce36dca22015-04-21 22:11:237011 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:107012 request.traffic_annotation =
7013 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:277014
[email protected]f4e426b2008-11-05 00:24:497015 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:497016 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
7017 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]db8f44c2008-12-13 04:52:017018
danakj1fd259a02016-04-16 03:17:097019 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:497020
bnc87dcefc2017-05-25 12:47:587021 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:197022 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]f4e426b2008-11-05 00:24:497023
[email protected]f4e426b2008-11-05 00:24:497024 // Since we have proxy, should try to establish tunnel.
7025 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:177026 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7027 "Host: www.example.org:443\r\n"
7028 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:497029 };
7030
[email protected]77848d12008-11-14 00:00:227031 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:497032 // connection. Usually a proxy would return 501 (not implemented),
7033 // or 200 (tunnel established).
7034 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:237035 MockRead("HTTP/1.1 404 Not Found\r\n"),
7036 MockRead("Content-Length: 10\r\n\r\n"),
7037 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]f4e426b2008-11-05 00:24:497038 };
7039
Ryan Sleevib8d7ea02018-05-07 20:01:017040 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:077041 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:497042
[email protected]49639fa2011-12-20 23:22:417043 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:497044
tfarina42834112016-09-22 13:38:207045 int rv = trans->Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017046 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f4e426b2008-11-05 00:24:497047
7048 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017049 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]f4e426b2008-11-05 00:24:497050
[email protected]b4404c02009-04-10 16:38:527051 // Empty the current queue. This is necessary because idle sockets are
7052 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557053 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:527054
[email protected]f4e426b2008-11-05 00:24:497055 // We now check to make sure the TCPClientSocket was not added back to
7056 // the pool.
[email protected]90499482013-06-01 00:39:507057 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:497058 trans.reset();
fdoray92e35a72016-06-10 15:54:557059 base::RunLoop().RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:497060 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:507061 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:497062}
[email protected]372d34a2008-11-05 21:30:517063
[email protected]1b157c02009-04-21 01:55:407064// Make sure that we recycle a socket after reading all of the response body.
bncd16676a2016-07-20 16:23:017065TEST_F(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:427066 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:407067 request.method = "GET";
bncce36dca22015-04-21 22:11:237068 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:107069 request.traffic_annotation =
7070 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1b157c02009-04-21 01:55:407071
danakj1fd259a02016-04-16 03:17:097072 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277073
bnc691fda62016-08-12 00:43:167074 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277075
[email protected]1b157c02009-04-21 01:55:407076 MockRead data_reads[] = {
7077 // A part of the response body is received with the response headers.
7078 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
7079 // The rest of the response body is received in two parts.
7080 MockRead("lo"),
7081 MockRead(" world"),
7082 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:067083 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:407084 };
7085
Ryan Sleevib8d7ea02018-05-07 20:01:017086 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:077087 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:407088
[email protected]49639fa2011-12-20 23:22:417089 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:407090
tfarina42834112016-09-22 13:38:207091 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017092 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1b157c02009-04-21 01:55:407093
7094 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017095 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:407096
bnc691fda62016-08-12 00:43:167097 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527098 ASSERT_TRUE(response);
[email protected]1b157c02009-04-21 01:55:407099
wezca1070932016-05-26 20:30:527100 EXPECT_TRUE(response->headers);
[email protected]1b157c02009-04-21 01:55:407101 std::string status_line = response->headers->GetStatusLine();
7102 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
7103
[email protected]90499482013-06-01 00:39:507104 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:407105
7106 std::string response_data;
bnc691fda62016-08-12 00:43:167107 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017108 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:407109 EXPECT_EQ("hello world", response_data);
7110
7111 // Empty the current queue. This is necessary because idle sockets are
7112 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557113 base::RunLoop().RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:407114
7115 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507116 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:407117}
7118
[email protected]76a505b2010-08-25 06:23:007119// Make sure that we recycle a SSL socket after reading all of the response
7120// body.
bncd16676a2016-07-20 16:23:017121TEST_F(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:007122 HttpRequestInfo request;
7123 request.method = "GET";
bncce36dca22015-04-21 22:11:237124 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:107125 request.traffic_annotation =
7126 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:007127
7128 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237129 MockWrite(
7130 "GET / HTTP/1.1\r\n"
7131 "Host: www.example.org\r\n"
7132 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:007133 };
7134
7135 MockRead data_reads[] = {
7136 MockRead("HTTP/1.1 200 OK\r\n"),
7137 MockRead("Content-Length: 11\r\n\r\n"),
7138 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:067139 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:007140 };
7141
[email protected]8ddf8322012-02-23 18:08:067142 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077143 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:007144
Ryan Sleevib8d7ea02018-05-07 20:01:017145 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:077146 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:007147
[email protected]49639fa2011-12-20 23:22:417148 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:007149
danakj1fd259a02016-04-16 03:17:097150 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167151 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:007152
tfarina42834112016-09-22 13:38:207153 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:007154
robpercival214763f2016-07-01 23:27:017155 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7156 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:007157
bnc691fda62016-08-12 00:43:167158 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527159 ASSERT_TRUE(response);
7160 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:007161 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7162
[email protected]90499482013-06-01 00:39:507163 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007164
7165 std::string response_data;
bnc691fda62016-08-12 00:43:167166 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017167 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:007168 EXPECT_EQ("hello world", response_data);
7169
7170 // Empty the current queue. This is necessary because idle sockets are
7171 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557172 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:007173
7174 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507175 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007176}
7177
7178// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
7179// from the pool and make sure that we recover okay.
bncd16676a2016-07-20 16:23:017180TEST_F(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:007181 HttpRequestInfo request;
7182 request.method = "GET";
bncce36dca22015-04-21 22:11:237183 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:107184 request.traffic_annotation =
7185 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:007186
7187 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237188 MockWrite(
7189 "GET / HTTP/1.1\r\n"
7190 "Host: www.example.org\r\n"
7191 "Connection: keep-alive\r\n\r\n"),
7192 MockWrite(
7193 "GET / HTTP/1.1\r\n"
7194 "Host: www.example.org\r\n"
7195 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:007196 };
7197
7198 MockRead data_reads[] = {
mmenke911ee0222015-12-04 03:58:427199 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
7200 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
[email protected]76a505b2010-08-25 06:23:007201
[email protected]8ddf8322012-02-23 18:08:067202 SSLSocketDataProvider ssl(ASYNC, OK);
7203 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077204 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7205 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:007206
Ryan Sleevib8d7ea02018-05-07 20:01:017207 StaticSocketDataProvider data(data_reads, data_writes);
7208 StaticSocketDataProvider data2(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:077209 session_deps_.socket_factory->AddSocketDataProvider(&data);
7210 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:007211
[email protected]49639fa2011-12-20 23:22:417212 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:007213
danakj1fd259a02016-04-16 03:17:097214 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:587215 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:197216 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:007217
tfarina42834112016-09-22 13:38:207218 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:007219
robpercival214763f2016-07-01 23:27:017220 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7221 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:007222
7223 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:527224 ASSERT_TRUE(response);
7225 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:007226 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7227
[email protected]90499482013-06-01 00:39:507228 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007229
7230 std::string response_data;
7231 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:017232 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:007233 EXPECT_EQ("hello world", response_data);
7234
7235 // Empty the current queue. This is necessary because idle sockets are
7236 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557237 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:007238
7239 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507240 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007241
7242 // Now start the second transaction, which should reuse the previous socket.
7243
bnc87dcefc2017-05-25 12:47:587244 trans =
Jeremy Roman0579ed62017-08-29 15:56:197245 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:007246
tfarina42834112016-09-22 13:38:207247 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:007248
robpercival214763f2016-07-01 23:27:017249 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7250 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:007251
7252 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:527253 ASSERT_TRUE(response);
7254 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:007255 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7256
[email protected]90499482013-06-01 00:39:507257 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007258
7259 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:017260 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:007261 EXPECT_EQ("hello world", response_data);
7262
7263 // Empty the current queue. This is necessary because idle sockets are
7264 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557265 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:007266
7267 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507268 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007269}
7270
maksim.sisov0adf8592016-07-15 06:25:567271// Grab a socket, use it, and put it back into the pool. Then, make
7272// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:017273TEST_F(HttpNetworkTransactionTest, FlushSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:567274 HttpRequestInfo request;
7275 request.method = "GET";
7276 request.url = GURL("http://www.example.org/");
7277 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:107278 request.traffic_annotation =
7279 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
maksim.sisov0adf8592016-07-15 06:25:567280
7281 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7282
bnc691fda62016-08-12 00:43:167283 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:567284
7285 MockRead data_reads[] = {
7286 // A part of the response body is received with the response headers.
7287 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
7288 // The rest of the response body is received in two parts.
7289 MockRead("lo"), MockRead(" world"),
7290 MockRead("junk"), // Should not be read!!
7291 MockRead(SYNCHRONOUS, OK),
7292 };
7293
Ryan Sleevib8d7ea02018-05-07 20:01:017294 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
maksim.sisov0adf8592016-07-15 06:25:567295 session_deps_.socket_factory->AddSocketDataProvider(&data);
7296
7297 TestCompletionCallback callback;
7298
tfarina42834112016-09-22 13:38:207299 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:567300 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7301
7302 EXPECT_THAT(callback.GetResult(rv), IsOk());
7303
bnc691fda62016-08-12 00:43:167304 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:567305 ASSERT_TRUE(response);
7306 EXPECT_TRUE(response->headers);
7307 std::string status_line = response->headers->GetStatusLine();
7308 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
7309
7310 // Make memory critical notification and ensure the transaction still has been
7311 // operating right.
7312 base::MemoryPressureListener::NotifyMemoryPressure(
7313 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7314 base::RunLoop().RunUntilIdle();
7315
7316 // Socket should not be flushed as long as it is not idle.
7317 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
7318
7319 std::string response_data;
bnc691fda62016-08-12 00:43:167320 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:567321 EXPECT_THAT(rv, IsOk());
7322 EXPECT_EQ("hello world", response_data);
7323
7324 // Empty the current queue. This is necessary because idle sockets are
7325 // added to the connection pool asynchronously with a PostTask.
7326 base::RunLoop().RunUntilIdle();
7327
7328 // We now check to make sure the socket was added back to the pool.
7329 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
7330
7331 // Idle sockets should be flushed now.
7332 base::MemoryPressureListener::NotifyMemoryPressure(
7333 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7334 base::RunLoop().RunUntilIdle();
7335
7336 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
7337}
7338
yucliu48f235d2018-01-11 00:59:557339// Disable idle socket closing on memory pressure.
7340// Grab a socket, use it, and put it back into the pool. Then, make
7341// low memory notification and ensure the socket pool is NOT flushed.
7342TEST_F(HttpNetworkTransactionTest, NoFlushSocketPoolOnLowMemoryNotifications) {
7343 HttpRequestInfo request;
7344 request.method = "GET";
7345 request.url = GURL("http://www.example.org/");
7346 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:107347 request.traffic_annotation =
7348 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
yucliu48f235d2018-01-11 00:59:557349
7350 // Disable idle socket closing on memory pressure.
7351 session_deps_.disable_idle_sockets_close_on_memory_pressure = true;
7352 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7353
7354 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
7355
7356 MockRead data_reads[] = {
7357 // A part of the response body is received with the response headers.
7358 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
7359 // The rest of the response body is received in two parts.
7360 MockRead("lo"), MockRead(" world"),
7361 MockRead("junk"), // Should not be read!!
7362 MockRead(SYNCHRONOUS, OK),
7363 };
7364
Ryan Sleevib8d7ea02018-05-07 20:01:017365 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
yucliu48f235d2018-01-11 00:59:557366 session_deps_.socket_factory->AddSocketDataProvider(&data);
7367
7368 TestCompletionCallback callback;
7369
7370 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
7371 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7372
7373 EXPECT_THAT(callback.GetResult(rv), IsOk());
7374
7375 const HttpResponseInfo* response = trans.GetResponseInfo();
7376 ASSERT_TRUE(response);
7377 EXPECT_TRUE(response->headers);
7378 std::string status_line = response->headers->GetStatusLine();
7379 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
7380
7381 // Make memory critical notification and ensure the transaction still has been
7382 // operating right.
7383 base::MemoryPressureListener::NotifyMemoryPressure(
7384 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7385 base::RunLoop().RunUntilIdle();
7386
7387 // Socket should not be flushed as long as it is not idle.
7388 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
7389
7390 std::string response_data;
7391 rv = ReadTransaction(&trans, &response_data);
7392 EXPECT_THAT(rv, IsOk());
7393 EXPECT_EQ("hello world", response_data);
7394
7395 // Empty the current queue. This is necessary because idle sockets are
7396 // added to the connection pool asynchronously with a PostTask.
7397 base::RunLoop().RunUntilIdle();
7398
7399 // We now check to make sure the socket was added back to the pool.
7400 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
7401
7402 // Idle sockets should NOT be flushed on moderate memory pressure.
7403 base::MemoryPressureListener::NotifyMemoryPressure(
7404 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE);
7405 base::RunLoop().RunUntilIdle();
7406
7407 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
7408
7409 // Idle sockets should NOT be flushed on critical memory pressure.
7410 base::MemoryPressureListener::NotifyMemoryPressure(
7411 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7412 base::RunLoop().RunUntilIdle();
7413
7414 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
7415}
7416
maksim.sisov0adf8592016-07-15 06:25:567417// Grab an SSL socket, use it, and put it back into the pool. Then, make
7418// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:017419TEST_F(HttpNetworkTransactionTest, FlushSSLSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:567420 HttpRequestInfo request;
7421 request.method = "GET";
7422 request.url = GURL("https://www.example.org/");
7423 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:107424 request.traffic_annotation =
7425 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
maksim.sisov0adf8592016-07-15 06:25:567426
7427 MockWrite data_writes[] = {
7428 MockWrite("GET / HTTP/1.1\r\n"
7429 "Host: www.example.org\r\n"
7430 "Connection: keep-alive\r\n\r\n"),
7431 };
7432
7433 MockRead data_reads[] = {
7434 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
7435 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
7436
7437 SSLSocketDataProvider ssl(ASYNC, OK);
7438 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7439
Ryan Sleevib8d7ea02018-05-07 20:01:017440 StaticSocketDataProvider data(data_reads, data_writes);
maksim.sisov0adf8592016-07-15 06:25:567441 session_deps_.socket_factory->AddSocketDataProvider(&data);
7442
7443 TestCompletionCallback callback;
7444
7445 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167446 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:567447
7448 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
tfarina42834112016-09-22 13:38:207449 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:567450
7451 EXPECT_THAT(callback.GetResult(rv), IsOk());
7452
bnc691fda62016-08-12 00:43:167453 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:567454 ASSERT_TRUE(response);
7455 ASSERT_TRUE(response->headers);
7456 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7457
7458 // Make memory critical notification and ensure the transaction still has been
7459 // operating right.
7460 base::MemoryPressureListener::NotifyMemoryPressure(
7461 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7462 base::RunLoop().RunUntilIdle();
7463
7464 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
7465
7466 std::string response_data;
bnc691fda62016-08-12 00:43:167467 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:567468 EXPECT_THAT(rv, IsOk());
7469 EXPECT_EQ("hello world", response_data);
7470
7471 // Empty the current queue. This is necessary because idle sockets are
7472 // added to the connection pool asynchronously with a PostTask.
7473 base::RunLoop().RunUntilIdle();
7474
7475 // We now check to make sure the socket was added back to the pool.
7476 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
7477
7478 // Make memory notification once again and ensure idle socket is closed.
7479 base::MemoryPressureListener::NotifyMemoryPressure(
7480 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7481 base::RunLoop().RunUntilIdle();
7482
7483 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
7484}
7485
[email protected]b4404c02009-04-10 16:38:527486// Make sure that we recycle a socket after a zero-length response.
7487// http://crbug.com/9880
bncd16676a2016-07-20 16:23:017488TEST_F(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:427489 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:527490 request.method = "GET";
bncce36dca22015-04-21 22:11:237491 request.url = GURL(
7492 "http://www.example.org/csi?v=3&s=web&action=&"
7493 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
7494 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
7495 "rt=prt.2642,ol.2649,xjs.2951");
Ramin Halavatib5e433e62018-02-07 07:41:107496 request.traffic_annotation =
7497 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]b4404c02009-04-10 16:38:527498
danakj1fd259a02016-04-16 03:17:097499 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277500
[email protected]b4404c02009-04-10 16:38:527501 MockRead data_reads[] = {
7502 MockRead("HTTP/1.1 204 No Content\r\n"
7503 "Content-Length: 0\r\n"
7504 "Content-Type: text/html\r\n\r\n"),
7505 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:067506 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:527507 };
7508
Ryan Sleevib8d7ea02018-05-07 20:01:017509 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:077510 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:527511
mmenkecc2298e2015-12-07 18:20:187512 // Transaction must be created after the MockReads, so it's destroyed before
7513 // them.
bnc691fda62016-08-12 00:43:167514 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkecc2298e2015-12-07 18:20:187515
[email protected]49639fa2011-12-20 23:22:417516 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:527517
tfarina42834112016-09-22 13:38:207518 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017519 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]b4404c02009-04-10 16:38:527520
7521 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017522 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:527523
bnc691fda62016-08-12 00:43:167524 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527525 ASSERT_TRUE(response);
[email protected]b4404c02009-04-10 16:38:527526
wezca1070932016-05-26 20:30:527527 EXPECT_TRUE(response->headers);
[email protected]b4404c02009-04-10 16:38:527528 std::string status_line = response->headers->GetStatusLine();
7529 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
7530
[email protected]90499482013-06-01 00:39:507531 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:527532
7533 std::string response_data;
bnc691fda62016-08-12 00:43:167534 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017535 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:527536 EXPECT_EQ("", response_data);
7537
7538 // Empty the current queue. This is necessary because idle sockets are
7539 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557540 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:527541
7542 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507543 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:527544}
7545
bncd16676a2016-07-20 16:23:017546TEST_F(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
danakj1fd259a02016-04-16 03:17:097547 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:227548 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:197549 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:227550 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:277551
[email protected]1c773ea12009-04-28 19:58:427552 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:517553 // Transaction 1: a GET request that succeeds. The socket is recycled
7554 // after use.
7555 request[0].method = "GET";
7556 request[0].url = GURL("http://www.google.com/");
7557 request[0].load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:107558 request[0].traffic_annotation =
7559 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]372d34a2008-11-05 21:30:517560 // Transaction 2: a POST request. Reuses the socket kept alive from
7561 // transaction 1. The first attempts fails when writing the POST data.
7562 // This causes the transaction to retry with a new socket. The second
7563 // attempt succeeds.
7564 request[1].method = "POST";
7565 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:277566 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:517567 request[1].load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:107568 request[1].traffic_annotation =
7569 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]372d34a2008-11-05 21:30:517570
danakj1fd259a02016-04-16 03:17:097571 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:517572
7573 // The first socket is used for transaction 1 and the first attempt of
7574 // transaction 2.
7575
7576 // The response of transaction 1.
7577 MockRead data_reads1[] = {
7578 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
7579 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:067580 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:517581 };
7582 // The mock write results of transaction 1 and the first attempt of
7583 // transaction 2.
7584 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:067585 MockWrite(SYNCHRONOUS, 64), // GET
7586 MockWrite(SYNCHRONOUS, 93), // POST
7587 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:517588 };
Ryan Sleevib8d7ea02018-05-07 20:01:017589 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]372d34a2008-11-05 21:30:517590
7591 // The second socket is used for the second attempt of transaction 2.
7592
7593 // The response of transaction 2.
7594 MockRead data_reads2[] = {
7595 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
7596 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:067597 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:517598 };
7599 // The mock write results of the second attempt of transaction 2.
7600 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:067601 MockWrite(SYNCHRONOUS, 93), // POST
7602 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:517603 };
Ryan Sleevib8d7ea02018-05-07 20:01:017604 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]372d34a2008-11-05 21:30:517605
[email protected]bb88e1d32013-05-03 23:11:077606 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7607 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:517608
thestig9d3bb0c2015-01-24 00:49:517609 const char* const kExpectedResponseData[] = {
[email protected]372d34a2008-11-05 21:30:517610 "hello world", "welcome"
7611 };
7612
7613 for (int i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:167614 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]372d34a2008-11-05 21:30:517615
[email protected]49639fa2011-12-20 23:22:417616 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:517617
tfarina42834112016-09-22 13:38:207618 int rv = trans.Start(&request[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017619 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]372d34a2008-11-05 21:30:517620
7621 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017622 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:517623
bnc691fda62016-08-12 00:43:167624 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527625 ASSERT_TRUE(response);
[email protected]372d34a2008-11-05 21:30:517626
wezca1070932016-05-26 20:30:527627 EXPECT_TRUE(response->headers);
[email protected]372d34a2008-11-05 21:30:517628 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7629
7630 std::string response_data;
bnc691fda62016-08-12 00:43:167631 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017632 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:517633 EXPECT_EQ(kExpectedResponseData[i], response_data);
7634 }
7635}
[email protected]f9ee6b52008-11-08 06:46:237636
7637// Test the request-challenge-retry sequence for basic auth when there is
7638// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:167639// it fails the identity from the URL is used to answer the challenge.
bncd16676a2016-07-20 16:23:017640TEST_F(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:427641 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237642 request.method = "GET";
bncce36dca22015-04-21 22:11:237643 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:417644 request.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:107645 request.traffic_annotation =
7646 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]a97cca42009-08-14 01:00:297647
danakj1fd259a02016-04-16 03:17:097648 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167649 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277650
[email protected]a97cca42009-08-14 01:00:297651 // The password contains an escaped character -- for this test to pass it
7652 // will need to be unescaped by HttpNetworkTransaction.
7653 EXPECT_EQ("b%40r", request.url.password());
7654
[email protected]f9ee6b52008-11-08 06:46:237655 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237656 MockWrite(
7657 "GET / HTTP/1.1\r\n"
7658 "Host: www.example.org\r\n"
7659 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237660 };
7661
7662 MockRead data_reads1[] = {
7663 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7664 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7665 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067666 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237667 };
7668
[email protected]2262e3a2012-05-22 16:08:167669 // After the challenge above, the transaction will be restarted using the
7670 // identity from the url (foo, b@r) to answer the challenge.
7671 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237672 MockWrite(
7673 "GET / HTTP/1.1\r\n"
7674 "Host: www.example.org\r\n"
7675 "Connection: keep-alive\r\n"
7676 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167677 };
7678
7679 MockRead data_reads2[] = {
7680 MockRead("HTTP/1.0 200 OK\r\n"),
7681 MockRead("Content-Length: 100\r\n\r\n"),
7682 MockRead(SYNCHRONOUS, OK),
7683 };
7684
Ryan Sleevib8d7ea02018-05-07 20:01:017685 StaticSocketDataProvider data1(data_reads1, data_writes1);
7686 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:077687 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7688 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237689
[email protected]49639fa2011-12-20 23:22:417690 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:207691 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017692 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237693 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017694 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167695 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167696
7697 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167698 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017699 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167700 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017701 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167702 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227703
bnc691fda62016-08-12 00:43:167704 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527705 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:167706
7707 // There is no challenge info, since the identity in URL worked.
wezca1070932016-05-26 20:30:527708 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:167709
7710 EXPECT_EQ(100, response->headers->GetContentLength());
7711
7712 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557713 base::RunLoop().RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:167714}
7715
7716// Test the request-challenge-retry sequence for basic auth when there is an
7717// incorrect identity in the URL. The identity from the URL should be used only
7718// once.
bncd16676a2016-07-20 16:23:017719TEST_F(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:167720 HttpRequestInfo request;
7721 request.method = "GET";
7722 // Note: the URL has a username:password in it. The password "baz" is
7723 // wrong (should be "bar").
bncce36dca22015-04-21 22:11:237724 request.url = GURL("http://foo:[email protected]/");
[email protected]2262e3a2012-05-22 16:08:167725
7726 request.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:107727 request.traffic_annotation =
7728 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2262e3a2012-05-22 16:08:167729
danakj1fd259a02016-04-16 03:17:097730 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167731 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2262e3a2012-05-22 16:08:167732
7733 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237734 MockWrite(
7735 "GET / HTTP/1.1\r\n"
7736 "Host: www.example.org\r\n"
7737 "Connection: keep-alive\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167738 };
7739
7740 MockRead data_reads1[] = {
7741 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7742 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7743 MockRead("Content-Length: 10\r\n\r\n"),
7744 MockRead(SYNCHRONOUS, ERR_FAILED),
7745 };
7746
7747 // After the challenge above, the transaction will be restarted using the
7748 // identity from the url (foo, baz) to answer the challenge.
7749 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237750 MockWrite(
7751 "GET / HTTP/1.1\r\n"
7752 "Host: www.example.org\r\n"
7753 "Connection: keep-alive\r\n"
7754 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167755 };
7756
7757 MockRead data_reads2[] = {
7758 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7759 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7760 MockRead("Content-Length: 10\r\n\r\n"),
7761 MockRead(SYNCHRONOUS, ERR_FAILED),
7762 };
7763
7764 // After the challenge above, the transaction will be restarted using the
7765 // identity supplied by the user (foo, bar) to answer the challenge.
7766 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237767 MockWrite(
7768 "GET / HTTP/1.1\r\n"
7769 "Host: www.example.org\r\n"
7770 "Connection: keep-alive\r\n"
7771 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167772 };
7773
7774 MockRead data_reads3[] = {
7775 MockRead("HTTP/1.0 200 OK\r\n"),
7776 MockRead("Content-Length: 100\r\n\r\n"),
7777 MockRead(SYNCHRONOUS, OK),
7778 };
7779
Ryan Sleevib8d7ea02018-05-07 20:01:017780 StaticSocketDataProvider data1(data_reads1, data_writes1);
7781 StaticSocketDataProvider data2(data_reads2, data_writes2);
7782 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]bb88e1d32013-05-03 23:11:077783 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7784 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7785 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:167786
7787 TestCompletionCallback callback1;
7788
tfarina42834112016-09-22 13:38:207789 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017790 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167791
7792 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017793 EXPECT_THAT(rv, IsOk());
[email protected]2262e3a2012-05-22 16:08:167794
bnc691fda62016-08-12 00:43:167795 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167796 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167797 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017798 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167799 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017800 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167801 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167802
bnc691fda62016-08-12 00:43:167803 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527804 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:167805 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
7806
7807 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:167808 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:017809 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167810 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017811 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167812 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167813
bnc691fda62016-08-12 00:43:167814 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527815 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:167816
7817 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:527818 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:167819
7820 EXPECT_EQ(100, response->headers->GetContentLength());
7821
[email protected]ea9dc9a2009-09-05 00:43:327822 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557823 base::RunLoop().RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:327824}
7825
[email protected]2217aa22013-10-11 03:03:547826
7827// Test the request-challenge-retry sequence for basic auth when there is a
7828// correct identity in the URL, but its use is being suppressed. The identity
7829// from the URL should never be used.
bncd16676a2016-07-20 16:23:017830TEST_F(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
[email protected]2217aa22013-10-11 03:03:547831 HttpRequestInfo request;
7832 request.method = "GET";
bncce36dca22015-04-21 22:11:237833 request.url = GURL("http://foo:[email protected]/");
[email protected]2217aa22013-10-11 03:03:547834 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
Ramin Halavatib5e433e62018-02-07 07:41:107835 request.traffic_annotation =
7836 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2217aa22013-10-11 03:03:547837
danakj1fd259a02016-04-16 03:17:097838 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167839 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2217aa22013-10-11 03:03:547840
7841 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237842 MockWrite(
7843 "GET / HTTP/1.1\r\n"
7844 "Host: www.example.org\r\n"
7845 "Connection: keep-alive\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:547846 };
7847
7848 MockRead data_reads1[] = {
7849 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7850 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7851 MockRead("Content-Length: 10\r\n\r\n"),
7852 MockRead(SYNCHRONOUS, ERR_FAILED),
7853 };
7854
7855 // After the challenge above, the transaction will be restarted using the
7856 // identity supplied by the user, not the one in the URL, to answer the
7857 // challenge.
7858 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237859 MockWrite(
7860 "GET / HTTP/1.1\r\n"
7861 "Host: www.example.org\r\n"
7862 "Connection: keep-alive\r\n"
7863 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:547864 };
7865
7866 MockRead data_reads3[] = {
7867 MockRead("HTTP/1.0 200 OK\r\n"),
7868 MockRead("Content-Length: 100\r\n\r\n"),
7869 MockRead(SYNCHRONOUS, OK),
7870 };
7871
Ryan Sleevib8d7ea02018-05-07 20:01:017872 StaticSocketDataProvider data1(data_reads1, data_writes1);
7873 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]2217aa22013-10-11 03:03:547874 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7875 session_deps_.socket_factory->AddSocketDataProvider(&data3);
7876
7877 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:207878 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017879 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:547880 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017881 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167882 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:547883
bnc691fda62016-08-12 00:43:167884 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527885 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:547886 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
7887
7888 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:167889 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:017890 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:547891 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017892 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167893 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:547894
bnc691fda62016-08-12 00:43:167895 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527896 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:547897
7898 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:527899 EXPECT_FALSE(response->auth_challenge);
[email protected]2217aa22013-10-11 03:03:547900 EXPECT_EQ(100, response->headers->GetContentLength());
7901
7902 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557903 base::RunLoop().RunUntilIdle();
[email protected]2217aa22013-10-11 03:03:547904}
7905
[email protected]f9ee6b52008-11-08 06:46:237906// Test that previously tried username/passwords for a realm get re-used.
bncd16676a2016-07-20 16:23:017907TEST_F(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
danakj1fd259a02016-04-16 03:17:097908 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:237909
7910 // Transaction 1: authenticate (foo, bar) on MyRealm1
7911 {
[email protected]1c773ea12009-04-28 19:58:427912 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237913 request.method = "GET";
bncce36dca22015-04-21 22:11:237914 request.url = GURL("http://www.example.org/x/y/z");
Ramin Halavatib5e433e62018-02-07 07:41:107915 request.traffic_annotation =
7916 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:237917
bnc691fda62016-08-12 00:43:167918 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277919
[email protected]f9ee6b52008-11-08 06:46:237920 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237921 MockWrite(
7922 "GET /x/y/z HTTP/1.1\r\n"
7923 "Host: www.example.org\r\n"
7924 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237925 };
7926
7927 MockRead data_reads1[] = {
7928 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7929 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7930 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067931 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237932 };
7933
7934 // Resend with authorization (username=foo, password=bar)
7935 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237936 MockWrite(
7937 "GET /x/y/z HTTP/1.1\r\n"
7938 "Host: www.example.org\r\n"
7939 "Connection: keep-alive\r\n"
7940 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237941 };
7942
7943 // Sever accepts the authorization.
7944 MockRead data_reads2[] = {
7945 MockRead("HTTP/1.0 200 OK\r\n"),
7946 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067947 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237948 };
7949
Ryan Sleevib8d7ea02018-05-07 20:01:017950 StaticSocketDataProvider data1(data_reads1, data_writes1);
7951 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:077952 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7953 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237954
[email protected]49639fa2011-12-20 23:22:417955 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237956
tfarina42834112016-09-22 13:38:207957 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017958 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237959
7960 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017961 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237962
bnc691fda62016-08-12 00:43:167963 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527964 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047965 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:237966
[email protected]49639fa2011-12-20 23:22:417967 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:237968
bnc691fda62016-08-12 00:43:167969 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
7970 callback2.callback());
robpercival214763f2016-07-01 23:27:017971 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237972
7973 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017974 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237975
bnc691fda62016-08-12 00:43:167976 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527977 ASSERT_TRUE(response);
7978 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237979 EXPECT_EQ(100, response->headers->GetContentLength());
7980 }
7981
7982 // ------------------------------------------------------------------------
7983
7984 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
7985 {
[email protected]1c773ea12009-04-28 19:58:427986 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237987 request.method = "GET";
7988 // Note that Transaction 1 was at /x/y/z, so this is in the same
7989 // protection space as MyRealm1.
bncce36dca22015-04-21 22:11:237990 request.url = GURL("http://www.example.org/x/y/a/b");
Ramin Halavatib5e433e62018-02-07 07:41:107991 request.traffic_annotation =
7992 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:237993
bnc691fda62016-08-12 00:43:167994 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277995
[email protected]f9ee6b52008-11-08 06:46:237996 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237997 MockWrite(
7998 "GET /x/y/a/b HTTP/1.1\r\n"
7999 "Host: www.example.org\r\n"
8000 "Connection: keep-alive\r\n"
8001 // Send preemptive authorization for MyRealm1
8002 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238003 };
8004
8005 // The server didn't like the preemptive authorization, and
8006 // challenges us for a different realm (MyRealm2).
8007 MockRead data_reads1[] = {
8008 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8009 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
8010 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068011 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238012 };
8013
8014 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
8015 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238016 MockWrite(
8017 "GET /x/y/a/b HTTP/1.1\r\n"
8018 "Host: www.example.org\r\n"
8019 "Connection: keep-alive\r\n"
8020 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238021 };
8022
8023 // Sever accepts the authorization.
8024 MockRead data_reads2[] = {
8025 MockRead("HTTP/1.0 200 OK\r\n"),
8026 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068027 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238028 };
8029
Ryan Sleevib8d7ea02018-05-07 20:01:018030 StaticSocketDataProvider data1(data_reads1, data_writes1);
8031 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:078032 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8033 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:238034
[email protected]49639fa2011-12-20 23:22:418035 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238036
tfarina42834112016-09-22 13:38:208037 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018038 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238039
8040 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018041 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238042
bnc691fda62016-08-12 00:43:168043 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528044 ASSERT_TRUE(response);
8045 ASSERT_TRUE(response->auth_challenge);
[email protected]79cb5c12011-09-12 13:12:048046 EXPECT_FALSE(response->auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:438047 EXPECT_EQ("http://www.example.org",
8048 response->auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:048049 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
aberentbba302d2015-12-03 10:20:198050 EXPECT_EQ(kBasicAuthScheme, response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:238051
[email protected]49639fa2011-12-20 23:22:418052 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:238053
bnc691fda62016-08-12 00:43:168054 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
8055 callback2.callback());
robpercival214763f2016-07-01 23:27:018056 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238057
8058 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018059 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238060
bnc691fda62016-08-12 00:43:168061 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528062 ASSERT_TRUE(response);
8063 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238064 EXPECT_EQ(100, response->headers->GetContentLength());
8065 }
8066
8067 // ------------------------------------------------------------------------
8068
8069 // Transaction 3: Resend a request in MyRealm's protection space --
8070 // succeed with preemptive authorization.
8071 {
[email protected]1c773ea12009-04-28 19:58:428072 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238073 request.method = "GET";
bncce36dca22015-04-21 22:11:238074 request.url = GURL("http://www.example.org/x/y/z2");
Ramin Halavatib5e433e62018-02-07 07:41:108075 request.traffic_annotation =
8076 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238077
bnc691fda62016-08-12 00:43:168078 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278079
[email protected]f9ee6b52008-11-08 06:46:238080 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238081 MockWrite(
8082 "GET /x/y/z2 HTTP/1.1\r\n"
8083 "Host: www.example.org\r\n"
8084 "Connection: keep-alive\r\n"
8085 // The authorization for MyRealm1 gets sent preemptively
8086 // (since the url is in the same protection space)
8087 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238088 };
8089
8090 // Sever accepts the preemptive authorization
8091 MockRead data_reads1[] = {
8092 MockRead("HTTP/1.0 200 OK\r\n"),
8093 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068094 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238095 };
8096
Ryan Sleevib8d7ea02018-05-07 20:01:018097 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:078098 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:238099
[email protected]49639fa2011-12-20 23:22:418100 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238101
tfarina42834112016-09-22 13:38:208102 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018103 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238104
8105 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018106 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238107
bnc691fda62016-08-12 00:43:168108 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528109 ASSERT_TRUE(response);
[email protected]f9ee6b52008-11-08 06:46:238110
wezca1070932016-05-26 20:30:528111 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238112 EXPECT_EQ(100, response->headers->GetContentLength());
8113 }
8114
8115 // ------------------------------------------------------------------------
8116
8117 // Transaction 4: request another URL in MyRealm (however the
8118 // url is not known to belong to the protection space, so no pre-auth).
8119 {
[email protected]1c773ea12009-04-28 19:58:428120 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238121 request.method = "GET";
bncce36dca22015-04-21 22:11:238122 request.url = GURL("http://www.example.org/x/1");
Ramin Halavatib5e433e62018-02-07 07:41:108123 request.traffic_annotation =
8124 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238125
bnc691fda62016-08-12 00:43:168126 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278127
[email protected]f9ee6b52008-11-08 06:46:238128 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238129 MockWrite(
8130 "GET /x/1 HTTP/1.1\r\n"
8131 "Host: www.example.org\r\n"
8132 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238133 };
8134
8135 MockRead data_reads1[] = {
8136 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8137 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8138 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068139 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238140 };
8141
8142 // Resend with authorization from MyRealm's cache.
8143 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238144 MockWrite(
8145 "GET /x/1 HTTP/1.1\r\n"
8146 "Host: www.example.org\r\n"
8147 "Connection: keep-alive\r\n"
8148 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238149 };
8150
8151 // Sever accepts the authorization.
8152 MockRead data_reads2[] = {
8153 MockRead("HTTP/1.0 200 OK\r\n"),
8154 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068155 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238156 };
8157
Ryan Sleevib8d7ea02018-05-07 20:01:018158 StaticSocketDataProvider data1(data_reads1, data_writes1);
8159 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:078160 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8161 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:238162
[email protected]49639fa2011-12-20 23:22:418163 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238164
tfarina42834112016-09-22 13:38:208165 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018166 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238167
8168 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018169 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238170
bnc691fda62016-08-12 00:43:168171 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:418172 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:168173 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:018174 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:228175 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018176 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168177 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:228178
bnc691fda62016-08-12 00:43:168179 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528180 ASSERT_TRUE(response);
8181 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238182 EXPECT_EQ(100, response->headers->GetContentLength());
8183 }
8184
8185 // ------------------------------------------------------------------------
8186
8187 // Transaction 5: request a URL in MyRealm, but the server rejects the
8188 // cached identity. Should invalidate and re-prompt.
8189 {
[email protected]1c773ea12009-04-28 19:58:428190 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238191 request.method = "GET";
bncce36dca22015-04-21 22:11:238192 request.url = GURL("http://www.example.org/p/q/t");
Ramin Halavatib5e433e62018-02-07 07:41:108193 request.traffic_annotation =
8194 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238195
bnc691fda62016-08-12 00:43:168196 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278197
[email protected]f9ee6b52008-11-08 06:46:238198 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238199 MockWrite(
8200 "GET /p/q/t HTTP/1.1\r\n"
8201 "Host: www.example.org\r\n"
8202 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238203 };
8204
8205 MockRead data_reads1[] = {
8206 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8207 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8208 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068209 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238210 };
8211
8212 // Resend with authorization from cache for MyRealm.
8213 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238214 MockWrite(
8215 "GET /p/q/t HTTP/1.1\r\n"
8216 "Host: www.example.org\r\n"
8217 "Connection: keep-alive\r\n"
8218 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238219 };
8220
8221 // Sever rejects the authorization.
8222 MockRead data_reads2[] = {
8223 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8224 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8225 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068226 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238227 };
8228
8229 // At this point we should prompt for new credentials for MyRealm.
8230 // Restart with username=foo3, password=foo4.
8231 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:238232 MockWrite(
8233 "GET /p/q/t HTTP/1.1\r\n"
8234 "Host: www.example.org\r\n"
8235 "Connection: keep-alive\r\n"
8236 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238237 };
8238
8239 // Sever accepts the authorization.
8240 MockRead data_reads3[] = {
8241 MockRead("HTTP/1.0 200 OK\r\n"),
8242 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068243 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238244 };
8245
Ryan Sleevib8d7ea02018-05-07 20:01:018246 StaticSocketDataProvider data1(data_reads1, data_writes1);
8247 StaticSocketDataProvider data2(data_reads2, data_writes2);
8248 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]bb88e1d32013-05-03 23:11:078249 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8250 session_deps_.socket_factory->AddSocketDataProvider(&data2);
8251 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:238252
[email protected]49639fa2011-12-20 23:22:418253 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238254
tfarina42834112016-09-22 13:38:208255 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018256 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238257
8258 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018259 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238260
bnc691fda62016-08-12 00:43:168261 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:418262 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:168263 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:018264 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:228265 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018266 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168267 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:228268
bnc691fda62016-08-12 00:43:168269 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528270 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:048271 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:238272
[email protected]49639fa2011-12-20 23:22:418273 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:238274
bnc691fda62016-08-12 00:43:168275 rv = trans.RestartWithAuth(AuthCredentials(kFoo3, kBar3),
8276 callback3.callback());
robpercival214763f2016-07-01 23:27:018277 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238278
[email protected]0757e7702009-03-27 04:00:228279 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:018280 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238281
bnc691fda62016-08-12 00:43:168282 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528283 ASSERT_TRUE(response);
8284 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238285 EXPECT_EQ(100, response->headers->GetContentLength());
8286 }
8287}
[email protected]89ceba9a2009-03-21 03:46:068288
[email protected]3c32c5f2010-05-18 15:18:128289// Tests that nonce count increments when multiple auth attempts
8290// are started with the same nonce.
bncd16676a2016-07-20 16:23:018291TEST_F(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:448292 HttpAuthHandlerDigest::Factory* digest_factory =
8293 new HttpAuthHandlerDigest::Factory();
8294 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
8295 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
8296 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:078297 session_deps_.http_auth_handler_factory.reset(digest_factory);
danakj1fd259a02016-04-16 03:17:098298 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:128299
8300 // Transaction 1: authenticate (foo, bar) on MyRealm1
8301 {
[email protected]3c32c5f2010-05-18 15:18:128302 HttpRequestInfo request;
8303 request.method = "GET";
bncce36dca22015-04-21 22:11:238304 request.url = GURL("http://www.example.org/x/y/z");
Ramin Halavatib5e433e62018-02-07 07:41:108305 request.traffic_annotation =
8306 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3c32c5f2010-05-18 15:18:128307
bnc691fda62016-08-12 00:43:168308 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278309
[email protected]3c32c5f2010-05-18 15:18:128310 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238311 MockWrite(
8312 "GET /x/y/z HTTP/1.1\r\n"
8313 "Host: www.example.org\r\n"
8314 "Connection: keep-alive\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:128315 };
8316
8317 MockRead data_reads1[] = {
8318 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8319 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
8320 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068321 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:128322 };
8323
8324 // Resend with authorization (username=foo, password=bar)
8325 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238326 MockWrite(
8327 "GET /x/y/z HTTP/1.1\r\n"
8328 "Host: www.example.org\r\n"
8329 "Connection: keep-alive\r\n"
8330 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
8331 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
8332 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
8333 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:128334 };
8335
8336 // Sever accepts the authorization.
8337 MockRead data_reads2[] = {
zmo9528c9f42015-08-04 22:12:088338 MockRead("HTTP/1.0 200 OK\r\n"),
8339 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:128340 };
8341
Ryan Sleevib8d7ea02018-05-07 20:01:018342 StaticSocketDataProvider data1(data_reads1, data_writes1);
8343 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:078344 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8345 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:128346
[email protected]49639fa2011-12-20 23:22:418347 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:128348
tfarina42834112016-09-22 13:38:208349 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018350 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:128351
8352 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018353 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:128354
bnc691fda62016-08-12 00:43:168355 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528356 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:048357 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:128358
[email protected]49639fa2011-12-20 23:22:418359 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:128360
bnc691fda62016-08-12 00:43:168361 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
8362 callback2.callback());
robpercival214763f2016-07-01 23:27:018363 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:128364
8365 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018366 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:128367
bnc691fda62016-08-12 00:43:168368 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528369 ASSERT_TRUE(response);
8370 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:128371 }
8372
8373 // ------------------------------------------------------------------------
8374
8375 // Transaction 2: Request another resource in digestive's protection space.
8376 // This will preemptively add an Authorization header which should have an
8377 // "nc" value of 2 (as compared to 1 in the first use.
8378 {
[email protected]3c32c5f2010-05-18 15:18:128379 HttpRequestInfo request;
8380 request.method = "GET";
8381 // Note that Transaction 1 was at /x/y/z, so this is in the same
8382 // protection space as digest.
bncce36dca22015-04-21 22:11:238383 request.url = GURL("http://www.example.org/x/y/a/b");
Ramin Halavatib5e433e62018-02-07 07:41:108384 request.traffic_annotation =
8385 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3c32c5f2010-05-18 15:18:128386
bnc691fda62016-08-12 00:43:168387 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278388
[email protected]3c32c5f2010-05-18 15:18:128389 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238390 MockWrite(
8391 "GET /x/y/a/b HTTP/1.1\r\n"
8392 "Host: www.example.org\r\n"
8393 "Connection: keep-alive\r\n"
8394 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
8395 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
8396 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
8397 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:128398 };
8399
8400 // Sever accepts the authorization.
8401 MockRead data_reads1[] = {
8402 MockRead("HTTP/1.0 200 OK\r\n"),
8403 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068404 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:128405 };
8406
Ryan Sleevib8d7ea02018-05-07 20:01:018407 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:078408 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:128409
[email protected]49639fa2011-12-20 23:22:418410 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:128411
tfarina42834112016-09-22 13:38:208412 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018413 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:128414
8415 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018416 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:128417
bnc691fda62016-08-12 00:43:168418 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528419 ASSERT_TRUE(response);
8420 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:128421 }
8422}
8423
[email protected]89ceba9a2009-03-21 03:46:068424// Test the ResetStateForRestart() private method.
bncd16676a2016-07-20 16:23:018425TEST_F(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:068426 // Create a transaction (the dependencies aren't important).
danakj1fd259a02016-04-16 03:17:098427 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168428 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]89ceba9a2009-03-21 03:46:068429
8430 // Setup some state (which we expect ResetStateForRestart() will clear).
bnc691fda62016-08-12 00:43:168431 trans.read_buf_ = new IOBuffer(15);
8432 trans.read_buf_len_ = 15;
8433 trans.request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:068434
8435 // Setup state in response_
bnc691fda62016-08-12 00:43:168436 HttpResponseInfo* response = &trans.response_;
[email protected]0877e3d2009-10-17 22:29:578437 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:088438 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:578439 response->response_time = base::Time::Now();
8440 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:068441
8442 { // Setup state for response_.vary_data
8443 HttpRequestInfo request;
8444 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
8445 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:278446 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:438447 request.extra_headers.SetHeader("Foo", "1");
8448 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:508449 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:068450 }
8451
8452 // Cause the above state to be reset.
bnc691fda62016-08-12 00:43:168453 trans.ResetStateForRestart();
[email protected]89ceba9a2009-03-21 03:46:068454
8455 // Verify that the state that needed to be reset, has been reset.
bnc691fda62016-08-12 00:43:168456 EXPECT_FALSE(trans.read_buf_);
8457 EXPECT_EQ(0, trans.read_buf_len_);
8458 EXPECT_TRUE(trans.request_headers_.IsEmpty());
wezca1070932016-05-26 20:30:528459 EXPECT_FALSE(response->auth_challenge);
8460 EXPECT_FALSE(response->headers);
[email protected]34f40942010-10-04 00:34:048461 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:088462 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:578463 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:068464}
8465
[email protected]bacff652009-03-31 17:50:338466// Test HTTPS connections to a site with a bad certificate
bncd16676a2016-07-20 16:23:018467TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:338468 HttpRequestInfo request;
8469 request.method = "GET";
bncce36dca22015-04-21 22:11:238470 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:108471 request.traffic_annotation =
8472 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]bacff652009-03-31 17:50:338473
danakj1fd259a02016-04-16 03:17:098474 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168475 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278476
[email protected]bacff652009-03-31 17:50:338477 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238478 MockWrite(
8479 "GET / HTTP/1.1\r\n"
8480 "Host: www.example.org\r\n"
8481 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:338482 };
8483
8484 MockRead data_reads[] = {
8485 MockRead("HTTP/1.0 200 OK\r\n"),
8486 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8487 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068488 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:338489 };
8490
[email protected]5ecc992a42009-11-11 01:41:598491 StaticSocketDataProvider ssl_bad_certificate;
Ryan Sleevib8d7ea02018-05-07 20:01:018492 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:068493 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8494 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:338495
[email protected]bb88e1d32013-05-03 23:11:078496 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
8497 session_deps_.socket_factory->AddSocketDataProvider(&data);
8498 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
8499 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:338500
[email protected]49639fa2011-12-20 23:22:418501 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:338502
tfarina42834112016-09-22 13:38:208503 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018504 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:338505
8506 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018507 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:338508
bnc691fda62016-08-12 00:43:168509 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:018510 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:338511
8512 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018513 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:338514
bnc691fda62016-08-12 00:43:168515 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:338516
wezca1070932016-05-26 20:30:528517 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:338518 EXPECT_EQ(100, response->headers->GetContentLength());
8519}
8520
8521// Test HTTPS connections to a site with a bad certificate, going through a
8522// proxy
bncd16676a2016-07-20 16:23:018523TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
Ramin Halavatica8d5252018-03-12 05:33:498524 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
8525 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]bacff652009-03-31 17:50:338526
8527 HttpRequestInfo request;
8528 request.method = "GET";
bncce36dca22015-04-21 22:11:238529 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:108530 request.traffic_annotation =
8531 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]bacff652009-03-31 17:50:338532
8533 MockWrite proxy_writes[] = {
rsleevidb16bb02015-11-12 23:47:178534 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8535 "Host: www.example.org:443\r\n"
8536 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:338537 };
8538
8539 MockRead proxy_reads[] = {
8540 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068541 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:338542 };
8543
8544 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178545 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8546 "Host: www.example.org:443\r\n"
8547 "Proxy-Connection: keep-alive\r\n\r\n"),
8548 MockWrite("GET / HTTP/1.1\r\n"
8549 "Host: www.example.org\r\n"
8550 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:338551 };
8552
8553 MockRead data_reads[] = {
8554 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
8555 MockRead("HTTP/1.0 200 OK\r\n"),
8556 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8557 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068558 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:338559 };
8560
Ryan Sleevib8d7ea02018-05-07 20:01:018561 StaticSocketDataProvider ssl_bad_certificate(proxy_reads, proxy_writes);
8562 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:068563 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8564 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:338565
[email protected]bb88e1d32013-05-03 23:11:078566 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
8567 session_deps_.socket_factory->AddSocketDataProvider(&data);
8568 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
8569 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:338570
[email protected]49639fa2011-12-20 23:22:418571 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:338572
8573 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:078574 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:338575
danakj1fd259a02016-04-16 03:17:098576 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168577 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bacff652009-03-31 17:50:338578
tfarina42834112016-09-22 13:38:208579 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018580 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:338581
8582 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018583 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:338584
bnc691fda62016-08-12 00:43:168585 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:018586 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:338587
8588 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018589 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:338590
bnc691fda62016-08-12 00:43:168591 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:338592
wezca1070932016-05-26 20:30:528593 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:338594 EXPECT_EQ(100, response->headers->GetContentLength());
8595 }
8596}
8597
[email protected]2df19bb2010-08-25 20:13:468598
8599// Test HTTPS connections to a site, going through an HTTPS proxy
bncd16676a2016-07-20 16:23:018600TEST_F(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:598601 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:498602 ProxyResolutionService::CreateFixedFromPacResult(
8603 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:518604 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078605 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:468606
8607 HttpRequestInfo request;
8608 request.method = "GET";
bncce36dca22015-04-21 22:11:238609 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:108610 request.traffic_annotation =
8611 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:468612
8613 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178614 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8615 "Host: www.example.org:443\r\n"
8616 "Proxy-Connection: keep-alive\r\n\r\n"),
8617 MockWrite("GET / HTTP/1.1\r\n"
8618 "Host: www.example.org\r\n"
8619 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:468620 };
8621
8622 MockRead data_reads[] = {
8623 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
8624 MockRead("HTTP/1.1 200 OK\r\n"),
8625 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8626 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068627 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:468628 };
8629
Ryan Sleevib8d7ea02018-05-07 20:01:018630 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:068631 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
8632 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:468633
[email protected]bb88e1d32013-05-03 23:11:078634 session_deps_.socket_factory->AddSocketDataProvider(&data);
8635 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
8636 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:468637
[email protected]49639fa2011-12-20 23:22:418638 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:468639
danakj1fd259a02016-04-16 03:17:098640 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168641 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:468642
tfarina42834112016-09-22 13:38:208643 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018644 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:468645
8646 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018647 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168648 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:468649
wezca1070932016-05-26 20:30:528650 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:468651
tbansal2ecbbc72016-10-06 17:15:478652 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:468653 EXPECT_TRUE(response->headers->IsKeepAlive());
8654 EXPECT_EQ(200, response->headers->response_code());
8655 EXPECT_EQ(100, response->headers->GetContentLength());
8656 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:208657
8658 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:168659 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:208660 TestLoadTimingNotReusedWithPac(load_timing_info,
8661 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:468662}
8663
[email protected]511f6f52010-12-17 03:58:298664// Test an HTTPS Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:018665TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:598666 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:498667 ProxyResolutionService::CreateFixedFromPacResult(
8668 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:518669 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078670 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:298671
8672 HttpRequestInfo request;
8673 request.method = "GET";
bncce36dca22015-04-21 22:11:238674 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:108675 request.traffic_annotation =
8676 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298677
8678 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178679 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8680 "Host: www.example.org:443\r\n"
8681 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:298682 };
8683
8684 MockRead data_reads[] = {
8685 MockRead("HTTP/1.1 302 Redirect\r\n"),
8686 MockRead("Location: http://login.example.com/\r\n"),
8687 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068688 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:298689 };
8690
Ryan Sleevib8d7ea02018-05-07 20:01:018691 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:068692 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:298693
[email protected]bb88e1d32013-05-03 23:11:078694 session_deps_.socket_factory->AddSocketDataProvider(&data);
8695 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298696
[email protected]49639fa2011-12-20 23:22:418697 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298698
danakj1fd259a02016-04-16 03:17:098699 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168700 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298701
tfarina42834112016-09-22 13:38:208702 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018703 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298704
8705 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018706 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168707 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:298708
wezca1070932016-05-26 20:30:528709 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:298710
8711 EXPECT_EQ(302, response->headers->response_code());
8712 std::string url;
8713 EXPECT_TRUE(response->headers->IsRedirect(&url));
8714 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:208715
8716 // In the case of redirects from proxies, HttpNetworkTransaction returns
8717 // timing for the proxy connection instead of the connection to the host,
8718 // and no send / receive times.
8719 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
8720 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:168721 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:208722
8723 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:198724 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:208725
8726 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
8727 EXPECT_LE(load_timing_info.proxy_resolve_start,
8728 load_timing_info.proxy_resolve_end);
8729 EXPECT_LE(load_timing_info.proxy_resolve_end,
8730 load_timing_info.connect_timing.connect_start);
8731 ExpectConnectTimingHasTimes(
8732 load_timing_info.connect_timing,
8733 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
8734
8735 EXPECT_TRUE(load_timing_info.send_start.is_null());
8736 EXPECT_TRUE(load_timing_info.send_end.is_null());
8737 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:298738}
8739
8740// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:018741TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
Ramin Halavatica8d5252018-03-12 05:33:498742 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
8743 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298744
8745 HttpRequestInfo request;
8746 request.method = "GET";
bncce36dca22015-04-21 22:11:238747 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:108748 request.traffic_annotation =
8749 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298750
Ryan Hamilton0239aac2018-05-19 00:03:138751 spdy::SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238752 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:138753 spdy::SpdySerializedFrame goaway(
8754 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:298755 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:418756 CreateMockWrite(conn, 0, SYNCHRONOUS),
8757 CreateMockWrite(goaway, 2, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:298758 };
8759
8760 static const char* const kExtraHeaders[] = {
8761 "location",
8762 "http://login.example.com/",
8763 };
Ryan Hamilton0239aac2018-05-19 00:03:138764 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:238765 "302", kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
[email protected]511f6f52010-12-17 03:58:298766 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:418767 CreateMockRead(resp, 1), MockRead(ASYNC, 0, 3), // EOF
[email protected]511f6f52010-12-17 03:58:298768 };
8769
Ryan Sleevib8d7ea02018-05-07 20:01:018770 SequencedSocketData data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:068771 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:368772 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:298773
[email protected]bb88e1d32013-05-03 23:11:078774 session_deps_.socket_factory->AddSocketDataProvider(&data);
8775 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298776
[email protected]49639fa2011-12-20 23:22:418777 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298778
danakj1fd259a02016-04-16 03:17:098779 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168780 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298781
tfarina42834112016-09-22 13:38:208782 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018783 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298784
8785 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018786 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168787 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:298788
wezca1070932016-05-26 20:30:528789 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:298790
8791 EXPECT_EQ(302, response->headers->response_code());
8792 std::string url;
8793 EXPECT_TRUE(response->headers->IsRedirect(&url));
8794 EXPECT_EQ("http://login.example.com/", url);
8795}
8796
[email protected]4eddbc732012-08-09 05:40:178797// Test that an HTTPS proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:018798TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaHttpsProxy) {
Ramin Halavatica8d5252018-03-12 05:33:498799 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
8800 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298801
8802 HttpRequestInfo request;
8803 request.method = "GET";
bncce36dca22015-04-21 22:11:238804 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:108805 request.traffic_annotation =
8806 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298807
8808 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178809 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8810 "Host: www.example.org:443\r\n"
8811 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:298812 };
8813
8814 MockRead data_reads[] = {
8815 MockRead("HTTP/1.1 404 Not Found\r\n"),
8816 MockRead("Content-Length: 23\r\n\r\n"),
8817 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:068818 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:298819 };
8820
Ryan Sleevib8d7ea02018-05-07 20:01:018821 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:068822 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:298823
[email protected]bb88e1d32013-05-03 23:11:078824 session_deps_.socket_factory->AddSocketDataProvider(&data);
8825 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298826
[email protected]49639fa2011-12-20 23:22:418827 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298828
danakj1fd259a02016-04-16 03:17:098829 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168830 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298831
tfarina42834112016-09-22 13:38:208832 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018833 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298834
8835 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018836 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:298837
ttuttle960fcbf2016-04-19 13:26:328838 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:298839}
8840
[email protected]4eddbc732012-08-09 05:40:178841// Test that a SPDY proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:018842TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaSpdyProxy) {
Ramin Halavatica8d5252018-03-12 05:33:498843 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
8844 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298845
8846 HttpRequestInfo request;
8847 request.method = "GET";
bncce36dca22015-04-21 22:11:238848 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:108849 request.traffic_annotation =
8850 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298851
Ryan Hamilton0239aac2018-05-19 00:03:138852 spdy::SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238853 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:138854 spdy::SpdySerializedFrame rst(
8855 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:298856 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:418857 CreateMockWrite(conn, 0), CreateMockWrite(rst, 3),
[email protected]511f6f52010-12-17 03:58:298858 };
8859
8860 static const char* const kExtraHeaders[] = {
8861 "location",
8862 "http://login.example.com/",
8863 };
Ryan Hamilton0239aac2018-05-19 00:03:138864 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:238865 "404", kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
Ryan Hamilton0239aac2018-05-19 00:03:138866 spdy::SpdySerializedFrame body(
Bence Békyd74f4382018-02-20 18:26:198867 spdy_util_.ConstructSpdyDataFrame(1, "The host does not exist", true));
[email protected]511f6f52010-12-17 03:58:298868 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:418869 CreateMockRead(resp, 1), CreateMockRead(body, 2),
rch8e6c6c42015-05-01 14:05:138870 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:298871 };
8872
Ryan Sleevib8d7ea02018-05-07 20:01:018873 SequencedSocketData data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:068874 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:368875 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:298876
[email protected]bb88e1d32013-05-03 23:11:078877 session_deps_.socket_factory->AddSocketDataProvider(&data);
8878 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298879
[email protected]49639fa2011-12-20 23:22:418880 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298881
danakj1fd259a02016-04-16 03:17:098882 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168883 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298884
tfarina42834112016-09-22 13:38:208885 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018886 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298887
8888 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018889 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:298890
ttuttle960fcbf2016-04-19 13:26:328891 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:298892}
8893
[email protected]0c5fb722012-02-28 11:50:358894// Test the request-challenge-retry sequence for basic auth, through
8895// a SPDY proxy over a single SPDY session.
bncd16676a2016-07-20 16:23:018896TEST_F(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:358897 HttpRequestInfo request;
8898 request.method = "GET";
bncce36dca22015-04-21 22:11:238899 request.url = GURL("https://www.example.org/");
[email protected]0c5fb722012-02-28 11:50:358900 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:298901 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:108902 request.traffic_annotation =
8903 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0c5fb722012-02-28 11:50:358904
8905 // Configure against https proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:598906 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:498907 ProxyResolutionService::CreateFixedFromPacResult(
8908 "HTTPS myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:518909 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078910 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:098911 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:358912
8913 // Since we have proxy, should try to establish tunnel.
Ryan Hamilton0239aac2018-05-19 00:03:138914 spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238915 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:138916 spdy::SpdySerializedFrame rst(
8917 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
rdsmithebb50aa2015-11-12 03:44:388918 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]0c5fb722012-02-28 11:50:358919
bnc691fda62016-08-12 00:43:168920 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0c5fb722012-02-28 11:50:358921 // be issuing -- the final header line contains the credentials.
8922 const char* const kAuthCredentials[] = {
8923 "proxy-authorization", "Basic Zm9vOmJhcg==",
8924 };
Ryan Hamilton0239aac2018-05-19 00:03:138925 spdy::SpdySerializedFrame connect2(spdy_util_.ConstructSpdyConnect(
lgarrona91df87f2014-12-05 00:51:348926 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST,
bncce36dca22015-04-21 22:11:238927 HostPortPair("www.example.org", 443)));
8928 // fetch https://www.example.org/ via HTTP
8929 const char get[] =
8930 "GET / HTTP/1.1\r\n"
8931 "Host: www.example.org\r\n"
8932 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:138933 spdy::SpdySerializedFrame wrapped_get(
Bence Békyd74f4382018-02-20 18:26:198934 spdy_util_.ConstructSpdyDataFrame(3, get, false));
[email protected]0c5fb722012-02-28 11:50:358935
8936 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418937 CreateMockWrite(req, 0, ASYNC), CreateMockWrite(rst, 2, ASYNC),
8938 CreateMockWrite(connect2, 3), CreateMockWrite(wrapped_get, 5),
[email protected]0c5fb722012-02-28 11:50:358939 };
8940
8941 // The proxy responds to the connect with a 407, using a persistent
8942 // connection.
thestig9d3bb0c2015-01-24 00:49:518943 const char kAuthStatus[] = "407";
[email protected]0c5fb722012-02-28 11:50:358944 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:358945 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
8946 };
Ryan Hamilton0239aac2018-05-19 00:03:138947 spdy::SpdySerializedFrame conn_auth_resp(spdy_util_.ConstructSpdyReplyError(
bncdf80d44fd2016-07-15 20:27:418948 kAuthStatus, kAuthChallenge, arraysize(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:358949
Ryan Hamilton0239aac2018-05-19 00:03:138950 spdy::SpdySerializedFrame conn_resp(
8951 spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:358952 const char resp[] = "HTTP/1.1 200 OK\r\n"
8953 "Content-Length: 5\r\n\r\n";
8954
Ryan Hamilton0239aac2018-05-19 00:03:138955 spdy::SpdySerializedFrame wrapped_get_resp(
Bence Békyd74f4382018-02-20 18:26:198956 spdy_util_.ConstructSpdyDataFrame(3, resp, false));
Ryan Hamilton0239aac2018-05-19 00:03:138957 spdy::SpdySerializedFrame wrapped_body(
Bence Békyd74f4382018-02-20 18:26:198958 spdy_util_.ConstructSpdyDataFrame(3, "hello", false));
[email protected]0c5fb722012-02-28 11:50:358959 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418960 CreateMockRead(conn_auth_resp, 1, ASYNC),
8961 CreateMockRead(conn_resp, 4, ASYNC),
8962 CreateMockRead(wrapped_get_resp, 6, ASYNC),
8963 CreateMockRead(wrapped_body, 7, ASYNC),
rch8e6c6c42015-05-01 14:05:138964 MockRead(ASYNC, OK, 8), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:358965 };
8966
Ryan Sleevib8d7ea02018-05-07 20:01:018967 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:078968 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:358969 // Negotiate SPDY to the proxy
8970 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368971 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:078972 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:358973 // Vanilla SSL to the server
8974 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078975 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:358976
8977 TestCompletionCallback callback1;
8978
bnc87dcefc2017-05-25 12:47:588979 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:198980 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0c5fb722012-02-28 11:50:358981
8982 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018983 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:358984
8985 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018986 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:468987 TestNetLogEntry::List entries;
[email protected]0c5fb722012-02-28 11:50:358988 log.GetEntries(&entries);
8989 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:008990 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
8991 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:358992 ExpectLogContainsSomewhere(
8993 entries, pos,
mikecirone8b85c432016-09-08 19:11:008994 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
8995 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:358996
8997 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528998 ASSERT_TRUE(response);
8999 ASSERT_TRUE(response->headers);
[email protected]0c5fb722012-02-28 11:50:359000 EXPECT_EQ(407, response->headers->response_code());
9001 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
wezca1070932016-05-26 20:30:529002 EXPECT_TRUE(response->auth_challenge);
asanka098c0092016-06-16 20:18:439003 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]0c5fb722012-02-28 11:50:359004
9005 TestCompletionCallback callback2;
9006
9007 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
9008 callback2.callback());
robpercival214763f2016-07-01 23:27:019009 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:359010
9011 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:019012 EXPECT_THAT(rv, IsOk());
[email protected]0c5fb722012-02-28 11:50:359013
9014 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529015 ASSERT_TRUE(response);
[email protected]0c5fb722012-02-28 11:50:359016
9017 EXPECT_TRUE(response->headers->IsKeepAlive());
9018 EXPECT_EQ(200, response->headers->response_code());
9019 EXPECT_EQ(5, response->headers->GetContentLength());
9020 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
9021
9022 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:529023 EXPECT_FALSE(response->auth_challenge);
[email protected]0c5fb722012-02-28 11:50:359024
[email protected]029c83b62013-01-24 05:28:209025 LoadTimingInfo load_timing_info;
9026 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
9027 TestLoadTimingNotReusedWithPac(load_timing_info,
9028 CONNECT_TIMING_HAS_SSL_TIMES);
9029
[email protected]0c5fb722012-02-28 11:50:359030 trans.reset();
9031 session->CloseAllConnections();
9032}
9033
[email protected]7c6f7ba2012-04-03 04:09:299034// Test that an explicitly trusted SPDY proxy can push a resource from an
9035// origin that is different from that of its associated resource.
bncd16676a2016-07-20 16:23:019036TEST_F(HttpNetworkTransactionTest, CrossOriginSPDYProxyPush) {
tbansal28e68f82016-02-04 02:56:159037 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:199038 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:159039 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
9040 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]7c6f7ba2012-04-03 04:09:299041 HttpRequestInfo request;
9042 HttpRequestInfo push_request;
Ramin Halavatib5e433e62018-02-07 07:41:109043 request.traffic_annotation =
9044 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7c6f7ba2012-04-03 04:09:299045
[email protected]7c6f7ba2012-04-03 04:09:299046 request.method = "GET";
bncce36dca22015-04-21 22:11:239047 request.url = GURL("http://www.example.org/");
[email protected]7c6f7ba2012-04-03 04:09:299048 push_request.method = "GET";
9049 push_request.url = GURL("http://www.another-origin.com/foo.dat");
Ramin Halavatib5e433e62018-02-07 07:41:109050 push_request.traffic_annotation =
9051 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7c6f7ba2012-04-03 04:09:299052
tbansal28e68f82016-02-04 02:56:159053 // Configure against https proxy server "myproxy:443".
Lily Houghton8c2f97d2018-01-22 05:06:599054 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499055 ProxyResolutionService::CreateFixedFromPacResult(
9056 "HTTPS myproxy:443", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519057 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:079058 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:509059
inlinechan894515af2016-12-09 02:40:109060 session_deps_.proxy_delegate = std::move(proxy_delegate);
[email protected]61b4efc2012-04-27 18:12:509061
danakj1fd259a02016-04-16 03:17:099062 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:299063
Ryan Hamilton0239aac2018-05-19 00:03:139064 spdy::SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:459065 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:139066 spdy::SpdySerializedFrame stream2_priority(
tombergan5d22c182017-01-11 02:05:359067 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
[email protected]7c6f7ba2012-04-03 04:09:299068
9069 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:419070 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:359071 CreateMockWrite(stream2_priority, 3, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:299072 };
9073
Ryan Hamilton0239aac2018-05-19 00:03:139074 spdy::SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
Bence Béky7bf94362018-01-10 13:19:369075 NULL, 0, 2, 1, "http://www.another-origin.com/foo.dat"));
9076
Ryan Hamilton0239aac2018-05-19 00:03:139077 spdy::SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:159078 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:299079
Ryan Hamilton0239aac2018-05-19 00:03:139080 spdy::SpdySerializedFrame stream1_body(
9081 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:299082
Ryan Hamilton0239aac2018-05-19 00:03:139083 spdy::SpdySerializedFrame stream2_body(
Bence Békyd74f4382018-02-20 18:26:199084 spdy_util_.ConstructSpdyDataFrame(2, "pushed", true));
[email protected]7c6f7ba2012-04-03 04:09:299085
9086 MockRead spdy_reads[] = {
Bence Béky7bf94362018-01-10 13:19:369087 CreateMockRead(stream2_syn, 1, ASYNC),
9088 CreateMockRead(stream1_reply, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:359089 CreateMockRead(stream1_body, 4, ASYNC),
9090 CreateMockRead(stream2_body, 5, ASYNC),
9091 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
[email protected]7c6f7ba2012-04-03 04:09:299092 };
9093
Ryan Sleevib8d7ea02018-05-07 20:01:019094 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:079095 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:299096 // Negotiate SPDY to the proxy
9097 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:369098 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:079099 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:299100
bnc87dcefc2017-05-25 12:47:589101 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:199102 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7c6f7ba2012-04-03 04:09:299103 TestCompletionCallback callback;
9104 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:019105 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:299106
9107 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019108 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:299109 const HttpResponseInfo* response = trans->GetResponseInfo();
9110
bnc87dcefc2017-05-25 12:47:589111 auto push_trans =
Jeremy Roman0579ed62017-08-29 15:56:199112 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]90499482013-06-01 00:39:509113 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:019114 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:299115
9116 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019117 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:299118 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
9119
wezca1070932016-05-26 20:30:529120 ASSERT_TRUE(response);
[email protected]7c6f7ba2012-04-03 04:09:299121 EXPECT_TRUE(response->headers->IsKeepAlive());
9122
9123 EXPECT_EQ(200, response->headers->response_code());
9124 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
9125
9126 std::string response_data;
9127 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:019128 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:299129 EXPECT_EQ("hello!", response_data);
9130
[email protected]029c83b62013-01-24 05:28:209131 LoadTimingInfo load_timing_info;
9132 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
9133 TestLoadTimingNotReusedWithPac(load_timing_info,
9134 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9135
[email protected]7c6f7ba2012-04-03 04:09:299136 // Verify the pushed stream.
wezca1070932016-05-26 20:30:529137 EXPECT_TRUE(push_response->headers);
[email protected]7c6f7ba2012-04-03 04:09:299138 EXPECT_EQ(200, push_response->headers->response_code());
9139
9140 rv = ReadTransaction(push_trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:019141 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:299142 EXPECT_EQ("pushed", response_data);
9143
[email protected]029c83b62013-01-24 05:28:209144 LoadTimingInfo push_load_timing_info;
9145 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
9146 TestLoadTimingReusedWithPac(push_load_timing_info);
9147 // The transactions should share a socket ID, despite being for different
9148 // origins.
9149 EXPECT_EQ(load_timing_info.socket_log_id,
9150 push_load_timing_info.socket_log_id);
9151
[email protected]7c6f7ba2012-04-03 04:09:299152 trans.reset();
9153 push_trans.reset();
9154 session->CloseAllConnections();
9155}
9156
[email protected]8c843192012-04-05 07:15:009157// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
bncd16676a2016-07-20 16:23:019158TEST_F(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:159159 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:199160 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:159161 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
9162 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]8c843192012-04-05 07:15:009163 HttpRequestInfo request;
9164
9165 request.method = "GET";
bncce36dca22015-04-21 22:11:239166 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109167 request.traffic_annotation =
9168 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c843192012-04-05 07:15:009169
Ramin Halavatica8d5252018-03-12 05:33:499170 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9171 "https://myproxy:443", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519172 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:079173 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:509174
9175 // Enable cross-origin push.
inlinechan894515af2016-12-09 02:40:109176 session_deps_.proxy_delegate = std::move(proxy_delegate);
[email protected]61b4efc2012-04-27 18:12:509177
danakj1fd259a02016-04-16 03:17:099178 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:009179
Ryan Hamilton0239aac2018-05-19 00:03:139180 spdy::SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:459181 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
[email protected]8c843192012-04-05 07:15:009182
Ryan Hamilton0239aac2018-05-19 00:03:139183 spdy::SpdySerializedFrame push_rst(
9184 spdy_util_.ConstructSpdyRstStream(2, spdy::ERROR_CODE_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:009185
9186 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:419187 CreateMockWrite(stream1_syn, 0, ASYNC), CreateMockWrite(push_rst, 3),
[email protected]8c843192012-04-05 07:15:009188 };
9189
Ryan Hamilton0239aac2018-05-19 00:03:139190 spdy::SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:159191 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:009192
Ryan Hamilton0239aac2018-05-19 00:03:139193 spdy::SpdySerializedFrame stream1_body(
9194 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]8c843192012-04-05 07:15:009195
Ryan Hamilton0239aac2018-05-19 00:03:139196 spdy::SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
bncb03b1092016-04-06 11:19:559197 NULL, 0, 2, 1, "https://www.another-origin.com/foo.dat"));
[email protected]8c843192012-04-05 07:15:009198
9199 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:419200 CreateMockRead(stream1_reply, 1, ASYNC),
9201 CreateMockRead(stream2_syn, 2, ASYNC),
9202 CreateMockRead(stream1_body, 4, ASYNC),
mmenkee24011922015-12-17 22:12:599203 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
[email protected]8c843192012-04-05 07:15:009204 };
9205
Ryan Sleevib8d7ea02018-05-07 20:01:019206 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:079207 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:009208 // Negotiate SPDY to the proxy
9209 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:369210 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:079211 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:009212
bnc87dcefc2017-05-25 12:47:589213 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:199214 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]8c843192012-04-05 07:15:009215 TestCompletionCallback callback;
9216 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:019217 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c843192012-04-05 07:15:009218
9219 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019220 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:009221 const HttpResponseInfo* response = trans->GetResponseInfo();
9222
wezca1070932016-05-26 20:30:529223 ASSERT_TRUE(response);
[email protected]8c843192012-04-05 07:15:009224 EXPECT_TRUE(response->headers->IsKeepAlive());
9225
9226 EXPECT_EQ(200, response->headers->response_code());
9227 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
9228
9229 std::string response_data;
9230 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:019231 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:009232 EXPECT_EQ("hello!", response_data);
9233
9234 trans.reset();
9235 session->CloseAllConnections();
9236}
9237
tbansal8ef1d3e2016-02-03 04:05:429238// Test that an explicitly trusted SPDY proxy can push same-origin HTTPS
9239// resources.
bncd16676a2016-07-20 16:23:019240TEST_F(HttpNetworkTransactionTest, SameOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:159241 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:199242 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:159243 proxy_delegate->set_trusted_spdy_proxy(
9244 net::ProxyServer::FromURI("myproxy:70", net::ProxyServer::SCHEME_HTTP));
9245
tbansal8ef1d3e2016-02-03 04:05:429246 HttpRequestInfo request;
9247
9248 request.method = "GET";
9249 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109250 request.traffic_annotation =
9251 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal8ef1d3e2016-02-03 04:05:429252
9253 // Configure against https proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:499254 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9255 "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal8ef1d3e2016-02-03 04:05:429256 BoundTestNetLog log;
9257 session_deps_.net_log = log.bound().net_log();
9258
9259 // Enable cross-origin push.
inlinechan894515af2016-12-09 02:40:109260 session_deps_.proxy_delegate = std::move(proxy_delegate);
tbansal8ef1d3e2016-02-03 04:05:429261
danakj1fd259a02016-04-16 03:17:099262 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
tbansal8ef1d3e2016-02-03 04:05:429263
Ryan Hamilton0239aac2018-05-19 00:03:139264 spdy::SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:459265 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:139266 spdy::SpdySerializedFrame stream2_priority(
tombergan5d22c182017-01-11 02:05:359267 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
tbansal8ef1d3e2016-02-03 04:05:429268
9269 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:419270 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:359271 CreateMockWrite(stream2_priority, 3, ASYNC),
tbansal8ef1d3e2016-02-03 04:05:429272 };
9273
Ryan Hamilton0239aac2018-05-19 00:03:139274 spdy::SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:159275 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:429276
Ryan Hamilton0239aac2018-05-19 00:03:139277 spdy::SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
Bence Béky096cf052017-08-08 23:55:339278 nullptr, 0, 2, 1, "http://www.example.org/foo.dat"));
bnc38dcd392016-02-09 23:19:499279
Ryan Hamilton0239aac2018-05-19 00:03:139280 spdy::SpdySerializedFrame stream1_body(
9281 spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:429282
Ryan Hamilton0239aac2018-05-19 00:03:139283 spdy::SpdySerializedFrame stream2_reply(
bnc42331402016-07-25 13:36:159284 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:429285
Ryan Hamilton0239aac2018-05-19 00:03:139286 spdy::SpdySerializedFrame stream2_body(
9287 spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:429288
9289 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:419290 CreateMockRead(stream1_reply, 1, ASYNC),
9291 CreateMockRead(stream2_syn, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:359292 CreateMockRead(stream1_body, 4, ASYNC),
9293 CreateMockRead(stream2_body, 5, ASYNC),
9294 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
tbansal8ef1d3e2016-02-03 04:05:429295 };
9296
Ryan Sleevib8d7ea02018-05-07 20:01:019297 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
tbansal8ef1d3e2016-02-03 04:05:429298 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
9299 // Negotiate SPDY to the proxy
9300 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:369301 proxy.next_proto = kProtoHTTP2;
tbansal8ef1d3e2016-02-03 04:05:429302 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
9303
bnc87dcefc2017-05-25 12:47:589304 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:199305 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tbansal8ef1d3e2016-02-03 04:05:429306 TestCompletionCallback callback;
9307 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:019308 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
tbansal8ef1d3e2016-02-03 04:05:429309
9310 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019311 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:429312 const HttpResponseInfo* response = trans->GetResponseInfo();
9313
wezca1070932016-05-26 20:30:529314 ASSERT_TRUE(response);
tbansal8ef1d3e2016-02-03 04:05:429315 EXPECT_TRUE(response->headers->IsKeepAlive());
9316
9317 EXPECT_EQ(200, response->headers->response_code());
9318 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
9319
9320 std::string response_data;
9321 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:019322 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:429323 EXPECT_EQ("hello!", response_data);
9324
9325 trans.reset();
9326 session->CloseAllConnections();
9327}
9328
[email protected]2df19bb2010-08-25 20:13:469329// Test HTTPS connections to a site with a bad certificate, going through an
9330// HTTPS proxy
bncd16676a2016-07-20 16:23:019331TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
Ramin Halavatica8d5252018-03-12 05:33:499332 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9333 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:469334
9335 HttpRequestInfo request;
9336 request.method = "GET";
bncce36dca22015-04-21 22:11:239337 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109338 request.traffic_annotation =
9339 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:469340
9341 // Attempt to fetch the URL from a server with a bad cert
9342 MockWrite bad_cert_writes[] = {
rsleevidb16bb02015-11-12 23:47:179343 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9344 "Host: www.example.org:443\r\n"
9345 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:469346 };
9347
9348 MockRead bad_cert_reads[] = {
9349 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069350 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:469351 };
9352
9353 // Attempt to fetch the URL with a good cert
9354 MockWrite good_data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179355 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9356 "Host: www.example.org:443\r\n"
9357 "Proxy-Connection: keep-alive\r\n\r\n"),
9358 MockWrite("GET / HTTP/1.1\r\n"
9359 "Host: www.example.org\r\n"
9360 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:469361 };
9362
9363 MockRead good_cert_reads[] = {
9364 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
9365 MockRead("HTTP/1.0 200 OK\r\n"),
9366 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9367 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069368 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:469369 };
9370
Ryan Sleevib8d7ea02018-05-07 20:01:019371 StaticSocketDataProvider ssl_bad_certificate(bad_cert_reads, bad_cert_writes);
9372 StaticSocketDataProvider data(good_cert_reads, good_data_writes);
[email protected]8ddf8322012-02-23 18:08:069373 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
9374 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:469375
9376 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:079377 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9378 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
9379 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:469380
9381 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:079382 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9383 session_deps_.socket_factory->AddSocketDataProvider(&data);
9384 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:469385
[email protected]49639fa2011-12-20 23:22:419386 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:469387
danakj1fd259a02016-04-16 03:17:099388 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169389 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:469390
tfarina42834112016-09-22 13:38:209391 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019392 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:469393
9394 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019395 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]2df19bb2010-08-25 20:13:469396
bnc691fda62016-08-12 00:43:169397 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:019398 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:469399
9400 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019401 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:469402
bnc691fda62016-08-12 00:43:169403 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:469404
wezca1070932016-05-26 20:30:529405 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:469406 EXPECT_EQ(100, response->headers->GetContentLength());
9407}
9408
bncd16676a2016-07-20 16:23:019409TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:429410 HttpRequestInfo request;
9411 request.method = "GET";
bncce36dca22015-04-21 22:11:239412 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:439413 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
9414 "Chromium Ultra Awesome X Edition");
Ramin Halavatib5e433e62018-02-07 07:41:109415 request.traffic_annotation =
9416 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429417
danakj1fd259a02016-04-16 03:17:099418 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169419 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279420
[email protected]1c773ea12009-04-28 19:58:429421 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239422 MockWrite(
9423 "GET / HTTP/1.1\r\n"
9424 "Host: www.example.org\r\n"
9425 "Connection: keep-alive\r\n"
9426 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429427 };
9428
9429 // Lastly, the server responds with the actual content.
9430 MockRead data_reads[] = {
9431 MockRead("HTTP/1.0 200 OK\r\n"),
9432 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9433 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069434 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429435 };
9436
Ryan Sleevib8d7ea02018-05-07 20:01:019437 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:079438 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429439
[email protected]49639fa2011-12-20 23:22:419440 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429441
tfarina42834112016-09-22 13:38:209442 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019443 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429444
9445 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019446 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429447}
9448
bncd16676a2016-07-20 16:23:019449TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:299450 HttpRequestInfo request;
9451 request.method = "GET";
bncce36dca22015-04-21 22:11:239452 request.url = GURL("https://www.example.org/");
[email protected]da81f132010-08-18 23:39:299453 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
9454 "Chromium Ultra Awesome X Edition");
Ramin Halavatib5e433e62018-02-07 07:41:109455 request.traffic_annotation =
9456 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]da81f132010-08-18 23:39:299457
Ramin Halavatica8d5252018-03-12 05:33:499458 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9459 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:099460 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169461 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279462
[email protected]da81f132010-08-18 23:39:299463 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179464 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9465 "Host: www.example.org:443\r\n"
9466 "Proxy-Connection: keep-alive\r\n"
9467 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]da81f132010-08-18 23:39:299468 };
9469 MockRead data_reads[] = {
9470 // Return an error, so the transaction stops here (this test isn't
9471 // interested in the rest).
9472 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
9473 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9474 MockRead("Proxy-Connection: close\r\n\r\n"),
9475 };
9476
Ryan Sleevib8d7ea02018-05-07 20:01:019477 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:079478 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:299479
[email protected]49639fa2011-12-20 23:22:419480 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:299481
tfarina42834112016-09-22 13:38:209482 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019483 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]da81f132010-08-18 23:39:299484
9485 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019486 EXPECT_THAT(rv, IsOk());
[email protected]da81f132010-08-18 23:39:299487}
9488
bncd16676a2016-07-20 16:23:019489TEST_F(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:429490 HttpRequestInfo request;
9491 request.method = "GET";
bncce36dca22015-04-21 22:11:239492 request.url = GURL("http://www.example.org/");
[email protected]c10450102011-06-27 09:06:169493 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
9494 "http://the.previous.site.com/");
Ramin Halavatib5e433e62018-02-07 07:41:109495 request.traffic_annotation =
9496 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429497
danakj1fd259a02016-04-16 03:17:099498 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169499 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279500
[email protected]1c773ea12009-04-28 19:58:429501 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239502 MockWrite(
9503 "GET / HTTP/1.1\r\n"
9504 "Host: www.example.org\r\n"
9505 "Connection: keep-alive\r\n"
9506 "Referer: http://the.previous.site.com/\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429507 };
9508
9509 // Lastly, the server responds with the actual content.
9510 MockRead data_reads[] = {
9511 MockRead("HTTP/1.0 200 OK\r\n"),
9512 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9513 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069514 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429515 };
9516
Ryan Sleevib8d7ea02018-05-07 20:01:019517 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:079518 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429519
[email protected]49639fa2011-12-20 23:22:419520 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429521
tfarina42834112016-09-22 13:38:209522 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019523 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429524
9525 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019526 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429527}
9528
bncd16676a2016-07-20 16:23:019529TEST_F(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:429530 HttpRequestInfo request;
9531 request.method = "POST";
bncce36dca22015-04-21 22:11:239532 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109533 request.traffic_annotation =
9534 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429535
danakj1fd259a02016-04-16 03:17:099536 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169537 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279538
[email protected]1c773ea12009-04-28 19:58:429539 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239540 MockWrite(
9541 "POST / HTTP/1.1\r\n"
9542 "Host: www.example.org\r\n"
9543 "Connection: keep-alive\r\n"
9544 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429545 };
9546
9547 // Lastly, the server responds with the actual content.
9548 MockRead data_reads[] = {
9549 MockRead("HTTP/1.0 200 OK\r\n"),
9550 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9551 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069552 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429553 };
9554
Ryan Sleevib8d7ea02018-05-07 20:01:019555 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:079556 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429557
[email protected]49639fa2011-12-20 23:22:419558 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429559
tfarina42834112016-09-22 13:38:209560 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019561 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429562
9563 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019564 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429565}
9566
bncd16676a2016-07-20 16:23:019567TEST_F(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:429568 HttpRequestInfo request;
9569 request.method = "PUT";
bncce36dca22015-04-21 22:11:239570 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109571 request.traffic_annotation =
9572 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429573
danakj1fd259a02016-04-16 03:17:099574 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169575 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279576
[email protected]1c773ea12009-04-28 19:58:429577 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239578 MockWrite(
9579 "PUT / HTTP/1.1\r\n"
9580 "Host: www.example.org\r\n"
9581 "Connection: keep-alive\r\n"
9582 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429583 };
9584
9585 // Lastly, the server responds with the actual content.
9586 MockRead data_reads[] = {
9587 MockRead("HTTP/1.0 200 OK\r\n"),
9588 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9589 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069590 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429591 };
9592
Ryan Sleevib8d7ea02018-05-07 20:01:019593 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:079594 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429595
[email protected]49639fa2011-12-20 23:22:419596 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429597
tfarina42834112016-09-22 13:38:209598 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019599 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429600
9601 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019602 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429603}
9604
bncd16676a2016-07-20 16:23:019605TEST_F(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:429606 HttpRequestInfo request;
9607 request.method = "HEAD";
bncce36dca22015-04-21 22:11:239608 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109609 request.traffic_annotation =
9610 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429611
danakj1fd259a02016-04-16 03:17:099612 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169613 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279614
[email protected]1c773ea12009-04-28 19:58:429615 MockWrite data_writes[] = {
csharrisonf473dd192015-08-18 13:54:139616 MockWrite("HEAD / HTTP/1.1\r\n"
9617 "Host: www.example.org\r\n"
9618 "Connection: keep-alive\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429619 };
9620
9621 // Lastly, the server responds with the actual content.
9622 MockRead data_reads[] = {
9623 MockRead("HTTP/1.0 200 OK\r\n"),
9624 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9625 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069626 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429627 };
9628
Ryan Sleevib8d7ea02018-05-07 20:01:019629 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:079630 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429631
[email protected]49639fa2011-12-20 23:22:419632 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429633
tfarina42834112016-09-22 13:38:209634 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019635 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429636
9637 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019638 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429639}
9640
bncd16676a2016-07-20 16:23:019641TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:429642 HttpRequestInfo request;
9643 request.method = "GET";
bncce36dca22015-04-21 22:11:239644 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:429645 request.load_flags = LOAD_BYPASS_CACHE;
Ramin Halavatib5e433e62018-02-07 07:41:109646 request.traffic_annotation =
9647 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429648
danakj1fd259a02016-04-16 03:17:099649 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169650 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279651
[email protected]1c773ea12009-04-28 19:58:429652 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239653 MockWrite(
9654 "GET / HTTP/1.1\r\n"
9655 "Host: www.example.org\r\n"
9656 "Connection: keep-alive\r\n"
9657 "Pragma: no-cache\r\n"
9658 "Cache-Control: no-cache\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429659 };
9660
9661 // Lastly, the server responds with the actual content.
9662 MockRead data_reads[] = {
9663 MockRead("HTTP/1.0 200 OK\r\n"),
9664 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9665 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069666 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429667 };
9668
Ryan Sleevib8d7ea02018-05-07 20:01:019669 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:079670 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429671
[email protected]49639fa2011-12-20 23:22:419672 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429673
tfarina42834112016-09-22 13:38:209674 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019675 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429676
9677 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019678 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429679}
9680
bncd16676a2016-07-20 16:23:019681TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:429682 HttpRequestInfo request;
9683 request.method = "GET";
bncce36dca22015-04-21 22:11:239684 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:429685 request.load_flags = LOAD_VALIDATE_CACHE;
Ramin Halavatib5e433e62018-02-07 07:41:109686 request.traffic_annotation =
9687 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429688
danakj1fd259a02016-04-16 03:17:099689 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169690 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279691
[email protected]1c773ea12009-04-28 19:58:429692 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239693 MockWrite(
9694 "GET / HTTP/1.1\r\n"
9695 "Host: www.example.org\r\n"
9696 "Connection: keep-alive\r\n"
9697 "Cache-Control: max-age=0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429698 };
9699
9700 // Lastly, the server responds with the actual content.
9701 MockRead data_reads[] = {
9702 MockRead("HTTP/1.0 200 OK\r\n"),
9703 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9704 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069705 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429706 };
9707
Ryan Sleevib8d7ea02018-05-07 20:01:019708 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:079709 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429710
[email protected]49639fa2011-12-20 23:22:419711 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429712
tfarina42834112016-09-22 13:38:209713 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019714 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429715
9716 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019717 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429718}
9719
bncd16676a2016-07-20 16:23:019720TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:429721 HttpRequestInfo request;
9722 request.method = "GET";
bncce36dca22015-04-21 22:11:239723 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:439724 request.extra_headers.SetHeader("FooHeader", "Bar");
Ramin Halavatib5e433e62018-02-07 07:41:109725 request.traffic_annotation =
9726 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429727
danakj1fd259a02016-04-16 03:17:099728 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169729 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279730
[email protected]1c773ea12009-04-28 19:58:429731 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239732 MockWrite(
9733 "GET / HTTP/1.1\r\n"
9734 "Host: www.example.org\r\n"
9735 "Connection: keep-alive\r\n"
9736 "FooHeader: Bar\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429737 };
9738
9739 // Lastly, the server responds with the actual content.
9740 MockRead data_reads[] = {
9741 MockRead("HTTP/1.0 200 OK\r\n"),
9742 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9743 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069744 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429745 };
9746
Ryan Sleevib8d7ea02018-05-07 20:01:019747 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:079748 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429749
[email protected]49639fa2011-12-20 23:22:419750 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429751
tfarina42834112016-09-22 13:38:209752 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019753 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429754
9755 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019756 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429757}
9758
bncd16676a2016-07-20 16:23:019759TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:479760 HttpRequestInfo request;
9761 request.method = "GET";
bncce36dca22015-04-21 22:11:239762 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:439763 request.extra_headers.SetHeader("referer", "www.foo.com");
9764 request.extra_headers.SetHeader("hEllo", "Kitty");
9765 request.extra_headers.SetHeader("FoO", "bar");
Ramin Halavatib5e433e62018-02-07 07:41:109766 request.traffic_annotation =
9767 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]270c6412010-03-29 22:02:479768
danakj1fd259a02016-04-16 03:17:099769 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169770 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279771
[email protected]270c6412010-03-29 22:02:479772 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239773 MockWrite(
9774 "GET / HTTP/1.1\r\n"
9775 "Host: www.example.org\r\n"
9776 "Connection: keep-alive\r\n"
9777 "referer: www.foo.com\r\n"
9778 "hEllo: Kitty\r\n"
9779 "FoO: bar\r\n\r\n"),
[email protected]270c6412010-03-29 22:02:479780 };
9781
9782 // Lastly, the server responds with the actual content.
9783 MockRead data_reads[] = {
9784 MockRead("HTTP/1.0 200 OK\r\n"),
9785 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9786 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069787 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:479788 };
9789
Ryan Sleevib8d7ea02018-05-07 20:01:019790 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:079791 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:479792
[email protected]49639fa2011-12-20 23:22:419793 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:479794
tfarina42834112016-09-22 13:38:209795 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019796 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]270c6412010-03-29 22:02:479797
9798 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019799 EXPECT_THAT(rv, IsOk());
[email protected]270c6412010-03-29 22:02:479800}
9801
bncd16676a2016-07-20 16:23:019802TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279803 HttpRequestInfo request;
9804 request.method = "GET";
bncce36dca22015-04-21 22:11:239805 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109806 request.traffic_annotation =
9807 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:279808
Lily Houghton8c2f97d2018-01-22 05:06:599809 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499810 ProxyResolutionService::CreateFixedFromPacResult(
9811 "SOCKS myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519812 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079813 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:029814
danakj1fd259a02016-04-16 03:17:099815 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169816 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:029817
[email protected]3cd17242009-06-23 02:59:029818 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
9819 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9820
9821 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239822 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
9823 MockWrite(
9824 "GET / HTTP/1.1\r\n"
9825 "Host: www.example.org\r\n"
9826 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:029827
9828 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:069829 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:029830 MockRead("HTTP/1.0 200 OK\r\n"),
9831 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9832 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069833 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:029834 };
9835
Ryan Sleevib8d7ea02018-05-07 20:01:019836 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:079837 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:029838
[email protected]49639fa2011-12-20 23:22:419839 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:029840
tfarina42834112016-09-22 13:38:209841 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019842 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:029843
9844 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019845 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029846
bnc691fda62016-08-12 00:43:169847 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529848 ASSERT_TRUE(response);
[email protected]3cd17242009-06-23 02:59:029849
tbansal2ecbbc72016-10-06 17:15:479850 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]029c83b62013-01-24 05:28:209851 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169852 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209853 TestLoadTimingNotReusedWithPac(load_timing_info,
9854 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9855
[email protected]3cd17242009-06-23 02:59:029856 std::string response_text;
bnc691fda62016-08-12 00:43:169857 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019858 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029859 EXPECT_EQ("Payload", response_text);
9860}
9861
bncd16676a2016-07-20 16:23:019862TEST_F(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279863 HttpRequestInfo request;
9864 request.method = "GET";
bncce36dca22015-04-21 22:11:239865 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109866 request.traffic_annotation =
9867 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:279868
Lily Houghton8c2f97d2018-01-22 05:06:599869 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499870 ProxyResolutionService::CreateFixedFromPacResult(
9871 "SOCKS myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519872 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079873 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:029874
danakj1fd259a02016-04-16 03:17:099875 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169876 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:029877
[email protected]3cd17242009-06-23 02:59:029878 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
9879 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9880
9881 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239882 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
9883 arraysize(write_buffer)),
9884 MockWrite(
9885 "GET / HTTP/1.1\r\n"
9886 "Host: www.example.org\r\n"
9887 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:029888
9889 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:019890 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
9891 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:359892 MockRead("HTTP/1.0 200 OK\r\n"),
9893 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9894 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069895 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:359896 };
9897
Ryan Sleevib8d7ea02018-05-07 20:01:019898 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:079899 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:359900
[email protected]8ddf8322012-02-23 18:08:069901 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:079902 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:359903
[email protected]49639fa2011-12-20 23:22:419904 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:359905
tfarina42834112016-09-22 13:38:209906 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019907 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:359908
9909 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019910 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359911
[email protected]029c83b62013-01-24 05:28:209912 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169913 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209914 TestLoadTimingNotReusedWithPac(load_timing_info,
9915 CONNECT_TIMING_HAS_SSL_TIMES);
9916
bnc691fda62016-08-12 00:43:169917 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529918 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:479919 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:359920
9921 std::string response_text;
bnc691fda62016-08-12 00:43:169922 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019923 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359924 EXPECT_EQ("Payload", response_text);
9925}
9926
bncd16676a2016-07-20 16:23:019927TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:209928 HttpRequestInfo request;
9929 request.method = "GET";
bncce36dca22015-04-21 22:11:239930 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109931 request.traffic_annotation =
9932 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:209933
Ramin Halavatica8d5252018-03-12 05:33:499934 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9935 "socks4://myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519936 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079937 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:209938
danakj1fd259a02016-04-16 03:17:099939 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169940 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:209941
9942 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
9943 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9944
9945 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239946 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
9947 MockWrite(
9948 "GET / HTTP/1.1\r\n"
9949 "Host: www.example.org\r\n"
9950 "Connection: keep-alive\r\n\r\n")};
[email protected]029c83b62013-01-24 05:28:209951
9952 MockRead data_reads[] = {
9953 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
9954 MockRead("HTTP/1.0 200 OK\r\n"),
9955 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9956 MockRead("Payload"),
9957 MockRead(SYNCHRONOUS, OK)
9958 };
9959
Ryan Sleevib8d7ea02018-05-07 20:01:019960 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:079961 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:209962
9963 TestCompletionCallback callback;
9964
tfarina42834112016-09-22 13:38:209965 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019966 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:209967
9968 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019969 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:209970
bnc691fda62016-08-12 00:43:169971 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529972 ASSERT_TRUE(response);
[email protected]029c83b62013-01-24 05:28:209973
9974 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169975 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209976 TestLoadTimingNotReused(load_timing_info,
9977 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9978
9979 std::string response_text;
bnc691fda62016-08-12 00:43:169980 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019981 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:209982 EXPECT_EQ("Payload", response_text);
9983}
9984
bncd16676a2016-07-20 16:23:019985TEST_F(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279986 HttpRequestInfo request;
9987 request.method = "GET";
bncce36dca22015-04-21 22:11:239988 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109989 request.traffic_annotation =
9990 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:279991
Lily Houghton8c2f97d2018-01-22 05:06:599992 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499993 ProxyResolutionService::CreateFixedFromPacResult(
9994 "SOCKS5 myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519995 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079996 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:359997
danakj1fd259a02016-04-16 03:17:099998 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169999 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:3510000
[email protected]e0c27be2009-07-15 13:09:3510001 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
10002 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:3710003 const char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:2310004 0x05, // Version
10005 0x01, // Command (CONNECT)
10006 0x00, // Reserved.
10007 0x03, // Address type (DOMAINNAME).
10008 0x0F, // Length of domain (15)
10009 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
10010 '.', 'o', 'r', 'g', 0x00, 0x50, // 16-bit port (80)
[email protected]f209dba2009-12-18 00:24:3710011 };
[email protected]e0c27be2009-07-15 13:09:3510012 const char kSOCKS5OkResponse[] =
10013 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
10014
10015 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310016 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
10017 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
10018 MockWrite(
10019 "GET / HTTP/1.1\r\n"
10020 "Host: www.example.org\r\n"
10021 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:3510022
10023 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:0110024 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
10025 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:3510026 MockRead("HTTP/1.0 200 OK\r\n"),
10027 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
10028 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:0610029 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:3510030 };
10031
Ryan Sleevib8d7ea02018-05-07 20:01:0110032 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710033 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:3510034
[email protected]49639fa2011-12-20 23:22:4110035 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:3510036
tfarina42834112016-09-22 13:38:2010037 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110038 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:3510039
10040 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110041 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3510042
bnc691fda62016-08-12 00:43:1610043 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210044 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:4710045 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:3510046
[email protected]029c83b62013-01-24 05:28:2010047 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1610048 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2010049 TestLoadTimingNotReusedWithPac(load_timing_info,
10050 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
10051
[email protected]e0c27be2009-07-15 13:09:3510052 std::string response_text;
bnc691fda62016-08-12 00:43:1610053 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0110054 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3510055 EXPECT_EQ("Payload", response_text);
10056}
10057
bncd16676a2016-07-20 16:23:0110058TEST_F(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:2710059 HttpRequestInfo request;
10060 request.method = "GET";
bncce36dca22015-04-21 22:11:2310061 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010062 request.traffic_annotation =
10063 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710064
Lily Houghton8c2f97d2018-01-22 05:06:5910065 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910066 ProxyResolutionService::CreateFixedFromPacResult(
10067 "SOCKS5 myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110068 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710069 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:3510070
danakj1fd259a02016-04-16 03:17:0910071 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610072 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:3510073
[email protected]e0c27be2009-07-15 13:09:3510074 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
10075 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:3710076 const unsigned char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:2310077 0x05, // Version
10078 0x01, // Command (CONNECT)
10079 0x00, // Reserved.
10080 0x03, // Address type (DOMAINNAME).
10081 0x0F, // Length of domain (15)
10082 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
10083 '.', 'o', 'r', 'g', 0x01, 0xBB, // 16-bit port (443)
[email protected]f209dba2009-12-18 00:24:3710084 };
10085
[email protected]e0c27be2009-07-15 13:09:3510086 const char kSOCKS5OkResponse[] =
10087 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
10088
10089 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310090 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
10091 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
10092 arraysize(kSOCKS5OkRequest)),
10093 MockWrite(
10094 "GET / HTTP/1.1\r\n"
10095 "Host: www.example.org\r\n"
10096 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:3510097
10098 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:0110099 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
10100 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:0210101 MockRead("HTTP/1.0 200 OK\r\n"),
10102 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
10103 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:0610104 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:0210105 };
10106
Ryan Sleevib8d7ea02018-05-07 20:01:0110107 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710108 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:0210109
[email protected]8ddf8322012-02-23 18:08:0610110 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710111 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:0210112
[email protected]49639fa2011-12-20 23:22:4110113 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:0210114
tfarina42834112016-09-22 13:38:2010115 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110116 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:0210117
10118 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110119 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0210120
bnc691fda62016-08-12 00:43:1610121 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210122 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:4710123 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]3cd17242009-06-23 02:59:0210124
[email protected]029c83b62013-01-24 05:28:2010125 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1610126 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2010127 TestLoadTimingNotReusedWithPac(load_timing_info,
10128 CONNECT_TIMING_HAS_SSL_TIMES);
10129
[email protected]3cd17242009-06-23 02:59:0210130 std::string response_text;
bnc691fda62016-08-12 00:43:1610131 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0110132 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0210133 EXPECT_EQ("Payload", response_text);
10134}
10135
[email protected]448d4ca52012-03-04 04:12:2310136namespace {
10137
[email protected]04e5be32009-06-26 20:00:3110138// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:0610139
10140struct GroupNameTest {
10141 std::string proxy_server;
10142 std::string url;
10143 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:1810144 bool ssl;
[email protected]2d731a32010-04-29 01:04:0610145};
10146
danakj1fd259a02016-04-16 03:17:0910147std::unique_ptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]bb88e1d32013-05-03 23:11:0710148 SpdySessionDependencies* session_deps_) {
danakj1fd259a02016-04-16 03:17:0910149 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:0610150
bnc525e175a2016-06-20 12:36:4010151 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310152 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110153 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnc7dc7e1b42015-07-28 14:43:1210154 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110155 http_server_properties->SetHttp2AlternativeService(
bncaa60ff402016-06-22 19:12:4210156 url::SchemeHostPort("https", "host.with.alternate", 443),
zhongyi3d4a55e72016-04-22 20:36:4610157 alternative_service, expiration);
[email protected]2d731a32010-04-29 01:04:0610158
10159 return session;
10160}
10161
mmenkee65e7af2015-10-13 17:16:4210162int GroupNameTransactionHelper(const std::string& url,
10163 HttpNetworkSession* session) {
[email protected]2d731a32010-04-29 01:04:0610164 HttpRequestInfo request;
10165 request.method = "GET";
10166 request.url = GURL(url);
Ramin Halavatib5e433e62018-02-07 07:41:1010167 request.traffic_annotation =
10168 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d731a32010-04-29 01:04:0610169
bnc691fda62016-08-12 00:43:1610170 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
[email protected]cb9bf6ca2011-01-28 13:15:2710171
[email protected]49639fa2011-12-20 23:22:4110172 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:0610173
10174 // We do not complete this request, the dtor will clean the transaction up.
tfarina42834112016-09-22 13:38:2010175 return trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]2d731a32010-04-29 01:04:0610176}
10177
[email protected]448d4ca52012-03-04 04:12:2310178} // namespace
10179
bncd16676a2016-07-20 16:23:0110180TEST_F(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:0610181 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:2310182 {
10183 "", // unused
10184 "http://www.example.org/direct",
10185 "www.example.org:80",
10186 false,
10187 },
10188 {
10189 "", // unused
10190 "http://[2001:1418:13:1::25]/direct",
10191 "[2001:1418:13:1::25]:80",
10192 false,
10193 },
[email protected]04e5be32009-06-26 20:00:3110194
bncce36dca22015-04-21 22:11:2310195 // SSL Tests
10196 {
10197 "", // unused
10198 "https://www.example.org/direct_ssl",
10199 "ssl/www.example.org:443",
10200 true,
10201 },
10202 {
10203 "", // unused
10204 "https://[2001:1418:13:1::25]/direct",
10205 "ssl/[2001:1418:13:1::25]:443",
10206 true,
10207 },
10208 {
10209 "", // unused
bncaa60ff402016-06-22 19:12:4210210 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:2310211 "ssl/host.with.alternate:443",
10212 true,
10213 },
[email protected]2d731a32010-04-29 01:04:0610214 };
[email protected]2ff8b312010-04-26 22:20:5410215
viettrungluue4a8b882014-10-16 06:17:3810216 for (size_t i = 0; i < arraysize(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5910217 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910218 ProxyResolutionService::CreateFixed(tests[i].proxy_server,
10219 TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:0910220 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:4010221 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:0610222
mmenkee65e7af2015-10-13 17:16:4210223 HttpNetworkSessionPeer peer(session.get());
[email protected]ab739042011-04-07 15:22:2810224 CaptureGroupNameTransportSocketPool* transport_conn_pool =
bnc87dcefc2017-05-25 12:47:5810225 new CaptureGroupNameTransportSocketPool(nullptr, nullptr);
[email protected]2431756e2010-09-29 20:26:1310226 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
bnc87dcefc2017-05-25 12:47:5810227 new CaptureGroupNameSSLSocketPool(nullptr, nullptr);
Jeremy Roman0579ed62017-08-29 15:56:1910228 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
[email protected]a42dbd142011-11-17 16:42:0210229 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
10230 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
dchengc7eeda422015-12-26 03:56:4810231 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:0610232
10233 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:4210234 GroupNameTransactionHelper(tests[i].url, session.get()));
Tarun Bansal162eabe52018-01-20 01:16:3910235 if (tests[i].ssl) {
[email protected]e60e47a2010-07-14 03:37:1810236 EXPECT_EQ(tests[i].expected_group_name,
10237 ssl_conn_pool->last_group_name_received());
Tarun Bansal162eabe52018-01-20 01:16:3910238 } else {
[email protected]e60e47a2010-07-14 03:37:1810239 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:2810240 transport_conn_pool->last_group_name_received());
Tarun Bansal162eabe52018-01-20 01:16:3910241 }
10242 // When SSL proxy is in use, socket must be requested from |ssl_conn_pool|.
10243 EXPECT_EQ(tests[i].ssl, ssl_conn_pool->socket_requested());
10244 // When SSL proxy is not in use, socket must be requested from
10245 // |transport_conn_pool|.
10246 EXPECT_EQ(!tests[i].ssl, transport_conn_pool->socket_requested());
[email protected]2d731a32010-04-29 01:04:0610247 }
[email protected]2d731a32010-04-29 01:04:0610248}
10249
bncd16676a2016-07-20 16:23:0110250TEST_F(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:0610251 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:2310252 {
Matt Menked1eb6d42018-01-17 04:54:0610253 "http_proxy", "http://www.example.org/http_proxy_normal",
10254 "http_proxy/www.example.org:80", false,
bncce36dca22015-04-21 22:11:2310255 },
[email protected]2d731a32010-04-29 01:04:0610256
bncce36dca22015-04-21 22:11:2310257 // SSL Tests
10258 {
Matt Menked1eb6d42018-01-17 04:54:0610259 "http_proxy", "https://www.example.org/http_connect_ssl",
10260 "http_proxy/ssl/www.example.org:443", true,
bncce36dca22015-04-21 22:11:2310261 },
[email protected]af3490e2010-10-16 21:02:2910262
bncce36dca22015-04-21 22:11:2310263 {
Matt Menked1eb6d42018-01-17 04:54:0610264 "http_proxy", "https://host.with.alternate/direct",
10265 "http_proxy/ssl/host.with.alternate:443", true,
bncce36dca22015-04-21 22:11:2310266 },
[email protected]45499252013-01-23 17:12:5610267
bncce36dca22015-04-21 22:11:2310268 {
Matt Menked1eb6d42018-01-17 04:54:0610269 "http_proxy", "ftp://ftp.google.com/http_proxy_normal",
10270 "http_proxy/ftp/ftp.google.com:21", false,
bncce36dca22015-04-21 22:11:2310271 },
[email protected]2d731a32010-04-29 01:04:0610272 };
10273
viettrungluue4a8b882014-10-16 06:17:3810274 for (size_t i = 0; i < arraysize(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5910275 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910276 ProxyResolutionService::CreateFixed(tests[i].proxy_server,
10277 TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:0910278 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:4010279 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:0610280
mmenkee65e7af2015-10-13 17:16:4210281 HttpNetworkSessionPeer peer(session.get());
[email protected]2d731a32010-04-29 01:04:0610282
[email protected]e60e47a2010-07-14 03:37:1810283 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:1310284 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:3410285 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:1310286 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:3410287 new CaptureGroupNameSSLSocketPool(NULL, NULL);
Jeremy Roman0579ed62017-08-29 15:56:1910288 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
aviadef3442016-10-03 18:50:3910289 mock_pool_manager->SetSocketPoolForHTTPProxy(
10290 proxy_host, base::WrapUnique(http_proxy_pool));
10291 mock_pool_manager->SetSocketPoolForSSLWithProxy(
10292 proxy_host, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:4810293 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:0610294
10295 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:4210296 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:1810297 if (tests[i].ssl)
10298 EXPECT_EQ(tests[i].expected_group_name,
10299 ssl_conn_pool->last_group_name_received());
10300 else
10301 EXPECT_EQ(tests[i].expected_group_name,
10302 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:0610303 }
[email protected]2d731a32010-04-29 01:04:0610304}
10305
bncd16676a2016-07-20 16:23:0110306TEST_F(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:0610307 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:2310308 {
10309 "socks4://socks_proxy:1080",
10310 "http://www.example.org/socks4_direct",
10311 "socks4/www.example.org:80",
10312 false,
10313 },
10314 {
10315 "socks5://socks_proxy:1080",
10316 "http://www.example.org/socks5_direct",
10317 "socks5/www.example.org:80",
10318 false,
10319 },
[email protected]2d731a32010-04-29 01:04:0610320
bncce36dca22015-04-21 22:11:2310321 // SSL Tests
10322 {
10323 "socks4://socks_proxy:1080",
10324 "https://www.example.org/socks4_ssl",
10325 "socks4/ssl/www.example.org:443",
10326 true,
10327 },
10328 {
10329 "socks5://socks_proxy:1080",
10330 "https://www.example.org/socks5_ssl",
10331 "socks5/ssl/www.example.org:443",
10332 true,
10333 },
[email protected]af3490e2010-10-16 21:02:2910334
bncce36dca22015-04-21 22:11:2310335 {
10336 "socks4://socks_proxy:1080",
bncaa60ff402016-06-22 19:12:4210337 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:2310338 "socks4/ssl/host.with.alternate:443",
10339 true,
10340 },
[email protected]04e5be32009-06-26 20:00:3110341 };
10342
viettrungluue4a8b882014-10-16 06:17:3810343 for (size_t i = 0; i < arraysize(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5910344 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910345 ProxyResolutionService::CreateFixed(tests[i].proxy_server,
10346 TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:0910347 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:4010348 SetupSessionForGroupNameTests(&session_deps_));
[email protected]8b114dd72011-03-25 05:33:0210349
mmenkee65e7af2015-10-13 17:16:4210350 HttpNetworkSessionPeer peer(session.get());
[email protected]04e5be32009-06-26 20:00:3110351
[email protected]e60e47a2010-07-14 03:37:1810352 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:1310353 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:3410354 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:1310355 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:3410356 new CaptureGroupNameSSLSocketPool(NULL, NULL);
Jeremy Roman0579ed62017-08-29 15:56:1910357 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
aviadef3442016-10-03 18:50:3910358 mock_pool_manager->SetSocketPoolForSOCKSProxy(
10359 proxy_host, base::WrapUnique(socks_conn_pool));
10360 mock_pool_manager->SetSocketPoolForSSLWithProxy(
10361 proxy_host, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:4810362 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]04e5be32009-06-26 20:00:3110363
bnc691fda62016-08-12 00:43:1610364 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]04e5be32009-06-26 20:00:3110365
[email protected]2d731a32010-04-29 01:04:0610366 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:4210367 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:1810368 if (tests[i].ssl)
10369 EXPECT_EQ(tests[i].expected_group_name,
10370 ssl_conn_pool->last_group_name_received());
10371 else
10372 EXPECT_EQ(tests[i].expected_group_name,
10373 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:3110374 }
10375}
10376
bncd16676a2016-07-20 16:23:0110377TEST_F(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:2710378 HttpRequestInfo request;
10379 request.method = "GET";
bncce36dca22015-04-21 22:11:2310380 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010381 request.traffic_annotation =
10382 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710383
Ramin Halavatica8d5252018-03-12 05:33:4910384 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
10385 "myproxy:70;foobar:80", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]b59ff372009-07-15 22:04:3210386
[email protected]69719062010-01-05 20:09:2110387 // This simulates failure resolving all hostnames; that means we will fail
10388 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:0710389 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:3210390
danakj1fd259a02016-04-16 03:17:0910391 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610392 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]9172a982009-06-06 00:30:2510393
[email protected]49639fa2011-12-20 23:22:4110394 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:2510395
tfarina42834112016-09-22 13:38:2010396 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110397 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9172a982009-06-06 00:30:2510398
[email protected]9172a982009-06-06 00:30:2510399 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110400 EXPECT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]9172a982009-06-06 00:30:2510401}
10402
Miriam Gershenson2a01b162018-03-22 22:54:4710403// LOAD_BYPASS_CACHE should trigger the host cache bypass.
10404TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh) {
[email protected]cb9bf6ca2011-01-28 13:15:2710405 // Issue a request, asking to bypass the cache(s).
maksim.sisov31452af2016-07-27 06:38:1010406 HttpRequestInfo request_info;
10407 request_info.method = "GET";
Miriam Gershenson2a01b162018-03-22 22:54:4710408 request_info.load_flags = LOAD_BYPASS_CACHE;
maksim.sisov31452af2016-07-27 06:38:1010409 request_info.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010410 request_info.traffic_annotation =
10411 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710412
[email protected]a2c2fb92009-07-18 07:31:0410413 // Select a host resolver that does caching.
Jeremy Roman0579ed62017-08-29 15:56:1910414 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
[email protected]b59ff372009-07-15 22:04:3210415
danakj1fd259a02016-04-16 03:17:0910416 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610417 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3b9cca42009-06-16 01:08:2810418
bncce36dca22015-04-21 22:11:2310419 // Warm up the host cache so it has an entry for "www.example.org".
[email protected]3b9cca42009-06-16 01:08:2810420 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:2910421 TestCompletionCallback callback;
maksim.sisov31452af2016-07-27 06:38:1010422 std::unique_ptr<HostResolver::Request> request1;
[email protected]bb88e1d32013-05-03 23:11:0710423 int rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:2310424 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:1010425 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request1,
tfarina42834112016-09-22 13:38:2010426 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110427 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4710428 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110429 EXPECT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:2810430
10431 // Verify that it was added to host cache, by doing a subsequent async lookup
10432 // and confirming it completes synchronously.
maksim.sisov31452af2016-07-27 06:38:1010433 std::unique_ptr<HostResolver::Request> request2;
[email protected]bb88e1d32013-05-03 23:11:0710434 rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:2310435 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:1010436 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request2,
tfarina42834112016-09-22 13:38:2010437 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110438 ASSERT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:2810439
bncce36dca22015-04-21 22:11:2310440 // Inject a failure the next time that "www.example.org" is resolved. This way
[email protected]3b9cca42009-06-16 01:08:2810441 // we can tell if the next lookup hit the cache, or the "network".
10442 // (cache --> success, "network" --> failure).
bncce36dca22015-04-21 22:11:2310443 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.example.org");
[email protected]3b9cca42009-06-16 01:08:2810444
10445 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
10446 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:0610447 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
Ryan Sleevib8d7ea02018-05-07 20:01:0110448 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0710449 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:2810450
[email protected]3b9cca42009-06-16 01:08:2810451 // Run the request.
tfarina42834112016-09-22 13:38:2010452 rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110453 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]49639fa2011-12-20 23:22:4110454 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:2810455
10456 // If we bypassed the cache, we would have gotten a failure while resolving
bncce36dca22015-04-21 22:11:2310457 // "www.example.org".
robpercival214763f2016-07-01 23:27:0110458 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]3b9cca42009-06-16 01:08:2810459}
10460
[email protected]0877e3d2009-10-17 22:29:5710461// Make sure we can handle an error when writing the request.
bncd16676a2016-07-20 16:23:0110462TEST_F(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:5710463 HttpRequestInfo request;
10464 request.method = "GET";
10465 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:1010466 request.traffic_annotation =
10467 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5710468
10469 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:0610470 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:5710471 };
Ryan Sleevib8d7ea02018-05-07 20:01:0110472 StaticSocketDataProvider data(base::span<MockRead>(), write_failure);
[email protected]bb88e1d32013-05-03 23:11:0710473 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:0910474 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5710475
[email protected]49639fa2011-12-20 23:22:4110476 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5710477
bnc691fda62016-08-12 00:43:1610478 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5710479
tfarina42834112016-09-22 13:38:2010480 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110481 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710482
10483 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110484 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:5910485
10486 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1610487 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5910488 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:5710489}
10490
zmo9528c9f42015-08-04 22:12:0810491// Check that a connection closed after the start of the headers finishes ok.
bncd16676a2016-07-20 16:23:0110492TEST_F(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:5710493 HttpRequestInfo request;
10494 request.method = "GET";
10495 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:1010496 request.traffic_annotation =
10497 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5710498
10499 MockRead data_reads[] = {
10500 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:0610501 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:5710502 };
10503
Ryan Sleevib8d7ea02018-05-07 20:01:0110504 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0710505 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:0910506 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5710507
[email protected]49639fa2011-12-20 23:22:4110508 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5710509
bnc691fda62016-08-12 00:43:1610510 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5710511
tfarina42834112016-09-22 13:38:2010512 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110513 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710514
10515 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110516 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:0810517
bnc691fda62016-08-12 00:43:1610518 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210519 ASSERT_TRUE(response);
zmo9528c9f42015-08-04 22:12:0810520
wezca1070932016-05-26 20:30:5210521 EXPECT_TRUE(response->headers);
zmo9528c9f42015-08-04 22:12:0810522 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
10523
10524 std::string response_data;
bnc691fda62016-08-12 00:43:1610525 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0110526 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:0810527 EXPECT_EQ("", response_data);
ttuttled9dbc652015-09-29 20:00:5910528
10529 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1610530 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5910531 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:5710532}
10533
10534// Make sure that a dropped connection while draining the body for auth
10535// restart does the right thing.
bncd16676a2016-07-20 16:23:0110536TEST_F(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:5710537 HttpRequestInfo request;
10538 request.method = "GET";
bncce36dca22015-04-21 22:11:2310539 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010540 request.traffic_annotation =
10541 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5710542
10543 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2310544 MockWrite(
10545 "GET / HTTP/1.1\r\n"
10546 "Host: www.example.org\r\n"
10547 "Connection: keep-alive\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:5710548 };
10549
10550 MockRead data_reads1[] = {
10551 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
10552 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
10553 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10554 MockRead("Content-Length: 14\r\n\r\n"),
10555 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:0610556 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:5710557 };
10558
Ryan Sleevib8d7ea02018-05-07 20:01:0110559 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:0710560 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:5710561
bnc691fda62016-08-12 00:43:1610562 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0877e3d2009-10-17 22:29:5710563 // be issuing -- the final header line contains the credentials.
10564 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:2310565 MockWrite(
10566 "GET / HTTP/1.1\r\n"
10567 "Host: www.example.org\r\n"
10568 "Connection: keep-alive\r\n"
10569 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:5710570 };
10571
10572 // Lastly, the server responds with the actual content.
10573 MockRead data_reads2[] = {
10574 MockRead("HTTP/1.1 200 OK\r\n"),
10575 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10576 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610577 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:5710578 };
10579
Ryan Sleevib8d7ea02018-05-07 20:01:0110580 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:0710581 session_deps_.socket_factory->AddSocketDataProvider(&data2);
danakj1fd259a02016-04-16 03:17:0910582 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5710583
[email protected]49639fa2011-12-20 23:22:4110584 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:5710585
bnc691fda62016-08-12 00:43:1610586 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5010587
tfarina42834112016-09-22 13:38:2010588 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110589 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710590
10591 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0110592 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:5710593
bnc691fda62016-08-12 00:43:1610594 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210595 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410596 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:5710597
[email protected]49639fa2011-12-20 23:22:4110598 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:5710599
bnc691fda62016-08-12 00:43:1610600 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:0110601 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710602
10603 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0110604 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:5710605
bnc691fda62016-08-12 00:43:1610606 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210607 ASSERT_TRUE(response);
10608 EXPECT_FALSE(response->auth_challenge);
[email protected]0877e3d2009-10-17 22:29:5710609 EXPECT_EQ(100, response->headers->GetContentLength());
10610}
10611
10612// Test HTTPS connections going through a proxy that sends extra data.
bncd16676a2016-07-20 16:23:0110613TEST_F(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
Ramin Halavatica8d5252018-03-12 05:33:4910614 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
10615 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5710616
10617 HttpRequestInfo request;
10618 request.method = "GET";
bncce36dca22015-04-21 22:11:2310619 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010620 request.traffic_annotation =
10621 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5710622
10623 MockRead proxy_reads[] = {
10624 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:0610625 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:5710626 };
10627
Ryan Sleevib8d7ea02018-05-07 20:01:0110628 StaticSocketDataProvider data(proxy_reads, base::span<MockWrite>());
[email protected]8ddf8322012-02-23 18:08:0610629 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:5710630
[email protected]bb88e1d32013-05-03 23:11:0710631 session_deps_.socket_factory->AddSocketDataProvider(&data);
10632 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:5710633
[email protected]49639fa2011-12-20 23:22:4110634 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5710635
[email protected]bb88e1d32013-05-03 23:11:0710636 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:5710637
danakj1fd259a02016-04-16 03:17:0910638 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610639 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5710640
tfarina42834112016-09-22 13:38:2010641 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110642 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710643
10644 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110645 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]0877e3d2009-10-17 22:29:5710646}
10647
bncd16676a2016-07-20 16:23:0110648TEST_F(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:4610649 HttpRequestInfo request;
10650 request.method = "GET";
bncce36dca22015-04-21 22:11:2310651 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010652 request.traffic_annotation =
10653 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]9492e4a2010-02-24 00:58:4610654
danakj1fd259a02016-04-16 03:17:0910655 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610656 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710657
[email protected]e22e1362009-11-23 21:31:1210658 MockRead data_reads[] = {
10659 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610660 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:1210661 };
[email protected]9492e4a2010-02-24 00:58:4610662
Ryan Sleevib8d7ea02018-05-07 20:01:0110663 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0710664 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:4610665
[email protected]49639fa2011-12-20 23:22:4110666 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:4610667
tfarina42834112016-09-22 13:38:2010668 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110669 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9492e4a2010-02-24 00:58:4610670
robpercival214763f2016-07-01 23:27:0110671 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]9492e4a2010-02-24 00:58:4610672
bnc691fda62016-08-12 00:43:1610673 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210674 ASSERT_TRUE(response);
[email protected]9492e4a2010-02-24 00:58:4610675
wezca1070932016-05-26 20:30:5210676 EXPECT_TRUE(response->headers);
[email protected]9492e4a2010-02-24 00:58:4610677 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
10678
10679 std::string response_data;
bnc691fda62016-08-12 00:43:1610680 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0110681 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]e22e1362009-11-23 21:31:1210682}
10683
bncd16676a2016-07-20 16:23:0110684TEST_F(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:1510685 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:5210686 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
avibf0746c2015-12-09 19:53:1410687 const uint64_t kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:2110688 UploadFileElementReader::ScopedOverridingContentLengthForTests
10689 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:3310690
danakj1fd259a02016-04-16 03:17:0910691 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:1910692 element_readers.push_back(std::make_unique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:1410693 base::ThreadTaskRunnerHandle::Get().get(), temp_file_path, 0,
ricea2deef682016-09-09 08:04:0710694 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:2210695 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:2710696
10697 HttpRequestInfo request;
10698 request.method = "POST";
bncce36dca22015-04-21 22:11:2310699 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:2710700 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1010701 request.traffic_annotation =
10702 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]329b68b2012-11-14 17:54:2710703
danakj1fd259a02016-04-16 03:17:0910704 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610705 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]95d88ffe2010-02-04 21:25:3310706
10707 MockRead data_reads[] = {
10708 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
10709 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610710 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:3310711 };
Ryan Sleevib8d7ea02018-05-07 20:01:0110712 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0710713 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:3310714
[email protected]49639fa2011-12-20 23:22:4110715 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:3310716
tfarina42834112016-09-22 13:38:2010717 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110718 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]95d88ffe2010-02-04 21:25:3310719
10720 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110721 EXPECT_THAT(rv, IsError(ERR_UPLOAD_FILE_CHANGED));
[email protected]95d88ffe2010-02-04 21:25:3310722
bnc691fda62016-08-12 00:43:1610723 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210724 ASSERT_TRUE(response);
[email protected]95d88ffe2010-02-04 21:25:3310725
maksim.sisove869bf52016-06-23 17:11:5210726 EXPECT_FALSE(response->headers);
[email protected]95d88ffe2010-02-04 21:25:3310727
[email protected]dd3aa792013-07-16 19:10:2310728 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:3310729}
10730
bncd16676a2016-07-20 16:23:0110731TEST_F(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:1510732 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:5210733 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:3610734 std::string temp_file_content("Unreadable file.");
lazyboy8df84fc2017-04-12 02:12:4810735 ASSERT_EQ(static_cast<int>(temp_file_content.length()),
10736 base::WriteFile(temp_file, temp_file_content.c_str(),
10737 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:1110738 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:3610739
danakj1fd259a02016-04-16 03:17:0910740 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:1910741 element_readers.push_back(std::make_unique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:1410742 base::ThreadTaskRunnerHandle::Get().get(), temp_file, 0,
ricea2deef682016-09-09 08:04:0710743 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:2210744 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:2710745
10746 HttpRequestInfo request;
10747 request.method = "POST";
bncce36dca22015-04-21 22:11:2310748 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:2710749 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1010750 request.traffic_annotation =
10751 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]329b68b2012-11-14 17:54:2710752
[email protected]999dd8c2013-11-12 06:45:5410753 // If we try to upload an unreadable file, the transaction should fail.
danakj1fd259a02016-04-16 03:17:0910754 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610755 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]6624b4622010-03-29 19:58:3610756
Ryan Sleevib8d7ea02018-05-07 20:01:0110757 StaticSocketDataProvider data;
[email protected]bb88e1d32013-05-03 23:11:0710758 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:3610759
[email protected]49639fa2011-12-20 23:22:4110760 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:3610761
tfarina42834112016-09-22 13:38:2010762 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110763 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6624b4622010-03-29 19:58:3610764
10765 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110766 EXPECT_THAT(rv, IsError(ERR_ACCESS_DENIED));
[email protected]6624b4622010-03-29 19:58:3610767
[email protected]dd3aa792013-07-16 19:10:2310768 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:3610769}
10770
bncd16676a2016-07-20 16:23:0110771TEST_F(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
[email protected]02cad5d2013-10-02 08:14:0310772 class FakeUploadElementReader : public UploadElementReader {
10773 public:
Chris Watkins7a41d3552017-12-01 02:13:2710774 FakeUploadElementReader() = default;
10775 ~FakeUploadElementReader() override = default;
[email protected]02cad5d2013-10-02 08:14:0310776
Matt Menkecc1d3a902018-02-05 18:27:3310777 CompletionOnceCallback TakeCallback() { return std::move(callback_); }
[email protected]02cad5d2013-10-02 08:14:0310778
10779 // UploadElementReader overrides:
Matt Menkecc1d3a902018-02-05 18:27:3310780 int Init(CompletionOnceCallback callback) override {
10781 callback_ = std::move(callback);
[email protected]02cad5d2013-10-02 08:14:0310782 return ERR_IO_PENDING;
10783 }
avibf0746c2015-12-09 19:53:1410784 uint64_t GetContentLength() const override { return 0; }
10785 uint64_t BytesRemaining() const override { return 0; }
dchengb03027d2014-10-21 12:00:2010786 int Read(IOBuffer* buf,
10787 int buf_length,
Matt Menkecc1d3a902018-02-05 18:27:3310788 CompletionOnceCallback callback) override {
[email protected]02cad5d2013-10-02 08:14:0310789 return ERR_FAILED;
10790 }
10791
10792 private:
Matt Menkecc1d3a902018-02-05 18:27:3310793 CompletionOnceCallback callback_;
[email protected]02cad5d2013-10-02 08:14:0310794 };
10795
10796 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
danakj1fd259a02016-04-16 03:17:0910797 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
10798 element_readers.push_back(base::WrapUnique(fake_reader));
olli.raula6df48b2a2015-11-26 07:40:2210799 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02cad5d2013-10-02 08:14:0310800
10801 HttpRequestInfo request;
10802 request.method = "POST";
bncce36dca22015-04-21 22:11:2310803 request.url = GURL("http://www.example.org/upload");
[email protected]02cad5d2013-10-02 08:14:0310804 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1010805 request.traffic_annotation =
10806 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02cad5d2013-10-02 08:14:0310807
danakj1fd259a02016-04-16 03:17:0910808 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5810809 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1910810 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]02cad5d2013-10-02 08:14:0310811
10812 StaticSocketDataProvider data;
10813 session_deps_.socket_factory->AddSocketDataProvider(&data);
10814
10815 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2010816 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110817 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
fdoray92e35a72016-06-10 15:54:5510818 base::RunLoop().RunUntilIdle();
[email protected]02cad5d2013-10-02 08:14:0310819
10820 // Transaction is pending on request body initialization.
Matt Menkecc1d3a902018-02-05 18:27:3310821 CompletionOnceCallback init_callback = fake_reader->TakeCallback();
10822 ASSERT_FALSE(init_callback.is_null());
[email protected]02cad5d2013-10-02 08:14:0310823
10824 // Return Init()'s result after the transaction gets destroyed.
10825 trans.reset();
Matt Menkecc1d3a902018-02-05 18:27:3310826 std::move(init_callback).Run(OK); // Should not crash.
[email protected]02cad5d2013-10-02 08:14:0310827}
10828
[email protected]aeefc9e82010-02-19 16:18:2710829// Tests that changes to Auth realms are treated like auth rejections.
bncd16676a2016-07-20 16:23:0110830TEST_F(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:2710831 HttpRequestInfo request;
10832 request.method = "GET";
bncce36dca22015-04-21 22:11:2310833 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010834 request.traffic_annotation =
10835 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]aeefc9e82010-02-19 16:18:2710836
10837 // First transaction will request a resource and receive a Basic challenge
10838 // with realm="first_realm".
10839 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2310840 MockWrite(
10841 "GET / HTTP/1.1\r\n"
10842 "Host: www.example.org\r\n"
10843 "Connection: keep-alive\r\n"
10844 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710845 };
10846 MockRead data_reads1[] = {
10847 MockRead("HTTP/1.1 401 Unauthorized\r\n"
10848 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
10849 "\r\n"),
10850 };
10851
bnc691fda62016-08-12 00:43:1610852 // After calling trans.RestartWithAuth(), provide an Authentication header
[email protected]aeefc9e82010-02-19 16:18:2710853 // for first_realm. The server will reject and provide a challenge with
10854 // second_realm.
10855 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:2310856 MockWrite(
10857 "GET / HTTP/1.1\r\n"
10858 "Host: www.example.org\r\n"
10859 "Connection: keep-alive\r\n"
10860 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
10861 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710862 };
10863 MockRead data_reads2[] = {
10864 MockRead("HTTP/1.1 401 Unauthorized\r\n"
10865 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
10866 "\r\n"),
10867 };
10868
10869 // This again fails, and goes back to first_realm. Make sure that the
10870 // entry is removed from cache.
10871 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:2310872 MockWrite(
10873 "GET / HTTP/1.1\r\n"
10874 "Host: www.example.org\r\n"
10875 "Connection: keep-alive\r\n"
10876 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
10877 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710878 };
10879 MockRead data_reads3[] = {
10880 MockRead("HTTP/1.1 401 Unauthorized\r\n"
10881 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
10882 "\r\n"),
10883 };
10884
10885 // Try one last time (with the correct password) and get the resource.
10886 MockWrite data_writes4[] = {
bncce36dca22015-04-21 22:11:2310887 MockWrite(
10888 "GET / HTTP/1.1\r\n"
10889 "Host: www.example.org\r\n"
10890 "Connection: keep-alive\r\n"
10891 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
10892 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710893 };
10894 MockRead data_reads4[] = {
10895 MockRead("HTTP/1.1 200 OK\r\n"
10896 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:5010897 "Content-Length: 5\r\n"
10898 "\r\n"
10899 "hello"),
[email protected]aeefc9e82010-02-19 16:18:2710900 };
10901
Ryan Sleevib8d7ea02018-05-07 20:01:0110902 StaticSocketDataProvider data1(data_reads1, data_writes1);
10903 StaticSocketDataProvider data2(data_reads2, data_writes2);
10904 StaticSocketDataProvider data3(data_reads3, data_writes3);
10905 StaticSocketDataProvider data4(data_reads4, data_writes4);
[email protected]bb88e1d32013-05-03 23:11:0710906 session_deps_.socket_factory->AddSocketDataProvider(&data1);
10907 session_deps_.socket_factory->AddSocketDataProvider(&data2);
10908 session_deps_.socket_factory->AddSocketDataProvider(&data3);
10909 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:2710910
[email protected]49639fa2011-12-20 23:22:4110911 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:2710912
danakj1fd259a02016-04-16 03:17:0910913 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610914 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5010915
[email protected]aeefc9e82010-02-19 16:18:2710916 // Issue the first request with Authorize headers. There should be a
10917 // password prompt for first_realm waiting to be filled in after the
10918 // transaction completes.
tfarina42834112016-09-22 13:38:2010919 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110920 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710921 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0110922 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610923 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210924 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410925 const AuthChallengeInfo* challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210926 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410927 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310928 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410929 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910930 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710931
10932 // Issue the second request with an incorrect password. There should be a
10933 // password prompt for second_realm waiting to be filled in after the
10934 // transaction completes.
[email protected]49639fa2011-12-20 23:22:4110935 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:1610936 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBaz),
10937 callback2.callback());
robpercival214763f2016-07-01 23:27:0110938 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710939 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0110940 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610941 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210942 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410943 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210944 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410945 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310946 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410947 EXPECT_EQ("second_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910948 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710949
10950 // Issue the third request with another incorrect password. There should be
10951 // a password prompt for first_realm waiting to be filled in. If the password
10952 // prompt is not present, it indicates that the HttpAuthCacheEntry for
10953 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:4110954 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:1610955 rv = trans.RestartWithAuth(AuthCredentials(kSecond, kFou),
10956 callback3.callback());
robpercival214763f2016-07-01 23:27:0110957 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710958 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:0110959 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610960 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210961 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410962 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210963 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410964 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310965 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410966 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910967 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710968
10969 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:4110970 TestCompletionCallback callback4;
bnc691fda62016-08-12 00:43:1610971 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBar),
10972 callback4.callback());
robpercival214763f2016-07-01 23:27:0110973 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710974 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:0110975 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610976 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210977 ASSERT_TRUE(response);
10978 EXPECT_FALSE(response->auth_challenge);
[email protected]aeefc9e82010-02-19 16:18:2710979}
10980
Bence Béky230ac612017-08-30 19:17:0810981// Regression test for https://crbug.com/754395.
10982TEST_F(HttpNetworkTransactionTest, IgnoreAltSvcWithInvalidCert) {
10983 MockRead data_reads[] = {
10984 MockRead("HTTP/1.1 200 OK\r\n"),
10985 MockRead(kAlternativeServiceHttpHeader),
10986 MockRead("\r\n"),
10987 MockRead("hello world"),
10988 MockRead(SYNCHRONOUS, OK),
10989 };
10990
10991 HttpRequestInfo request;
10992 request.method = "GET";
10993 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010994 request.traffic_annotation =
10995 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Béky230ac612017-08-30 19:17:0810996
Ryan Sleevib8d7ea02018-05-07 20:01:0110997 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
Bence Béky230ac612017-08-30 19:17:0810998 session_deps_.socket_factory->AddSocketDataProvider(&data);
10999
11000 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911001 ssl.ssl_info.cert =
11002 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11003 ASSERT_TRUE(ssl.ssl_info.cert);
11004 ssl.ssl_info.cert_status = CERT_STATUS_COMMON_NAME_INVALID;
Bence Béky230ac612017-08-30 19:17:0811005 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11006
11007 TestCompletionCallback callback;
11008
11009 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11010 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11011
11012 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
11013 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11014
11015 url::SchemeHostPort test_server(request.url);
11016 HttpServerProperties* http_server_properties =
11017 session->http_server_properties();
11018 EXPECT_TRUE(
11019 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
11020
11021 EXPECT_THAT(callback.WaitForResult(), IsOk());
11022
11023 const HttpResponseInfo* response = trans.GetResponseInfo();
11024 ASSERT_TRUE(response);
11025 ASSERT_TRUE(response->headers);
11026 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11027 EXPECT_FALSE(response->was_fetched_via_spdy);
11028 EXPECT_FALSE(response->was_alpn_negotiated);
11029
11030 std::string response_data;
11031 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
11032 EXPECT_EQ("hello world", response_data);
11033
11034 EXPECT_TRUE(
11035 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
11036}
11037
bncd16676a2016-07-20 16:23:0111038TEST_F(HttpNetworkTransactionTest, HonorAlternativeServiceHeader) {
bncc958faa2015-07-31 18:14:5211039 MockRead data_reads[] = {
11040 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311041 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211042 MockRead("\r\n"),
11043 MockRead("hello world"),
11044 MockRead(SYNCHRONOUS, OK),
11045 };
11046
11047 HttpRequestInfo request;
11048 request.method = "GET";
bncb26024382016-06-29 02:39:4511049 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011050 request.traffic_annotation =
11051 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bncc958faa2015-07-31 18:14:5211052
Ryan Sleevib8d7ea02018-05-07 20:01:0111053 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:5211054 session_deps_.socket_factory->AddSocketDataProvider(&data);
11055
bncb26024382016-06-29 02:39:4511056 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911057 ssl.ssl_info.cert =
11058 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11059 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4511060 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11061
bncc958faa2015-07-31 18:14:5211062 TestCompletionCallback callback;
11063
danakj1fd259a02016-04-16 03:17:0911064 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611065 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5211066
tfarina42834112016-09-22 13:38:2011067 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111068 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5211069
bncb26024382016-06-29 02:39:4511070 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4011071 HttpServerProperties* http_server_properties =
11072 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3411073 EXPECT_TRUE(
11074 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5211075
robpercival214763f2016-07-01 23:27:0111076 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5211077
bnc691fda62016-08-12 00:43:1611078 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211079 ASSERT_TRUE(response);
11080 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5211081 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11082 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211083 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5211084
11085 std::string response_data;
bnc691fda62016-08-12 00:43:1611086 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5211087 EXPECT_EQ("hello world", response_data);
11088
zhongyic4de03032017-05-19 04:07:3411089 AlternativeServiceInfoVector alternative_service_info_vector =
11090 http_server_properties->GetAlternativeServiceInfos(test_server);
11091 ASSERT_EQ(1u, alternative_service_info_vector.size());
11092 AlternativeService alternative_service(kProtoHTTP2, "mail.example.org", 443);
11093 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5411094 alternative_service_info_vector[0].alternative_service());
bncc958faa2015-07-31 18:14:5211095}
11096
bnce3dd56f2016-06-01 10:37:1111097// Regression test for https://crbug.com/615497.
bncd16676a2016-07-20 16:23:0111098TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1111099 DoNotParseAlternativeServiceHeaderOnInsecureRequest) {
bnce3dd56f2016-06-01 10:37:1111100 MockRead data_reads[] = {
11101 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311102 MockRead(kAlternativeServiceHttpHeader),
bnce3dd56f2016-06-01 10:37:1111103 MockRead("\r\n"),
11104 MockRead("hello world"),
11105 MockRead(SYNCHRONOUS, OK),
11106 };
11107
11108 HttpRequestInfo request;
11109 request.method = "GET";
11110 request.url = GURL("http://www.example.org/");
11111 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1011112 request.traffic_annotation =
11113 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnce3dd56f2016-06-01 10:37:1111114
Ryan Sleevib8d7ea02018-05-07 20:01:0111115 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
bnce3dd56f2016-06-01 10:37:1111116 session_deps_.socket_factory->AddSocketDataProvider(&data);
11117
11118 TestCompletionCallback callback;
11119
11120 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611121 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1111122
11123 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4011124 HttpServerProperties* http_server_properties =
11125 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3411126 EXPECT_TRUE(
11127 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1111128
tfarina42834112016-09-22 13:38:2011129 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111130 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11131 EXPECT_THAT(callback.WaitForResult(), IsOk());
bnce3dd56f2016-06-01 10:37:1111132
bnc691fda62016-08-12 00:43:1611133 const HttpResponseInfo* response = trans.GetResponseInfo();
bnce3dd56f2016-06-01 10:37:1111134 ASSERT_TRUE(response);
11135 ASSERT_TRUE(response->headers);
11136 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11137 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211138 EXPECT_FALSE(response->was_alpn_negotiated);
bnce3dd56f2016-06-01 10:37:1111139
11140 std::string response_data;
bnc691fda62016-08-12 00:43:1611141 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnce3dd56f2016-06-01 10:37:1111142 EXPECT_EQ("hello world", response_data);
11143
zhongyic4de03032017-05-19 04:07:3411144 EXPECT_TRUE(
11145 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1111146}
11147
bnca86731e2017-04-17 12:31:2811148// HTTP/2 Alternative Services should be disabled by default.
bnc8bef8da22016-05-30 01:28:2511149// TODO(bnc): Remove when https://crbug.com/615413 is fixed.
bncd16676a2016-07-20 16:23:0111150TEST_F(HttpNetworkTransactionTest,
bnc8bef8da22016-05-30 01:28:2511151 DisableHTTP2AlternativeServicesWithDifferentHost) {
bnca86731e2017-04-17 12:31:2811152 session_deps_.enable_http2_alternative_service = false;
bncb26024382016-06-29 02:39:4511153
bnc8bef8da22016-05-30 01:28:2511154 HttpRequestInfo request;
11155 request.method = "GET";
bncb26024382016-06-29 02:39:4511156 request.url = GURL("https://www.example.org/");
bnc8bef8da22016-05-30 01:28:2511157 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1011158 request.traffic_annotation =
11159 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8bef8da22016-05-30 01:28:2511160
11161 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11162 StaticSocketDataProvider first_data;
11163 first_data.set_connect_data(mock_connect);
11164 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4511165 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611166 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511167 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
bnc8bef8da22016-05-30 01:28:2511168
11169 MockRead data_reads[] = {
11170 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
11171 MockRead(ASYNC, OK),
11172 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111173 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
bnc8bef8da22016-05-30 01:28:2511174 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
11175
11176 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11177
bnc525e175a2016-06-20 12:36:4011178 HttpServerProperties* http_server_properties =
bnc8bef8da22016-05-30 01:28:2511179 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2111180 AlternativeService alternative_service(kProtoHTTP2, "different.example.org",
11181 444);
bnc8bef8da22016-05-30 01:28:2511182 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111183 http_server_properties->SetHttp2AlternativeService(
bnc8bef8da22016-05-30 01:28:2511184 url::SchemeHostPort(request.url), alternative_service, expiration);
11185
bnc691fda62016-08-12 00:43:1611186 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc8bef8da22016-05-30 01:28:2511187 TestCompletionCallback callback;
11188
tfarina42834112016-09-22 13:38:2011189 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc8bef8da22016-05-30 01:28:2511190 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0111191 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc8bef8da22016-05-30 01:28:2511192}
11193
bnce3dd56f2016-06-01 10:37:1111194// Regression test for https://crbug.com/615497:
11195// Alternative Services should be disabled for http origin.
bncd16676a2016-07-20 16:23:0111196TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1111197 DisableAlternativeServicesForInsecureOrigin) {
bnce3dd56f2016-06-01 10:37:1111198 HttpRequestInfo request;
11199 request.method = "GET";
11200 request.url = GURL("http://www.example.org/");
11201 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1011202 request.traffic_annotation =
11203 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnce3dd56f2016-06-01 10:37:1111204
11205 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11206 StaticSocketDataProvider first_data;
11207 first_data.set_connect_data(mock_connect);
11208 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
11209
11210 MockRead data_reads[] = {
11211 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
11212 MockRead(ASYNC, OK),
11213 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111214 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
bnce3dd56f2016-06-01 10:37:1111215 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
11216
11217 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11218
bnc525e175a2016-06-20 12:36:4011219 HttpServerProperties* http_server_properties =
bnce3dd56f2016-06-01 10:37:1111220 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2111221 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnce3dd56f2016-06-01 10:37:1111222 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111223 http_server_properties->SetHttp2AlternativeService(
bnce3dd56f2016-06-01 10:37:1111224 url::SchemeHostPort(request.url), alternative_service, expiration);
11225
bnc691fda62016-08-12 00:43:1611226 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1111227 TestCompletionCallback callback;
11228
tfarina42834112016-09-22 13:38:2011229 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnce3dd56f2016-06-01 10:37:1111230 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0111231 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnce3dd56f2016-06-01 10:37:1111232}
11233
bncd16676a2016-07-20 16:23:0111234TEST_F(HttpNetworkTransactionTest, ClearAlternativeServices) {
bnc4f575852015-10-14 18:35:0811235 // Set an alternative service for origin.
danakj1fd259a02016-04-16 03:17:0911236 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4011237 HttpServerProperties* http_server_properties =
11238 session->http_server_properties();
bncb26024382016-06-29 02:39:4511239 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc3472afd2016-11-17 15:27:2111240 AlternativeService alternative_service(kProtoQUIC, "", 80);
bnc4f575852015-10-14 18:35:0811241 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111242 http_server_properties->SetQuicAlternativeService(
11243 test_server, alternative_service, expiration,
11244 session->params().quic_supported_versions);
zhongyic4de03032017-05-19 04:07:3411245 EXPECT_EQ(
11246 1u,
11247 http_server_properties->GetAlternativeServiceInfos(test_server).size());
bnc4f575852015-10-14 18:35:0811248
11249 // Send a clear header.
11250 MockRead data_reads[] = {
11251 MockRead("HTTP/1.1 200 OK\r\n"),
11252 MockRead("Alt-Svc: clear\r\n"),
11253 MockRead("\r\n"),
11254 MockRead("hello world"),
11255 MockRead(SYNCHRONOUS, OK),
11256 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111257 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
bnc4f575852015-10-14 18:35:0811258 session_deps_.socket_factory->AddSocketDataProvider(&data);
11259
bncb26024382016-06-29 02:39:4511260 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911261 ssl.ssl_info.cert =
11262 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11263 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4511264 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11265
bnc4f575852015-10-14 18:35:0811266 HttpRequestInfo request;
11267 request.method = "GET";
bncb26024382016-06-29 02:39:4511268 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011269 request.traffic_annotation =
11270 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc4f575852015-10-14 18:35:0811271
11272 TestCompletionCallback callback;
11273
bnc691fda62016-08-12 00:43:1611274 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc4f575852015-10-14 18:35:0811275
tfarina42834112016-09-22 13:38:2011276 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111277 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc4f575852015-10-14 18:35:0811278
bnc691fda62016-08-12 00:43:1611279 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211280 ASSERT_TRUE(response);
11281 ASSERT_TRUE(response->headers);
bnc4f575852015-10-14 18:35:0811282 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11283 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211284 EXPECT_FALSE(response->was_alpn_negotiated);
bnc4f575852015-10-14 18:35:0811285
11286 std::string response_data;
bnc691fda62016-08-12 00:43:1611287 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc4f575852015-10-14 18:35:0811288 EXPECT_EQ("hello world", response_data);
11289
zhongyic4de03032017-05-19 04:07:3411290 EXPECT_TRUE(
11291 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnc4f575852015-10-14 18:35:0811292}
11293
bncd16676a2016-07-20 16:23:0111294TEST_F(HttpNetworkTransactionTest, HonorMultipleAlternativeServiceHeaders) {
bncc958faa2015-07-31 18:14:5211295 MockRead data_reads[] = {
11296 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311297 MockRead("Alt-Svc: h2=\"www.example.com:443\","),
11298 MockRead("h2=\":1234\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:5211299 MockRead("hello world"),
11300 MockRead(SYNCHRONOUS, OK),
11301 };
11302
11303 HttpRequestInfo request;
11304 request.method = "GET";
bncb26024382016-06-29 02:39:4511305 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011306 request.traffic_annotation =
11307 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bncc958faa2015-07-31 18:14:5211308
Ryan Sleevib8d7ea02018-05-07 20:01:0111309 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:5211310 session_deps_.socket_factory->AddSocketDataProvider(&data);
11311
bncb26024382016-06-29 02:39:4511312 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911313 ssl.ssl_info.cert =
11314 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11315 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4511316 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11317
bncc958faa2015-07-31 18:14:5211318 TestCompletionCallback callback;
11319
danakj1fd259a02016-04-16 03:17:0911320 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611321 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5211322
tfarina42834112016-09-22 13:38:2011323 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111324 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5211325
bncb26024382016-06-29 02:39:4511326 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc525e175a2016-06-20 12:36:4011327 HttpServerProperties* http_server_properties =
11328 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3411329 EXPECT_TRUE(
11330 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5211331
robpercival214763f2016-07-01 23:27:0111332 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5211333
bnc691fda62016-08-12 00:43:1611334 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211335 ASSERT_TRUE(response);
11336 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5211337 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11338 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211339 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5211340
11341 std::string response_data;
bnc691fda62016-08-12 00:43:1611342 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5211343 EXPECT_EQ("hello world", response_data);
11344
zhongyic4de03032017-05-19 04:07:3411345 AlternativeServiceInfoVector alternative_service_info_vector =
11346 http_server_properties->GetAlternativeServiceInfos(test_server);
11347 ASSERT_EQ(2u, alternative_service_info_vector.size());
11348
11349 AlternativeService alternative_service(kProtoHTTP2, "www.example.com", 443);
11350 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5411351 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3411352 AlternativeService alternative_service_2(kProtoHTTP2, "www.example.org",
11353 1234);
11354 EXPECT_EQ(alternative_service_2,
zhongyi422ce352017-06-09 23:28:5411355 alternative_service_info_vector[1].alternative_service());
bncc958faa2015-07-31 18:14:5211356}
11357
bncd16676a2016-07-20 16:23:0111358TEST_F(HttpNetworkTransactionTest, IdentifyQuicBroken) {
zhongyi3d4a55e72016-04-22 20:36:4611359 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0211360 HostPortPair alternative("alternative.example.org", 443);
11361 std::string origin_url = "https://origin.example.org:443";
11362 std::string alternative_url = "https://alternative.example.org:443";
11363
11364 // Negotiate HTTP/1.1 with alternative.example.org.
11365 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611366 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0211367 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11368
11369 // HTTP/1.1 data for request.
11370 MockWrite http_writes[] = {
11371 MockWrite("GET / HTTP/1.1\r\n"
11372 "Host: alternative.example.org\r\n"
11373 "Connection: keep-alive\r\n\r\n"),
11374 };
11375
11376 MockRead http_reads[] = {
11377 MockRead("HTTP/1.1 200 OK\r\n"
11378 "Content-Type: text/html; charset=iso-8859-1\r\n"
11379 "Content-Length: 40\r\n\r\n"
11380 "first HTTP/1.1 response from alternative"),
11381 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111382 StaticSocketDataProvider http_data(http_reads, http_writes);
zhongyi48704c182015-12-07 07:52:0211383 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
11384
11385 StaticSocketDataProvider data_refused;
11386 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
11387 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
11388
zhongyi3d4a55e72016-04-22 20:36:4611389 // Set up a QUIC alternative service for server.
danakj1fd259a02016-04-16 03:17:0911390 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4011391 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0211392 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2111393 AlternativeService alternative_service(kProtoQUIC, alternative);
zhongyi48704c182015-12-07 07:52:0211394 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111395 http_server_properties->SetQuicAlternativeService(
11396 server, alternative_service, expiration,
11397 HttpNetworkSession::Params().quic_supported_versions);
zhongyi48704c182015-12-07 07:52:0211398 // Mark the QUIC alternative service as broken.
11399 http_server_properties->MarkAlternativeServiceBroken(alternative_service);
11400
zhongyi48704c182015-12-07 07:52:0211401 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4611402 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0211403 request.method = "GET";
11404 request.url = GURL(origin_url);
Ramin Halavatib5e433e62018-02-07 07:41:1011405 request.traffic_annotation =
11406 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
11407
zhongyi48704c182015-12-07 07:52:0211408 TestCompletionCallback callback;
11409 NetErrorDetails details;
11410 EXPECT_FALSE(details.quic_broken);
11411
tfarina42834112016-09-22 13:38:2011412 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1611413 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0211414 EXPECT_TRUE(details.quic_broken);
11415}
11416
bncd16676a2016-07-20 16:23:0111417TEST_F(HttpNetworkTransactionTest, IdentifyQuicNotBroken) {
zhongyi3d4a55e72016-04-22 20:36:4611418 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0211419 HostPortPair alternative1("alternative1.example.org", 443);
11420 HostPortPair alternative2("alternative2.example.org", 443);
11421 std::string origin_url = "https://origin.example.org:443";
11422 std::string alternative_url1 = "https://alternative1.example.org:443";
11423 std::string alternative_url2 = "https://alternative2.example.org:443";
11424
11425 // Negotiate HTTP/1.1 with alternative1.example.org.
11426 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611427 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0211428 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11429
11430 // HTTP/1.1 data for request.
11431 MockWrite http_writes[] = {
11432 MockWrite("GET / HTTP/1.1\r\n"
11433 "Host: alternative1.example.org\r\n"
11434 "Connection: keep-alive\r\n\r\n"),
11435 };
11436
11437 MockRead http_reads[] = {
11438 MockRead("HTTP/1.1 200 OK\r\n"
11439 "Content-Type: text/html; charset=iso-8859-1\r\n"
11440 "Content-Length: 40\r\n\r\n"
11441 "first HTTP/1.1 response from alternative1"),
11442 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111443 StaticSocketDataProvider http_data(http_reads, http_writes);
zhongyi48704c182015-12-07 07:52:0211444 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
11445
11446 StaticSocketDataProvider data_refused;
11447 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
11448 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
11449
danakj1fd259a02016-04-16 03:17:0911450 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4011451 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0211452 session->http_server_properties();
11453
zhongyi3d4a55e72016-04-22 20:36:4611454 // Set up two QUIC alternative services for server.
zhongyi48704c182015-12-07 07:52:0211455 AlternativeServiceInfoVector alternative_service_info_vector;
11456 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
11457
bnc3472afd2016-11-17 15:27:2111458 AlternativeService alternative_service1(kProtoQUIC, alternative1);
zhongyie537a002017-06-27 16:48:2111459 alternative_service_info_vector.push_back(
11460 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
11461 alternative_service1, expiration,
11462 session->params().quic_supported_versions));
bnc3472afd2016-11-17 15:27:2111463 AlternativeService alternative_service2(kProtoQUIC, alternative2);
zhongyie537a002017-06-27 16:48:2111464 alternative_service_info_vector.push_back(
11465 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
11466 alternative_service2, expiration,
11467 session->params().quic_supported_versions));
zhongyi48704c182015-12-07 07:52:0211468
11469 http_server_properties->SetAlternativeServices(
zhongyi3d4a55e72016-04-22 20:36:4611470 server, alternative_service_info_vector);
zhongyi48704c182015-12-07 07:52:0211471
11472 // Mark one of the QUIC alternative service as broken.
11473 http_server_properties->MarkAlternativeServiceBroken(alternative_service1);
zhongyic4de03032017-05-19 04:07:3411474 EXPECT_EQ(2u,
11475 http_server_properties->GetAlternativeServiceInfos(server).size());
zhongyi48704c182015-12-07 07:52:0211476
zhongyi48704c182015-12-07 07:52:0211477 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4611478 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0211479 request.method = "GET";
11480 request.url = GURL(origin_url);
Ramin Halavatib5e433e62018-02-07 07:41:1011481 request.traffic_annotation =
11482 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
11483
zhongyi48704c182015-12-07 07:52:0211484 TestCompletionCallback callback;
11485 NetErrorDetails details;
11486 EXPECT_FALSE(details.quic_broken);
11487
tfarina42834112016-09-22 13:38:2011488 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1611489 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0211490 EXPECT_FALSE(details.quic_broken);
11491}
11492
bncd16676a2016-07-20 16:23:0111493TEST_F(HttpNetworkTransactionTest, MarkBrokenAlternateProtocolAndFallback) {
[email protected]564b4912010-03-09 16:30:4211494 HttpRequestInfo request;
11495 request.method = "GET";
bncb26024382016-06-29 02:39:4511496 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011497 request.traffic_annotation =
11498 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]564b4912010-03-09 16:30:4211499
[email protected]d973e99a2012-02-17 21:02:3611500 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:4211501 StaticSocketDataProvider first_data;
11502 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711503 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4511504 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611505 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511506 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]564b4912010-03-09 16:30:4211507
11508 MockRead data_reads[] = {
11509 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11510 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611511 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:4211512 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111513 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711514 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:4211515
danakj1fd259a02016-04-16 03:17:0911516 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:4211517
bnc525e175a2016-06-20 12:36:4011518 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311519 session->http_server_properties();
zhongyi3d4a55e72016-04-22 20:36:4611520 const url::SchemeHostPort server(request.url);
[email protected]3912662a32011-10-04 00:51:1111521 // Port must be < 1024, or the header will be ignored (since initial port was
11522 // port 80 (another restricted port).
zhongyie537a002017-06-27 16:48:2111523 // Port is ignored by MockConnect anyway.
11524 const AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11525 666);
bnc7dc7e1b42015-07-28 14:43:1211526 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111527 http_server_properties->SetHttp2AlternativeService(
11528 server, alternative_service, expiration);
[email protected]564b4912010-03-09 16:30:4211529
bnc691fda62016-08-12 00:43:1611530 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111531 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:4211532
tfarina42834112016-09-22 13:38:2011533 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111534 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11535 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]564b4912010-03-09 16:30:4211536
bnc691fda62016-08-12 00:43:1611537 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211538 ASSERT_TRUE(response);
11539 ASSERT_TRUE(response->headers);
[email protected]564b4912010-03-09 16:30:4211540 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11541
11542 std::string response_data;
bnc691fda62016-08-12 00:43:1611543 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]564b4912010-03-09 16:30:4211544 EXPECT_EQ("hello world", response_data);
11545
zhongyic4de03032017-05-19 04:07:3411546 const AlternativeServiceInfoVector alternative_service_info_vector =
11547 http_server_properties->GetAlternativeServiceInfos(server);
11548 ASSERT_EQ(1u, alternative_service_info_vector.size());
11549 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5411550 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3411551 EXPECT_TRUE(
11552 http_server_properties->IsAlternativeServiceBroken(alternative_service));
[email protected]564b4912010-03-09 16:30:4211553}
11554
bnc55ff9da2015-08-19 18:42:3511555// Ensure that we are not allowed to redirect traffic via an alternate protocol
11556// to an unrestricted (port >= 1024) when the original traffic was on a
11557// restricted port (port < 1024). Ensure that we can redirect in all other
11558// cases.
bncd16676a2016-07-20 16:23:0111559TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:1111560 HttpRequestInfo restricted_port_request;
11561 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511562 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1111563 restricted_port_request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1011564 restricted_port_request.traffic_annotation =
11565 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1111566
[email protected]d973e99a2012-02-17 21:02:3611567 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111568 StaticSocketDataProvider first_data;
11569 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711570 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111571
11572 MockRead data_reads[] = {
11573 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11574 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611575 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111576 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111577 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711578 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4511579 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611580 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511581 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1111582
danakj1fd259a02016-04-16 03:17:0911583 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111584
bnc525e175a2016-06-20 12:36:4011585 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311586 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1111587 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2111588 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11589 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211590 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111591 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611592 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011593 expiration);
[email protected]3912662a32011-10-04 00:51:1111594
bnc691fda62016-08-12 00:43:1611595 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111596 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111597
tfarina42834112016-09-22 13:38:2011598 int rv = trans.Start(&restricted_port_request, callback.callback(),
11599 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111600 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111601 // Invalid change to unrestricted port should fail.
robpercival214763f2016-07-01 23:27:0111602 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_REFUSED));
[email protected]c54c6962013-02-01 04:53:1911603}
[email protected]3912662a32011-10-04 00:51:1111604
bnc55ff9da2015-08-19 18:42:3511605// Ensure that we are allowed to redirect traffic via an alternate protocol to
11606// an unrestricted (port >= 1024) when the original traffic was on a restricted
11607// port (port < 1024) if we set |enable_user_alternate_protocol_ports|.
bncd16676a2016-07-20 16:23:0111608TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedPermitted) {
[email protected]bb88e1d32013-05-03 23:11:0711609 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:1911610
11611 HttpRequestInfo restricted_port_request;
11612 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511613 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]c54c6962013-02-01 04:53:1911614 restricted_port_request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1011615 restricted_port_request.traffic_annotation =
11616 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]c54c6962013-02-01 04:53:1911617
11618 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11619 StaticSocketDataProvider first_data;
11620 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711621 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:1911622
11623 MockRead data_reads[] = {
11624 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11625 MockRead("hello world"),
11626 MockRead(ASYNC, OK),
11627 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111628 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711629 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4511630 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611631 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511632 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]c54c6962013-02-01 04:53:1911633
danakj1fd259a02016-04-16 03:17:0911634 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:1911635
bnc525e175a2016-06-20 12:36:4011636 HttpServerProperties* http_server_properties =
[email protected]c54c6962013-02-01 04:53:1911637 session->http_server_properties();
11638 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2111639 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11640 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211641 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111642 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611643 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011644 expiration);
[email protected]c54c6962013-02-01 04:53:1911645
bnc691fda62016-08-12 00:43:1611646 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]c54c6962013-02-01 04:53:1911647 TestCompletionCallback callback;
11648
tfarina42834112016-09-22 13:38:2011649 EXPECT_EQ(ERR_IO_PENDING,
11650 trans.Start(&restricted_port_request, callback.callback(),
11651 NetLogWithSource()));
[email protected]c54c6962013-02-01 04:53:1911652 // Change to unrestricted port should succeed.
robpercival214763f2016-07-01 23:27:0111653 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111654}
11655
bnc55ff9da2015-08-19 18:42:3511656// Ensure that we are not allowed to redirect traffic via an alternate protocol
11657// to an unrestricted (port >= 1024) when the original traffic was on a
11658// restricted port (port < 1024). Ensure that we can redirect in all other
11659// cases.
bncd16676a2016-07-20 16:23:0111660TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:1111661 HttpRequestInfo restricted_port_request;
11662 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511663 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1111664 restricted_port_request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1011665 restricted_port_request.traffic_annotation =
11666 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1111667
[email protected]d973e99a2012-02-17 21:02:3611668 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111669 StaticSocketDataProvider first_data;
11670 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711671 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111672
11673 MockRead data_reads[] = {
11674 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11675 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611676 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111677 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111678 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711679 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1111680
bncb26024382016-06-29 02:39:4511681 SSLSocketDataProvider ssl(ASYNC, OK);
11682 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11683
danakj1fd259a02016-04-16 03:17:0911684 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111685
bnc525e175a2016-06-20 12:36:4011686 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311687 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1111688 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2111689 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11690 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211691 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111692 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611693 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011694 expiration);
[email protected]3912662a32011-10-04 00:51:1111695
bnc691fda62016-08-12 00:43:1611696 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111697 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111698
tfarina42834112016-09-22 13:38:2011699 int rv = trans.Start(&restricted_port_request, callback.callback(),
11700 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111701 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111702 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0111703 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111704}
11705
bnc55ff9da2015-08-19 18:42:3511706// Ensure that we are not allowed to redirect traffic via an alternate protocol
11707// to an unrestricted (port >= 1024) when the original traffic was on a
11708// restricted port (port < 1024). Ensure that we can redirect in all other
11709// cases.
bncd16676a2016-07-20 16:23:0111710TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:1111711 HttpRequestInfo unrestricted_port_request;
11712 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511713 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1111714 unrestricted_port_request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1011715 unrestricted_port_request.traffic_annotation =
11716 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1111717
[email protected]d973e99a2012-02-17 21:02:3611718 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111719 StaticSocketDataProvider first_data;
11720 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711721 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111722
11723 MockRead data_reads[] = {
11724 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11725 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611726 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111727 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111728 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711729 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4511730 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611731 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511732 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1111733
danakj1fd259a02016-04-16 03:17:0911734 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111735
bnc525e175a2016-06-20 12:36:4011736 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311737 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1111738 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2111739 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11740 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211741 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111742 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611743 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011744 expiration);
[email protected]3912662a32011-10-04 00:51:1111745
bnc691fda62016-08-12 00:43:1611746 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111747 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111748
bnc691fda62016-08-12 00:43:1611749 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2011750 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111751 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111752 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0111753 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111754}
11755
bnc55ff9da2015-08-19 18:42:3511756// Ensure that we are not allowed to redirect traffic via an alternate protocol
11757// to an unrestricted (port >= 1024) when the original traffic was on a
11758// restricted port (port < 1024). Ensure that we can redirect in all other
11759// cases.
bncd16676a2016-07-20 16:23:0111760TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:1111761 HttpRequestInfo unrestricted_port_request;
11762 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511763 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1111764 unrestricted_port_request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1011765 unrestricted_port_request.traffic_annotation =
11766 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1111767
[email protected]d973e99a2012-02-17 21:02:3611768 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111769 StaticSocketDataProvider first_data;
11770 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711771 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111772
11773 MockRead data_reads[] = {
11774 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11775 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611776 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111777 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111778 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711779 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1111780
bncb26024382016-06-29 02:39:4511781 SSLSocketDataProvider ssl(ASYNC, OK);
11782 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11783
danakj1fd259a02016-04-16 03:17:0911784 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111785
bnc525e175a2016-06-20 12:36:4011786 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311787 session->http_server_properties();
bnc0bbb02622015-07-23 10:06:2211788 const int kUnrestrictedAlternatePort = 1025;
bnc3472afd2016-11-17 15:27:2111789 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11790 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211791 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111792 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611793 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011794 expiration);
[email protected]3912662a32011-10-04 00:51:1111795
bnc691fda62016-08-12 00:43:1611796 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111797 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111798
bnc691fda62016-08-12 00:43:1611799 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2011800 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111801 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111802 // Valid change to an unrestricted port should pass.
robpercival214763f2016-07-01 23:27:0111803 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111804}
11805
bnc55ff9da2015-08-19 18:42:3511806// Ensure that we are not allowed to redirect traffic via an alternate protocol
Xida Chen9bfe0b62018-04-24 19:52:2111807// to an unsafe port, and that we resume the second HttpStreamFactory::Job once
11808// the alternate protocol request fails.
bncd16676a2016-07-20 16:23:0111809TEST_F(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:0211810 HttpRequestInfo request;
11811 request.method = "GET";
bncce36dca22015-04-21 22:11:2311812 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011813 request.traffic_annotation =
11814 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]eb6234e2012-01-19 01:50:0211815
11816 // The alternate protocol request will error out before we attempt to connect,
11817 // so only the standard HTTP request will try to connect.
11818 MockRead data_reads[] = {
11819 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11820 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611821 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:0211822 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111823 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711824 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:0211825
danakj1fd259a02016-04-16 03:17:0911826 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:0211827
bnc525e175a2016-06-20 12:36:4011828 HttpServerProperties* http_server_properties =
[email protected]eb6234e2012-01-19 01:50:0211829 session->http_server_properties();
11830 const int kUnsafePort = 7;
bnc3472afd2016-11-17 15:27:2111831 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11832 kUnsafePort);
bnc7dc7e1b42015-07-28 14:43:1211833 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111834 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611835 url::SchemeHostPort(request.url), alternative_service, expiration);
[email protected]eb6234e2012-01-19 01:50:0211836
bnc691fda62016-08-12 00:43:1611837 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]eb6234e2012-01-19 01:50:0211838 TestCompletionCallback callback;
11839
tfarina42834112016-09-22 13:38:2011840 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111841 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]eb6234e2012-01-19 01:50:0211842 // The HTTP request should succeed.
robpercival214763f2016-07-01 23:27:0111843 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb6234e2012-01-19 01:50:0211844
bnc691fda62016-08-12 00:43:1611845 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211846 ASSERT_TRUE(response);
11847 ASSERT_TRUE(response->headers);
[email protected]eb6234e2012-01-19 01:50:0211848 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11849
11850 std::string response_data;
bnc691fda62016-08-12 00:43:1611851 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]eb6234e2012-01-19 01:50:0211852 EXPECT_EQ("hello world", response_data);
11853}
11854
bncd16676a2016-07-20 16:23:0111855TEST_F(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]2ff8b312010-04-26 22:20:5411856 HttpRequestInfo request;
11857 request.method = "GET";
bncb26024382016-06-29 02:39:4511858 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011859 request.traffic_annotation =
11860 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2ff8b312010-04-26 22:20:5411861
11862 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211863 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311864 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211865 MockRead("\r\n"),
11866 MockRead("hello world"),
11867 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11868 MockRead(ASYNC, OK)};
[email protected]2ff8b312010-04-26 22:20:5411869
Ryan Sleevib8d7ea02018-05-07 20:01:0111870 StaticSocketDataProvider first_transaction(data_reads,
11871 base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711872 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4511873 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611874 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511875 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5411876
bnc032658ba2016-09-26 18:17:1511877 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5411878
Ryan Hamilton0239aac2018-05-19 00:03:1311879 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4511880 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4111881 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5411882
Ryan Hamilton0239aac2018-05-19 00:03:1311883 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
11884 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5411885 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111886 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5411887 };
11888
Ryan Sleevib8d7ea02018-05-07 20:01:0111889 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0711890 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5411891
[email protected]d973e99a2012-02-17 21:02:3611892 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0111893 StaticSocketDataProvider hanging_non_alternate_protocol_socket;
[email protected]2d6728692011-03-12 01:39:5511894 hanging_non_alternate_protocol_socket.set_connect_data(
11895 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0711896 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511897 &hanging_non_alternate_protocol_socket);
11898
[email protected]49639fa2011-12-20 23:22:4111899 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5411900
danakj1fd259a02016-04-16 03:17:0911901 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5811902 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1911903 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5411904
tfarina42834112016-09-22 13:38:2011905 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111906 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11907 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411908
11909 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211910 ASSERT_TRUE(response);
11911 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5411912 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11913
11914 std::string response_data;
robpercival214763f2016-07-01 23:27:0111915 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411916 EXPECT_EQ("hello world", response_data);
11917
bnc87dcefc2017-05-25 12:47:5811918 trans =
Jeremy Roman0579ed62017-08-29 15:56:1911919 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5411920
tfarina42834112016-09-22 13:38:2011921 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111922 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11923 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411924
11925 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211926 ASSERT_TRUE(response);
11927 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211928 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5311929 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211930 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5411931
robpercival214763f2016-07-01 23:27:0111932 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411933 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:5411934}
11935
bncd16676a2016-07-20 16:23:0111936TEST_F(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]2d6728692011-03-12 01:39:5511937 HttpRequestInfo request;
11938 request.method = "GET";
bncb26024382016-06-29 02:39:4511939 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011940 request.traffic_annotation =
11941 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d6728692011-03-12 01:39:5511942
bncb26024382016-06-29 02:39:4511943 // First transaction receives Alt-Svc header over HTTP/1.1.
[email protected]2d6728692011-03-12 01:39:5511944 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211945 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311946 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211947 MockRead("\r\n"),
11948 MockRead("hello world"),
11949 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11950 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5511951 };
11952
Ryan Sleevib8d7ea02018-05-07 20:01:0111953 StaticSocketDataProvider http11_data(data_reads, base::span<MockWrite>());
bncb26024382016-06-29 02:39:4511954 session_deps_.socket_factory->AddSocketDataProvider(&http11_data);
[email protected]2d6728692011-03-12 01:39:5511955
bncb26024382016-06-29 02:39:4511956 SSLSocketDataProvider ssl_http11(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911957 ssl_http11.ssl_info.cert =
11958 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11959 ASSERT_TRUE(ssl_http11.ssl_info.cert);
bncb26024382016-06-29 02:39:4511960 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
11961
11962 // Second transaction starts an alternative and a non-alternative Job.
11963 // Both sockets hang.
[email protected]d973e99a2012-02-17 21:02:3611964 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0111965 StaticSocketDataProvider hanging_socket1;
mmenkecc2298e2015-12-07 18:20:1811966 hanging_socket1.set_connect_data(never_finishing_connect);
mmenkecc2298e2015-12-07 18:20:1811967 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket1);
11968
Ryan Sleevib8d7ea02018-05-07 20:01:0111969 StaticSocketDataProvider hanging_socket2;
mmenkecc2298e2015-12-07 18:20:1811970 hanging_socket2.set_connect_data(never_finishing_connect);
11971 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket2);
[email protected]2d6728692011-03-12 01:39:5511972
bncb26024382016-06-29 02:39:4511973 // Third transaction starts an alternative and a non-alternative job.
11974 // The non-alternative job hangs, but the alternative one succeeds.
11975 // The second transaction, still pending, binds to this socket.
Ryan Hamilton0239aac2018-05-19 00:03:1311976 spdy::SpdySerializedFrame req1(
bncb26024382016-06-29 02:39:4511977 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1311978 spdy::SpdySerializedFrame req2(
bncb26024382016-06-29 02:39:4511979 spdy_util_.ConstructSpdyGet("https://www.example.org/", 3, LOWEST));
[email protected]2d6728692011-03-12 01:39:5511980 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4111981 CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
[email protected]2d6728692011-03-12 01:39:5511982 };
Ryan Hamilton0239aac2018-05-19 00:03:1311983 spdy::SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
11984 spdy::SpdySerializedFrame data1(spdy_util_.ConstructSpdyDataFrame(1, true));
11985 spdy::SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
11986 spdy::SpdySerializedFrame data2(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]2d6728692011-03-12 01:39:5511987 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111988 CreateMockRead(resp1, 2), CreateMockRead(data1, 3),
11989 CreateMockRead(resp2, 4), CreateMockRead(data2, 5),
rch8e6c6c42015-05-01 14:05:1311990 MockRead(ASYNC, 0, 6),
[email protected]2d6728692011-03-12 01:39:5511991 };
11992
Ryan Sleevib8d7ea02018-05-07 20:01:0111993 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0711994 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:5511995
bnc032658ba2016-09-26 18:17:1511996 AddSSLSocketData();
bncb26024382016-06-29 02:39:4511997
Ryan Sleevib8d7ea02018-05-07 20:01:0111998 StaticSocketDataProvider hanging_socket3;
mmenkecc2298e2015-12-07 18:20:1811999 hanging_socket3.set_connect_data(never_finishing_connect);
12000 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket3);
[email protected]2d6728692011-03-12 01:39:5512001
danakj1fd259a02016-04-16 03:17:0912002 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:4112003 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:5012004 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5512005
tfarina42834112016-09-22 13:38:2012006 int rv = trans1.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112007 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12008 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512009
12010 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5212011 ASSERT_TRUE(response);
12012 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5512013 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12014
12015 std::string response_data;
robpercival214763f2016-07-01 23:27:0112016 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512017 EXPECT_EQ("hello world", response_data);
12018
[email protected]49639fa2011-12-20 23:22:4112019 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:5012020 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2012021 rv = trans2.Start(&request, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112022 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5512023
[email protected]49639fa2011-12-20 23:22:4112024 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:5012025 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2012026 rv = trans3.Start(&request, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112027 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5512028
robpercival214763f2016-07-01 23:27:0112029 EXPECT_THAT(callback2.WaitForResult(), IsOk());
12030 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512031
12032 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5212033 ASSERT_TRUE(response);
12034 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212035 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5512036 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212037 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0112038 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512039 EXPECT_EQ("hello!", response_data);
12040
12041 response = trans3.GetResponseInfo();
wezca1070932016-05-26 20:30:5212042 ASSERT_TRUE(response);
12043 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212044 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5512045 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212046 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0112047 ASSERT_THAT(ReadTransaction(&trans3, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512048 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:5512049}
12050
bncd16676a2016-07-20 16:23:0112051TEST_F(HttpNetworkTransactionTest, StallAlternativeServiceForNpnSpdy) {
Bence Békybcae37092018-06-12 04:18:5312052 session_deps_.host_resolver->set_synchronous_mode(true);
12053
[email protected]2d6728692011-03-12 01:39:5512054 HttpRequestInfo request;
12055 request.method = "GET";
bncb26024382016-06-29 02:39:4512056 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1012057 request.traffic_annotation =
12058 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d6728692011-03-12 01:39:5512059
12060 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212061 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312062 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212063 MockRead("\r\n"),
12064 MockRead("hello world"),
12065 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
12066 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5512067 };
12068
Ryan Sleevib8d7ea02018-05-07 20:01:0112069 StaticSocketDataProvider first_transaction(data_reads,
12070 base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712071 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:5512072
[email protected]8ddf8322012-02-23 18:08:0612073 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4912074 ssl.ssl_info.cert =
12075 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
12076 ASSERT_TRUE(ssl.ssl_info.cert);
[email protected]bb88e1d32013-05-03 23:11:0712077 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5512078
[email protected]d973e99a2012-02-17 21:02:3612079 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0112080 StaticSocketDataProvider hanging_alternate_protocol_socket;
[email protected]2d6728692011-03-12 01:39:5512081 hanging_alternate_protocol_socket.set_connect_data(
12082 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0712083 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5512084 &hanging_alternate_protocol_socket);
12085
bncb26024382016-06-29 02:39:4512086 // 2nd request is just a copy of the first one, over HTTP/1.1 again.
Ryan Sleevib8d7ea02018-05-07 20:01:0112087 StaticSocketDataProvider second_transaction(data_reads,
12088 base::span<MockWrite>());
mmenkecc2298e2015-12-07 18:20:1812089 session_deps_.socket_factory->AddSocketDataProvider(&second_transaction);
bncb26024382016-06-29 02:39:4512090 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5512091
[email protected]49639fa2011-12-20 23:22:4112092 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:5512093
danakj1fd259a02016-04-16 03:17:0912094 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5812095 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1912096 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5512097
tfarina42834112016-09-22 13:38:2012098 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112099 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12100 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512101
12102 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212103 ASSERT_TRUE(response);
12104 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5512105 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12106
12107 std::string response_data;
robpercival214763f2016-07-01 23:27:0112108 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512109 EXPECT_EQ("hello world", response_data);
12110
bnc87dcefc2017-05-25 12:47:5812111 trans =
Jeremy Roman0579ed62017-08-29 15:56:1912112 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5512113
tfarina42834112016-09-22 13:38:2012114 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112115 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12116 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512117
12118 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212119 ASSERT_TRUE(response);
12120 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5512121 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12122 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212123 EXPECT_FALSE(response->was_alpn_negotiated);
[email protected]2d6728692011-03-12 01:39:5512124
robpercival214763f2016-07-01 23:27:0112125 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512126 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:5512127}
12128
[email protected]631f1322010-04-30 17:59:1112129class CapturingProxyResolver : public ProxyResolver {
12130 public:
Chris Watkins7a41d3552017-12-01 02:13:2712131 CapturingProxyResolver() = default;
12132 ~CapturingProxyResolver() override = default;
[email protected]631f1322010-04-30 17:59:1112133
dchengb03027d2014-10-21 12:00:2012134 int GetProxyForURL(const GURL& url,
12135 ProxyInfo* results,
Bence Békycc5b88a2018-05-25 20:24:1712136 CompletionOnceCallback callback,
maksim.sisov7e157262016-10-20 11:19:5512137 std::unique_ptr<Request>* request,
tfarina42834112016-09-22 13:38:2012138 const NetLogWithSource& net_log) override {
[email protected]fae7669f2010-08-02 21:49:4012139 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
12140 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:4212141 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:1112142 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:4212143 return OK;
[email protected]631f1322010-04-30 17:59:1112144 }
12145
[email protected]24476402010-07-20 20:55:1712146 const std::vector<GURL>& resolved() const { return resolved_; }
12147
12148 private:
[email protected]631f1322010-04-30 17:59:1112149 std::vector<GURL> resolved_;
12150
12151 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
12152};
12153
sammce64b2362015-04-29 03:50:2312154class CapturingProxyResolverFactory : public ProxyResolverFactory {
12155 public:
12156 explicit CapturingProxyResolverFactory(CapturingProxyResolver* resolver)
12157 : ProxyResolverFactory(false), resolver_(resolver) {}
12158
Lily Houghton99597862018-03-07 16:40:4212159 int CreateProxyResolver(const scoped_refptr<PacFileData>& pac_script,
12160 std::unique_ptr<ProxyResolver>* resolver,
Bence Békycc5b88a2018-05-25 20:24:1712161 CompletionOnceCallback callback,
Lily Houghton99597862018-03-07 16:40:4212162 std::unique_ptr<Request>* request) override {
Jeremy Roman0579ed62017-08-29 15:56:1912163 *resolver = std::make_unique<ForwardingProxyResolver>(resolver_);
sammce64b2362015-04-29 03:50:2312164 return OK;
12165 }
12166
12167 private:
12168 ProxyResolver* resolver_;
12169};
12170
bnc2e884782016-08-11 19:45:1912171// Test that proxy is resolved using the origin url,
12172// regardless of the alternative server.
12173TEST_F(HttpNetworkTransactionTest, UseOriginNotAlternativeForProxy) {
12174 // Configure proxy to bypass www.example.org, which is the origin URL.
12175 ProxyConfig proxy_config;
12176 proxy_config.proxy_rules().ParseFromString("myproxy:70");
12177 proxy_config.proxy_rules().bypass_rules.AddRuleFromString("www.example.org");
Ramin Halavatica8d5252018-03-12 05:33:4912178 auto proxy_config_service = std::make_unique<ProxyConfigServiceFixed>(
12179 ProxyConfigWithAnnotation(proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS));
bnc2e884782016-08-11 19:45:1912180
12181 CapturingProxyResolver capturing_proxy_resolver;
Jeremy Roman0579ed62017-08-29 15:56:1912182 auto proxy_resolver_factory = std::make_unique<CapturingProxyResolverFactory>(
bnc2e884782016-08-11 19:45:1912183 &capturing_proxy_resolver);
12184
12185 TestNetLog net_log;
12186
Bence Béky53a5aef2018-03-29 21:54:1212187 session_deps_.proxy_resolution_service =
12188 std::make_unique<ProxyResolutionService>(
12189 std::move(proxy_config_service), std::move(proxy_resolver_factory),
12190 &net_log);
bnc2e884782016-08-11 19:45:1912191
12192 session_deps_.net_log = &net_log;
12193
12194 // Configure alternative service with a hostname that is not bypassed by the
12195 // proxy.
12196 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12197 HttpServerProperties* http_server_properties =
12198 session->http_server_properties();
12199 url::SchemeHostPort server("https", "www.example.org", 443);
12200 HostPortPair alternative("www.example.com", 443);
bnc3472afd2016-11-17 15:27:2112201 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc2e884782016-08-11 19:45:1912202 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112203 http_server_properties->SetHttp2AlternativeService(
12204 server, alternative_service, expiration);
bnc2e884782016-08-11 19:45:1912205
12206 // Non-alternative job should hang.
12207 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0112208 StaticSocketDataProvider hanging_alternate_protocol_socket;
bnc2e884782016-08-11 19:45:1912209 hanging_alternate_protocol_socket.set_connect_data(never_finishing_connect);
12210 session_deps_.socket_factory->AddSocketDataProvider(
12211 &hanging_alternate_protocol_socket);
12212
bnc032658ba2016-09-26 18:17:1512213 AddSSLSocketData();
bnc2e884782016-08-11 19:45:1912214
12215 HttpRequestInfo request;
12216 request.method = "GET";
12217 request.url = GURL("https://www.example.org/");
12218 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1012219 request.traffic_annotation =
12220 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc2e884782016-08-11 19:45:1912221
Ryan Hamilton0239aac2018-05-19 00:03:1312222 spdy::SpdySerializedFrame req(
bnc2e884782016-08-11 19:45:1912223 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
12224
12225 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
12226
Ryan Hamilton0239aac2018-05-19 00:03:1312227 spdy::SpdySerializedFrame resp(
12228 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
12229 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
bnc2e884782016-08-11 19:45:1912230 MockRead spdy_reads[] = {
12231 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
12232 };
12233
Ryan Sleevib8d7ea02018-05-07 20:01:0112234 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
bnc2e884782016-08-11 19:45:1912235 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
12236
12237 TestCompletionCallback callback;
12238
12239 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
12240
tfarina42834112016-09-22 13:38:2012241 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc2e884782016-08-11 19:45:1912242 EXPECT_THAT(callback.GetResult(rv), IsOk());
12243
12244 const HttpResponseInfo* response = trans.GetResponseInfo();
12245 ASSERT_TRUE(response);
12246 ASSERT_TRUE(response->headers);
12247 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
12248 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212249 EXPECT_TRUE(response->was_alpn_negotiated);
bnc2e884782016-08-11 19:45:1912250
12251 std::string response_data;
12252 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
12253 EXPECT_EQ("hello!", response_data);
12254
12255 // Origin host bypasses proxy, no resolution should have happened.
12256 ASSERT_TRUE(capturing_proxy_resolver.resolved().empty());
12257}
12258
bncd16676a2016-07-20 16:23:0112259TEST_F(HttpNetworkTransactionTest, UseAlternativeServiceForTunneledNpnSpdy) {
[email protected]631f1322010-04-30 17:59:1112260 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:4212261 proxy_config.set_auto_detect(true);
12262 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:1112263
sammc5dd160c2015-04-02 02:43:1312264 CapturingProxyResolver capturing_proxy_resolver;
Ramin Halavatica8d5252018-03-12 05:33:4912265 session_deps_.proxy_resolution_service =
12266 std::make_unique<ProxyResolutionService>(
12267 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
12268 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
12269 std::make_unique<CapturingProxyResolverFactory>(
12270 &capturing_proxy_resolver),
12271 nullptr);
vishal.b62985ca92015-04-17 08:45:5112272 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0712273 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:1112274
12275 HttpRequestInfo request;
12276 request.method = "GET";
bncb26024382016-06-29 02:39:4512277 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1012278 request.traffic_annotation =
12279 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]631f1322010-04-30 17:59:1112280
12281 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212282 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312283 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212284 MockRead("\r\n"),
12285 MockRead("hello world"),
12286 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
12287 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:1112288 };
12289
Ryan Sleevib8d7ea02018-05-07 20:01:0112290 StaticSocketDataProvider first_transaction(data_reads,
12291 base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712292 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4512293 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612294 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512295 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]631f1322010-04-30 17:59:1112296
bnc032658ba2016-09-26 18:17:1512297 AddSSLSocketData();
[email protected]631f1322010-04-30 17:59:1112298
Ryan Hamilton0239aac2018-05-19 00:03:1312299 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4512300 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
[email protected]631f1322010-04-30 17:59:1112301 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1312302 MockWrite(ASYNC, 0,
bnc8bef8da22016-05-30 01:28:2512303 "CONNECT www.example.org:443 HTTP/1.1\r\n"
12304 "Host: www.example.org:443\r\n"
rch8e6c6c42015-05-01 14:05:1312305 "Proxy-Connection: keep-alive\r\n\r\n"),
bncdf80d44fd2016-07-15 20:27:4112306 CreateMockWrite(req, 2),
[email protected]631f1322010-04-30 17:59:1112307 };
12308
[email protected]d911f1b2010-05-05 22:39:4212309 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
12310
Ryan Hamilton0239aac2018-05-19 00:03:1312311 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
12312 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]631f1322010-04-30 17:59:1112313 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4112314 MockRead(ASYNC, 1, kCONNECTResponse), CreateMockRead(resp, 3),
12315 CreateMockRead(data, 4), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5),
[email protected]631f1322010-04-30 17:59:1112316 };
12317
Ryan Sleevib8d7ea02018-05-07 20:01:0112318 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0712319 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:1112320
[email protected]d973e99a2012-02-17 21:02:3612321 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0112322 StaticSocketDataProvider hanging_non_alternate_protocol_socket;
[email protected]2d6728692011-03-12 01:39:5512323 hanging_non_alternate_protocol_socket.set_connect_data(
12324 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0712325 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5512326 &hanging_non_alternate_protocol_socket);
12327
[email protected]49639fa2011-12-20 23:22:4112328 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:1112329
danakj1fd259a02016-04-16 03:17:0912330 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5812331 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1912332 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1112333
tfarina42834112016-09-22 13:38:2012334 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea2dcd3bf2016-08-16 21:49:4112335 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12336 EXPECT_THAT(callback.WaitForResult(), IsOk());
12337
12338 const HttpResponseInfo* response = trans->GetResponseInfo();
12339 ASSERT_TRUE(response);
12340 ASSERT_TRUE(response->headers);
12341 EXPECT_EQ("HTTP/0.9 200 OK", response->headers->GetStatusLine());
12342 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212343 EXPECT_TRUE(response->was_alpn_negotiated);
mmenkea2dcd3bf2016-08-16 21:49:4112344
12345 std::string response_data;
12346 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
12347 EXPECT_EQ("hello world", response_data);
[email protected]631f1322010-04-30 17:59:1112348
bnc87dcefc2017-05-25 12:47:5812349 trans =
Jeremy Roman0579ed62017-08-29 15:56:1912350 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1112351
tfarina42834112016-09-22 13:38:2012352 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112353 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12354 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]631f1322010-04-30 17:59:1112355
mmenkea2dcd3bf2016-08-16 21:49:4112356 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212357 ASSERT_TRUE(response);
12358 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212359 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5312360 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212361 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]631f1322010-04-30 17:59:1112362
robpercival214763f2016-07-01 23:27:0112363 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]631f1322010-04-30 17:59:1112364 EXPECT_EQ("hello!", response_data);
bncb26024382016-06-29 02:39:4512365 ASSERT_EQ(2u, capturing_proxy_resolver.resolved().size());
12366 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1312367 capturing_proxy_resolver.resolved()[0].spec());
bncce36dca22015-04-21 22:11:2312368 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1312369 capturing_proxy_resolver.resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:1112370
[email protected]029c83b62013-01-24 05:28:2012371 LoadTimingInfo load_timing_info;
12372 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
12373 TestLoadTimingNotReusedWithPac(load_timing_info,
12374 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:1112375}
[email protected]631f1322010-04-30 17:59:1112376
bncd16676a2016-07-20 16:23:0112377TEST_F(HttpNetworkTransactionTest,
bnc1c196c6e2016-05-28 13:51:4812378 UseAlternativeServiceForNpnSpdyWithExistingSpdySession) {
[email protected]2ff8b312010-04-26 22:20:5412379 HttpRequestInfo request;
12380 request.method = "GET";
bncb26024382016-06-29 02:39:4512381 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1012382 request.traffic_annotation =
12383 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2ff8b312010-04-26 22:20:5412384
12385 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212386 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312387 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212388 MockRead("\r\n"),
12389 MockRead("hello world"),
12390 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:5412391 };
12392
Ryan Sleevib8d7ea02018-05-07 20:01:0112393 StaticSocketDataProvider first_transaction(data_reads,
12394 base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712395 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4512396 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612397 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512398 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5412399
bnc032658ba2016-09-26 18:17:1512400 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5412401
Ryan Hamilton0239aac2018-05-19 00:03:1312402 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4512403 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4112404 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5412405
Ryan Hamilton0239aac2018-05-19 00:03:1312406 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
12407 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5412408 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4112409 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5412410 };
12411
Ryan Sleevib8d7ea02018-05-07 20:01:0112412 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0712413 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5412414
[email protected]83039bb2011-12-09 18:43:5512415 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5412416
danakj1fd259a02016-04-16 03:17:0912417 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:5412418
bnc87dcefc2017-05-25 12:47:5812419 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1912420 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5412421
tfarina42834112016-09-22 13:38:2012422 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112423 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12424 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412425
12426 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212427 ASSERT_TRUE(response);
12428 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5412429 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12430
12431 std::string response_data;
robpercival214763f2016-07-01 23:27:0112432 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412433 EXPECT_EQ("hello world", response_data);
12434
12435 // Set up an initial SpdySession in the pool to reuse.
bnc8bef8da22016-05-30 01:28:2512436 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4012437 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
Paul Jensena457017a2018-01-19 23:52:0412438 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]795cbf82013-07-22 09:37:2712439 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:5212440 CreateSpdySession(session.get(), key, NetLogWithSource());
[email protected]02b0c342010-09-25 21:09:3812441
bnc87dcefc2017-05-25 12:47:5812442 trans =
Jeremy Roman0579ed62017-08-29 15:56:1912443 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5412444
tfarina42834112016-09-22 13:38:2012445 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112446 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12447 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412448
12449 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212450 ASSERT_TRUE(response);
12451 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212452 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5312453 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212454 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5412455
robpercival214763f2016-07-01 23:27:0112456 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412457 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:4212458}
12459
[email protected]044de0642010-06-17 10:42:1512460// GenerateAuthToken is a mighty big test.
12461// It tests all permutation of GenerateAuthToken behavior:
12462// - Synchronous and Asynchronous completion.
12463// - OK or error on completion.
12464// - Direct connection, non-authenticating proxy, and authenticating proxy.
12465// - HTTP or HTTPS backend (to include proxy tunneling).
12466// - Non-authenticating and authenticating backend.
12467//
[email protected]fe3b7dc2012-02-03 19:52:0912468// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:1512469// problems generating an auth token for an authenticating proxy, we don't
12470// need to test all permutations of the backend server).
12471//
12472// The test proceeds by going over each of the configuration cases, and
12473// potentially running up to three rounds in each of the tests. The TestConfig
12474// specifies both the configuration for the test as well as the expectations
12475// for the results.
bncd16676a2016-07-20 16:23:0112476TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:5012477 static const char kServer[] = "http://www.example.com";
12478 static const char kSecureServer[] = "https://www.example.com";
12479 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:1512480
12481 enum AuthTiming {
12482 AUTH_NONE,
12483 AUTH_SYNC,
12484 AUTH_ASYNC,
12485 };
12486
12487 const MockWrite kGet(
12488 "GET / HTTP/1.1\r\n"
12489 "Host: www.example.com\r\n"
12490 "Connection: keep-alive\r\n\r\n");
12491 const MockWrite kGetProxy(
12492 "GET http://www.example.com/ HTTP/1.1\r\n"
12493 "Host: www.example.com\r\n"
12494 "Proxy-Connection: keep-alive\r\n\r\n");
12495 const MockWrite kGetAuth(
12496 "GET / HTTP/1.1\r\n"
12497 "Host: www.example.com\r\n"
12498 "Connection: keep-alive\r\n"
12499 "Authorization: auth_token\r\n\r\n");
12500 const MockWrite kGetProxyAuth(
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 "Proxy-Authorization: auth_token\r\n\r\n");
12505 const MockWrite kGetAuthThroughProxy(
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 "Authorization: auth_token\r\n\r\n");
12510 const MockWrite kGetAuthWithProxyAuth(
12511 "GET http://www.example.com/ HTTP/1.1\r\n"
12512 "Host: www.example.com\r\n"
12513 "Proxy-Connection: keep-alive\r\n"
12514 "Proxy-Authorization: auth_token\r\n"
12515 "Authorization: auth_token\r\n\r\n");
12516 const MockWrite kConnect(
12517 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1712518 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1512519 "Proxy-Connection: keep-alive\r\n\r\n");
12520 const MockWrite kConnectProxyAuth(
12521 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1712522 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1512523 "Proxy-Connection: keep-alive\r\n"
12524 "Proxy-Authorization: auth_token\r\n\r\n");
12525
12526 const MockRead kSuccess(
12527 "HTTP/1.1 200 OK\r\n"
12528 "Content-Type: text/html; charset=iso-8859-1\r\n"
12529 "Content-Length: 3\r\n\r\n"
12530 "Yes");
12531 const MockRead kFailure(
12532 "Should not be called.");
12533 const MockRead kServerChallenge(
12534 "HTTP/1.1 401 Unauthorized\r\n"
12535 "WWW-Authenticate: Mock realm=server\r\n"
12536 "Content-Type: text/html; charset=iso-8859-1\r\n"
12537 "Content-Length: 14\r\n\r\n"
12538 "Unauthorized\r\n");
12539 const MockRead kProxyChallenge(
12540 "HTTP/1.1 407 Unauthorized\r\n"
12541 "Proxy-Authenticate: Mock realm=proxy\r\n"
12542 "Proxy-Connection: close\r\n"
12543 "Content-Type: text/html; charset=iso-8859-1\r\n"
12544 "Content-Length: 14\r\n\r\n"
12545 "Unauthorized\r\n");
12546 const MockRead kProxyConnected(
12547 "HTTP/1.1 200 Connection Established\r\n\r\n");
12548
12549 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
12550 // no constructors, but the C++ compiler on Windows warns about
12551 // unspecified data in compound literals. So, moved to using constructors,
12552 // and TestRound's created with the default constructor should not be used.
12553 struct TestRound {
12554 TestRound()
12555 : expected_rv(ERR_UNEXPECTED),
12556 extra_write(NULL),
12557 extra_read(NULL) {
12558 }
12559 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
12560 int expected_rv_arg)
12561 : write(write_arg),
12562 read(read_arg),
12563 expected_rv(expected_rv_arg),
12564 extra_write(NULL),
12565 extra_read(NULL) {
12566 }
12567 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
12568 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:0112569 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:1512570 : write(write_arg),
12571 read(read_arg),
12572 expected_rv(expected_rv_arg),
12573 extra_write(extra_write_arg),
12574 extra_read(extra_read_arg) {
12575 }
12576 MockWrite write;
12577 MockRead read;
12578 int expected_rv;
12579 const MockWrite* extra_write;
12580 const MockRead* extra_read;
12581 };
12582
12583 static const int kNoSSL = 500;
12584
12585 struct TestConfig {
asanka463ca4262016-11-16 02:34:3112586 int line_number;
thestig9d3bb0c2015-01-24 00:49:5112587 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:1512588 AuthTiming proxy_auth_timing;
asanka463ca4262016-11-16 02:34:3112589 int first_generate_proxy_token_rv;
thestig9d3bb0c2015-01-24 00:49:5112590 const char* const server_url;
[email protected]044de0642010-06-17 10:42:1512591 AuthTiming server_auth_timing;
asanka463ca4262016-11-16 02:34:3112592 int first_generate_server_token_rv;
[email protected]044de0642010-06-17 10:42:1512593 int num_auth_rounds;
12594 int first_ssl_round;
asankae2257db2016-10-11 22:03:1612595 TestRound rounds[4];
[email protected]044de0642010-06-17 10:42:1512596 } test_configs[] = {
asankac93076192016-10-03 15:46:0212597 // Non-authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3112598 {__LINE__,
12599 nullptr,
asankac93076192016-10-03 15:46:0212600 AUTH_NONE,
12601 OK,
12602 kServer,
12603 AUTH_NONE,
12604 OK,
12605 1,
12606 kNoSSL,
12607 {TestRound(kGet, kSuccess, OK)}},
12608 // Authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3112609 {__LINE__,
12610 nullptr,
asankac93076192016-10-03 15:46:0212611 AUTH_NONE,
12612 OK,
12613 kServer,
12614 AUTH_SYNC,
12615 OK,
12616 2,
12617 kNoSSL,
12618 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512619 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112620 {__LINE__,
12621 nullptr,
asankac93076192016-10-03 15:46:0212622 AUTH_NONE,
12623 OK,
12624 kServer,
12625 AUTH_SYNC,
12626 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1612627 3,
12628 kNoSSL,
12629 {TestRound(kGet, kServerChallenge, OK),
12630 TestRound(kGet, kServerChallenge, OK),
12631 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112632 {__LINE__,
12633 nullptr,
asankae2257db2016-10-11 22:03:1612634 AUTH_NONE,
12635 OK,
12636 kServer,
12637 AUTH_SYNC,
12638 ERR_UNSUPPORTED_AUTH_SCHEME,
12639 2,
12640 kNoSSL,
12641 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112642 {__LINE__,
12643 nullptr,
asankae2257db2016-10-11 22:03:1612644 AUTH_NONE,
12645 OK,
12646 kServer,
12647 AUTH_SYNC,
12648 ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS,
12649 2,
12650 kNoSSL,
12651 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112652 {__LINE__,
12653 kProxy,
asankae2257db2016-10-11 22:03:1612654 AUTH_SYNC,
12655 ERR_FAILED,
12656 kServer,
12657 AUTH_NONE,
12658 OK,
12659 2,
12660 kNoSSL,
12661 {TestRound(kGetProxy, kProxyChallenge, OK),
12662 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112663 {__LINE__,
12664 kProxy,
asankae2257db2016-10-11 22:03:1612665 AUTH_ASYNC,
12666 ERR_FAILED,
12667 kServer,
12668 AUTH_NONE,
12669 OK,
12670 2,
12671 kNoSSL,
12672 {TestRound(kGetProxy, kProxyChallenge, OK),
12673 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112674 {__LINE__,
12675 nullptr,
asankae2257db2016-10-11 22:03:1612676 AUTH_NONE,
12677 OK,
12678 kServer,
12679 AUTH_SYNC,
12680 ERR_FAILED,
asankac93076192016-10-03 15:46:0212681 2,
12682 kNoSSL,
12683 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612684 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112685 {__LINE__,
12686 nullptr,
asankae2257db2016-10-11 22:03:1612687 AUTH_NONE,
12688 OK,
12689 kServer,
12690 AUTH_ASYNC,
12691 ERR_FAILED,
12692 2,
12693 kNoSSL,
12694 {TestRound(kGet, kServerChallenge, OK),
12695 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112696 {__LINE__,
12697 nullptr,
asankac93076192016-10-03 15:46:0212698 AUTH_NONE,
12699 OK,
12700 kServer,
12701 AUTH_ASYNC,
12702 OK,
12703 2,
12704 kNoSSL,
12705 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512706 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112707 {__LINE__,
12708 nullptr,
asankac93076192016-10-03 15:46:0212709 AUTH_NONE,
12710 OK,
12711 kServer,
12712 AUTH_ASYNC,
12713 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1612714 3,
asankac93076192016-10-03 15:46:0212715 kNoSSL,
12716 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612717 // The second round uses a HttpAuthHandlerMock that always succeeds.
12718 TestRound(kGet, kServerChallenge, OK),
12719 TestRound(kGetAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212720 // Non-authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3112721 {__LINE__,
12722 kProxy,
asankac93076192016-10-03 15:46:0212723 AUTH_NONE,
12724 OK,
12725 kServer,
12726 AUTH_NONE,
12727 OK,
12728 1,
12729 kNoSSL,
12730 {TestRound(kGetProxy, kSuccess, OK)}},
12731 // Authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3112732 {__LINE__,
12733 kProxy,
asankac93076192016-10-03 15:46:0212734 AUTH_NONE,
12735 OK,
12736 kServer,
12737 AUTH_SYNC,
12738 OK,
12739 2,
12740 kNoSSL,
12741 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512742 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112743 {__LINE__,
12744 kProxy,
asankac93076192016-10-03 15:46:0212745 AUTH_NONE,
12746 OK,
12747 kServer,
12748 AUTH_SYNC,
12749 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1612750 3,
asankac93076192016-10-03 15:46:0212751 kNoSSL,
12752 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612753 TestRound(kGetProxy, kServerChallenge, OK),
12754 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112755 {__LINE__,
12756 kProxy,
asankac93076192016-10-03 15:46:0212757 AUTH_NONE,
12758 OK,
12759 kServer,
12760 AUTH_ASYNC,
12761 OK,
12762 2,
12763 kNoSSL,
12764 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512765 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112766 {__LINE__,
12767 kProxy,
asankac93076192016-10-03 15:46:0212768 AUTH_NONE,
12769 OK,
12770 kServer,
12771 AUTH_ASYNC,
12772 ERR_INVALID_AUTH_CREDENTIALS,
12773 2,
12774 kNoSSL,
12775 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612776 TestRound(kGetProxy, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212777 // Non-authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112778 {__LINE__,
12779 kProxy,
asankac93076192016-10-03 15:46:0212780 AUTH_SYNC,
12781 OK,
12782 kServer,
12783 AUTH_NONE,
12784 OK,
12785 2,
12786 kNoSSL,
12787 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512788 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112789 {__LINE__,
12790 kProxy,
asankac93076192016-10-03 15:46:0212791 AUTH_SYNC,
12792 ERR_INVALID_AUTH_CREDENTIALS,
12793 kServer,
12794 AUTH_NONE,
12795 OK,
12796 2,
12797 kNoSSL,
12798 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612799 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112800 {__LINE__,
12801 kProxy,
asankac93076192016-10-03 15:46:0212802 AUTH_ASYNC,
12803 OK,
12804 kServer,
12805 AUTH_NONE,
12806 OK,
12807 2,
12808 kNoSSL,
12809 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512810 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112811 {__LINE__,
12812 kProxy,
asankac93076192016-10-03 15:46:0212813 AUTH_ASYNC,
12814 ERR_INVALID_AUTH_CREDENTIALS,
12815 kServer,
12816 AUTH_NONE,
12817 OK,
12818 2,
12819 kNoSSL,
12820 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612821 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112822 {__LINE__,
12823 kProxy,
12824 AUTH_ASYNC,
12825 ERR_INVALID_AUTH_CREDENTIALS,
12826 kServer,
12827 AUTH_NONE,
12828 OK,
12829 3,
12830 kNoSSL,
12831 {TestRound(kGetProxy, kProxyChallenge, OK),
12832 TestRound(kGetProxy, kProxyChallenge, OK),
12833 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212834 // Authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112835 {__LINE__,
12836 kProxy,
asankac93076192016-10-03 15:46:0212837 AUTH_SYNC,
12838 OK,
12839 kServer,
12840 AUTH_SYNC,
12841 OK,
12842 3,
12843 kNoSSL,
12844 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512845 TestRound(kGetProxyAuth, kServerChallenge, OK),
12846 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112847 {__LINE__,
12848 kProxy,
asankac93076192016-10-03 15:46:0212849 AUTH_SYNC,
12850 OK,
12851 kServer,
12852 AUTH_SYNC,
12853 ERR_INVALID_AUTH_CREDENTIALS,
12854 3,
12855 kNoSSL,
12856 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512857 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612858 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112859 {__LINE__,
12860 kProxy,
asankac93076192016-10-03 15:46:0212861 AUTH_ASYNC,
12862 OK,
12863 kServer,
12864 AUTH_SYNC,
12865 OK,
12866 3,
12867 kNoSSL,
12868 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512869 TestRound(kGetProxyAuth, kServerChallenge, OK),
12870 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112871 {__LINE__,
12872 kProxy,
asankac93076192016-10-03 15:46:0212873 AUTH_ASYNC,
12874 OK,
12875 kServer,
12876 AUTH_SYNC,
12877 ERR_INVALID_AUTH_CREDENTIALS,
12878 3,
12879 kNoSSL,
12880 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512881 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612882 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112883 {__LINE__,
12884 kProxy,
asankac93076192016-10-03 15:46:0212885 AUTH_SYNC,
12886 OK,
12887 kServer,
12888 AUTH_ASYNC,
12889 OK,
12890 3,
12891 kNoSSL,
12892 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512893 TestRound(kGetProxyAuth, kServerChallenge, OK),
12894 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112895 {__LINE__,
12896 kProxy,
12897 AUTH_SYNC,
12898 ERR_INVALID_AUTH_CREDENTIALS,
12899 kServer,
12900 AUTH_ASYNC,
12901 OK,
12902 4,
12903 kNoSSL,
12904 {TestRound(kGetProxy, kProxyChallenge, OK),
12905 TestRound(kGetProxy, kProxyChallenge, OK),
12906 TestRound(kGetProxyAuth, kServerChallenge, OK),
12907 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
12908 {__LINE__,
12909 kProxy,
asankac93076192016-10-03 15:46:0212910 AUTH_SYNC,
12911 OK,
12912 kServer,
12913 AUTH_ASYNC,
12914 ERR_INVALID_AUTH_CREDENTIALS,
12915 3,
12916 kNoSSL,
12917 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512918 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612919 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112920 {__LINE__,
12921 kProxy,
asankac93076192016-10-03 15:46:0212922 AUTH_ASYNC,
12923 OK,
12924 kServer,
12925 AUTH_ASYNC,
12926 OK,
12927 3,
12928 kNoSSL,
12929 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512930 TestRound(kGetProxyAuth, kServerChallenge, OK),
12931 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112932 {__LINE__,
12933 kProxy,
asankac93076192016-10-03 15:46:0212934 AUTH_ASYNC,
12935 OK,
12936 kServer,
12937 AUTH_ASYNC,
12938 ERR_INVALID_AUTH_CREDENTIALS,
12939 3,
12940 kNoSSL,
12941 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512942 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612943 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112944 {__LINE__,
12945 kProxy,
12946 AUTH_ASYNC,
12947 ERR_INVALID_AUTH_CREDENTIALS,
12948 kServer,
12949 AUTH_ASYNC,
12950 ERR_INVALID_AUTH_CREDENTIALS,
12951 4,
12952 kNoSSL,
12953 {TestRound(kGetProxy, kProxyChallenge, OK),
12954 TestRound(kGetProxy, kProxyChallenge, OK),
12955 TestRound(kGetProxyAuth, kServerChallenge, OK),
12956 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212957 // Non-authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3112958 {__LINE__,
12959 nullptr,
asankac93076192016-10-03 15:46:0212960 AUTH_NONE,
12961 OK,
12962 kSecureServer,
12963 AUTH_NONE,
12964 OK,
12965 1,
12966 0,
12967 {TestRound(kGet, kSuccess, OK)}},
12968 // Authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3112969 {__LINE__,
12970 nullptr,
asankac93076192016-10-03 15:46:0212971 AUTH_NONE,
12972 OK,
12973 kSecureServer,
12974 AUTH_SYNC,
12975 OK,
12976 2,
12977 0,
12978 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512979 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112980 {__LINE__,
12981 nullptr,
asankac93076192016-10-03 15:46:0212982 AUTH_NONE,
12983 OK,
12984 kSecureServer,
12985 AUTH_SYNC,
12986 ERR_INVALID_AUTH_CREDENTIALS,
12987 2,
12988 0,
asankae2257db2016-10-11 22:03:1612989 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112990 {__LINE__,
12991 nullptr,
asankac93076192016-10-03 15:46:0212992 AUTH_NONE,
12993 OK,
12994 kSecureServer,
12995 AUTH_ASYNC,
12996 OK,
12997 2,
12998 0,
12999 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513000 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113001 {__LINE__,
13002 nullptr,
asankac93076192016-10-03 15:46:0213003 AUTH_NONE,
13004 OK,
13005 kSecureServer,
13006 AUTH_ASYNC,
13007 ERR_INVALID_AUTH_CREDENTIALS,
13008 2,
13009 0,
asankae2257db2016-10-11 22:03:1613010 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213011 // Non-authenticating HTTPS server with a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3113012 {__LINE__,
13013 kProxy,
asankac93076192016-10-03 15:46:0213014 AUTH_NONE,
13015 OK,
13016 kSecureServer,
13017 AUTH_NONE,
13018 OK,
13019 1,
13020 0,
13021 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
13022 // Authenticating HTTPS server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3113023 {__LINE__,
13024 kProxy,
asankac93076192016-10-03 15:46:0213025 AUTH_NONE,
13026 OK,
13027 kSecureServer,
13028 AUTH_SYNC,
13029 OK,
13030 2,
13031 0,
13032 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513033 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113034 {__LINE__,
13035 kProxy,
asankac93076192016-10-03 15:46:0213036 AUTH_NONE,
13037 OK,
13038 kSecureServer,
13039 AUTH_SYNC,
13040 ERR_INVALID_AUTH_CREDENTIALS,
13041 2,
13042 0,
13043 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1613044 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113045 {__LINE__,
13046 kProxy,
asankac93076192016-10-03 15:46:0213047 AUTH_NONE,
13048 OK,
13049 kSecureServer,
13050 AUTH_ASYNC,
13051 OK,
13052 2,
13053 0,
13054 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513055 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113056 {__LINE__,
13057 kProxy,
asankac93076192016-10-03 15:46:0213058 AUTH_NONE,
13059 OK,
13060 kSecureServer,
13061 AUTH_ASYNC,
13062 ERR_INVALID_AUTH_CREDENTIALS,
13063 2,
13064 0,
13065 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1613066 TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213067 // Non-Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3113068 {__LINE__,
13069 kProxy,
asankac93076192016-10-03 15:46:0213070 AUTH_SYNC,
13071 OK,
13072 kSecureServer,
13073 AUTH_NONE,
13074 OK,
13075 2,
13076 1,
13077 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513078 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113079 {__LINE__,
13080 kProxy,
asankac93076192016-10-03 15:46:0213081 AUTH_SYNC,
13082 ERR_INVALID_AUTH_CREDENTIALS,
13083 kSecureServer,
13084 AUTH_NONE,
13085 OK,
13086 2,
13087 kNoSSL,
13088 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1613089 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113090 {__LINE__,
13091 kProxy,
asankae2257db2016-10-11 22:03:1613092 AUTH_SYNC,
13093 ERR_UNSUPPORTED_AUTH_SCHEME,
13094 kSecureServer,
13095 AUTH_NONE,
13096 OK,
13097 2,
13098 kNoSSL,
13099 {TestRound(kConnect, kProxyChallenge, OK),
13100 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113101 {__LINE__,
13102 kProxy,
asankae2257db2016-10-11 22:03:1613103 AUTH_SYNC,
13104 ERR_UNEXPECTED,
13105 kSecureServer,
13106 AUTH_NONE,
13107 OK,
13108 2,
13109 kNoSSL,
13110 {TestRound(kConnect, kProxyChallenge, OK),
13111 TestRound(kConnect, kProxyConnected, ERR_UNEXPECTED)}},
asanka463ca4262016-11-16 02:34:3113112 {__LINE__,
13113 kProxy,
asankac93076192016-10-03 15:46:0213114 AUTH_ASYNC,
13115 OK,
13116 kSecureServer,
13117 AUTH_NONE,
13118 OK,
13119 2,
13120 1,
13121 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513122 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113123 {__LINE__,
13124 kProxy,
asankac93076192016-10-03 15:46:0213125 AUTH_ASYNC,
13126 ERR_INVALID_AUTH_CREDENTIALS,
13127 kSecureServer,
13128 AUTH_NONE,
13129 OK,
13130 2,
13131 kNoSSL,
13132 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1613133 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asankac93076192016-10-03 15:46:0213134 // Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3113135 {__LINE__,
13136 kProxy,
asankac93076192016-10-03 15:46:0213137 AUTH_SYNC,
13138 OK,
13139 kSecureServer,
13140 AUTH_SYNC,
13141 OK,
13142 3,
13143 1,
13144 {TestRound(kConnect, kProxyChallenge, OK),
13145 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13146 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513147 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113148 {__LINE__,
13149 kProxy,
asankac93076192016-10-03 15:46:0213150 AUTH_SYNC,
13151 OK,
13152 kSecureServer,
13153 AUTH_SYNC,
13154 ERR_INVALID_AUTH_CREDENTIALS,
13155 3,
13156 1,
13157 {TestRound(kConnect, kProxyChallenge, OK),
13158 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13159 &kServerChallenge),
asankae2257db2016-10-11 22:03:1613160 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113161 {__LINE__,
13162 kProxy,
asankac93076192016-10-03 15:46:0213163 AUTH_ASYNC,
13164 OK,
13165 kSecureServer,
13166 AUTH_SYNC,
13167 OK,
13168 3,
13169 1,
13170 {TestRound(kConnect, kProxyChallenge, OK),
13171 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13172 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513173 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113174 {__LINE__,
13175 kProxy,
asankac93076192016-10-03 15:46:0213176 AUTH_ASYNC,
13177 OK,
13178 kSecureServer,
13179 AUTH_SYNC,
13180 ERR_INVALID_AUTH_CREDENTIALS,
13181 3,
13182 1,
13183 {TestRound(kConnect, kProxyChallenge, OK),
13184 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13185 &kServerChallenge),
asankae2257db2016-10-11 22:03:1613186 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113187 {__LINE__,
13188 kProxy,
asankac93076192016-10-03 15:46:0213189 AUTH_SYNC,
13190 OK,
13191 kSecureServer,
13192 AUTH_ASYNC,
13193 OK,
13194 3,
13195 1,
13196 {TestRound(kConnect, kProxyChallenge, OK),
13197 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13198 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513199 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113200 {__LINE__,
13201 kProxy,
asankac93076192016-10-03 15:46:0213202 AUTH_SYNC,
13203 OK,
13204 kSecureServer,
13205 AUTH_ASYNC,
13206 ERR_INVALID_AUTH_CREDENTIALS,
13207 3,
13208 1,
13209 {TestRound(kConnect, kProxyChallenge, OK),
13210 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13211 &kServerChallenge),
asankae2257db2016-10-11 22:03:1613212 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113213 {__LINE__,
13214 kProxy,
asankac93076192016-10-03 15:46:0213215 AUTH_ASYNC,
13216 OK,
13217 kSecureServer,
13218 AUTH_ASYNC,
13219 OK,
13220 3,
13221 1,
13222 {TestRound(kConnect, kProxyChallenge, OK),
13223 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13224 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513225 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113226 {__LINE__,
13227 kProxy,
asankac93076192016-10-03 15:46:0213228 AUTH_ASYNC,
13229 OK,
13230 kSecureServer,
13231 AUTH_ASYNC,
13232 ERR_INVALID_AUTH_CREDENTIALS,
13233 3,
13234 1,
13235 {TestRound(kConnect, kProxyChallenge, OK),
13236 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13237 &kServerChallenge),
asankae2257db2016-10-11 22:03:1613238 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113239 {__LINE__,
13240 kProxy,
13241 AUTH_ASYNC,
13242 ERR_INVALID_AUTH_CREDENTIALS,
13243 kSecureServer,
13244 AUTH_ASYNC,
13245 ERR_INVALID_AUTH_CREDENTIALS,
13246 4,
13247 2,
13248 {TestRound(kConnect, kProxyChallenge, OK),
13249 TestRound(kConnect, kProxyChallenge, OK),
13250 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13251 &kServerChallenge),
13252 TestRound(kGet, kSuccess, OK)}},
[email protected]044de0642010-06-17 10:42:1513253 };
13254
asanka463ca4262016-11-16 02:34:3113255 for (const auto& test_config : test_configs) {
13256 SCOPED_TRACE(::testing::Message() << "Test config at "
13257 << test_config.line_number);
[email protected]2d01c262011-08-11 23:07:0813258 HttpAuthHandlerMock::Factory* auth_factory(
13259 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0713260 session_deps_.http_auth_handler_factory.reset(auth_factory);
asanka5ffd5d72016-03-23 16:20:4913261 SSLInfo empty_ssl_info;
[email protected]65d34382010-07-01 18:12:2613262
13263 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:1513264 if (test_config.proxy_auth_timing != AUTH_NONE) {
asanka463ca4262016-11-16 02:34:3113265 for (int n = 0; n < 3; n++) {
[email protected]2d01c262011-08-11 23:07:0813266 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
13267 std::string auth_challenge = "Mock realm=proxy";
13268 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:2413269 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
13270 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:0813271 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
tfarina42834112016-09-22 13:38:2013272 empty_ssl_info, origin,
13273 NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0813274 auth_handler->SetGenerateExpectation(
13275 test_config.proxy_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3113276 n == 0 ? test_config.first_generate_proxy_token_rv : OK);
[email protected]2d01c262011-08-11 23:07:0813277 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
13278 }
[email protected]044de0642010-06-17 10:42:1513279 }
13280 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:0013281 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:1513282 std::string auth_challenge = "Mock realm=server";
13283 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:2413284 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
13285 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:1513286 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2013287 empty_ssl_info, origin,
13288 NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1513289 auth_handler->SetGenerateExpectation(
13290 test_config.server_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3113291 test_config.first_generate_server_token_rv);
[email protected]2d01c262011-08-11 23:07:0813292 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
asankae2257db2016-10-11 22:03:1613293
13294 // The second handler always succeeds. It should only be used where there
13295 // are multiple auth sessions for server auth in the same network
13296 // transaction using the same auth scheme.
13297 std::unique_ptr<HttpAuthHandlerMock> second_handler =
Jeremy Roman0579ed62017-08-29 15:56:1913298 std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:1613299 second_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
13300 empty_ssl_info, origin,
13301 NetLogWithSource());
13302 second_handler->SetGenerateExpectation(true, OK);
13303 auth_factory->AddMockHandler(second_handler.release(),
13304 HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:1513305 }
13306 if (test_config.proxy_url) {
Lily Houghton8c2f97d2018-01-22 05:06:5913307 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4913308 ProxyResolutionService::CreateFixed(test_config.proxy_url,
13309 TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]044de0642010-06-17 10:42:1513310 } else {
Bence Béky53a5aef2018-03-29 21:54:1213311 session_deps_.proxy_resolution_service =
13312 ProxyResolutionService::CreateDirect();
[email protected]044de0642010-06-17 10:42:1513313 }
13314
13315 HttpRequestInfo request;
13316 request.method = "GET";
13317 request.url = GURL(test_config.server_url);
Ramin Halavatib5e433e62018-02-07 07:41:1013318 request.traffic_annotation =
13319 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]044de0642010-06-17 10:42:1513320
danakj1fd259a02016-04-16 03:17:0913321 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]044de0642010-06-17 10:42:1513322
rchcb68dc62015-05-21 04:45:3613323 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
13324
13325 std::vector<std::vector<MockRead>> mock_reads(1);
13326 std::vector<std::vector<MockWrite>> mock_writes(1);
[email protected]044de0642010-06-17 10:42:1513327 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2213328 SCOPED_TRACE(round);
[email protected]044de0642010-06-17 10:42:1513329 const TestRound& read_write_round = test_config.rounds[round];
13330
13331 // Set up expected reads and writes.
rchcb68dc62015-05-21 04:45:3613332 mock_reads.back().push_back(read_write_round.read);
13333 mock_writes.back().push_back(read_write_round.write);
13334
13335 // kProxyChallenge uses Proxy-Connection: close which means that the
13336 // socket is closed and a new one will be created for the next request.
mmenkee71e15332015-10-07 16:39:5413337 if (read_write_round.read.data == kProxyChallenge.data) {
rchcb68dc62015-05-21 04:45:3613338 mock_reads.push_back(std::vector<MockRead>());
13339 mock_writes.push_back(std::vector<MockWrite>());
[email protected]044de0642010-06-17 10:42:1513340 }
13341
rchcb68dc62015-05-21 04:45:3613342 if (read_write_round.extra_read) {
13343 mock_reads.back().push_back(*read_write_round.extra_read);
[email protected]044de0642010-06-17 10:42:1513344 }
rchcb68dc62015-05-21 04:45:3613345 if (read_write_round.extra_write) {
13346 mock_writes.back().push_back(*read_write_round.extra_write);
13347 }
[email protected]044de0642010-06-17 10:42:1513348
13349 // Add an SSL sequence if necessary.
[email protected]044de0642010-06-17 10:42:1513350 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0713351 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1513352 &ssl_socket_data_provider);
rchcb68dc62015-05-21 04:45:3613353 }
[email protected]044de0642010-06-17 10:42:1513354
danakj1fd259a02016-04-16 03:17:0913355 std::vector<std::unique_ptr<StaticSocketDataProvider>> data_providers;
rchcb68dc62015-05-21 04:45:3613356 for (size_t i = 0; i < mock_reads.size(); ++i) {
Jeremy Roman0579ed62017-08-29 15:56:1913357 data_providers.push_back(std::make_unique<StaticSocketDataProvider>(
Ryan Sleevib8d7ea02018-05-07 20:01:0113358 mock_reads[i], mock_writes[i]));
rchcb68dc62015-05-21 04:45:3613359 session_deps_.socket_factory->AddSocketDataProvider(
olli.raula525048c2015-12-10 07:38:3213360 data_providers.back().get());
rchcb68dc62015-05-21 04:45:3613361 }
13362
mmenkecc2298e2015-12-07 18:20:1813363 // Transaction must be created after DataProviders, so it's destroyed before
13364 // they are as well.
13365 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
13366
rchcb68dc62015-05-21 04:45:3613367 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2213368 SCOPED_TRACE(round);
rchcb68dc62015-05-21 04:45:3613369 const TestRound& read_write_round = test_config.rounds[round];
[email protected]044de0642010-06-17 10:42:1513370 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4113371 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1513372 int rv;
13373 if (round == 0) {
tfarina42834112016-09-22 13:38:2013374 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1513375 } else {
[email protected]49639fa2011-12-20 23:22:4113376 rv = trans.RestartWithAuth(
13377 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1513378 }
13379 if (rv == ERR_IO_PENDING)
13380 rv = callback.WaitForResult();
13381
13382 // Compare results with expected data.
asankae2257db2016-10-11 22:03:1613383 EXPECT_THAT(rv, IsError(read_write_round.expected_rv));
[email protected]0b0bf032010-09-21 18:08:5013384 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttlec0c828492015-05-15 01:25:5513385 if (read_write_round.expected_rv != OK) {
[email protected]044de0642010-06-17 10:42:1513386 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
13387 continue;
13388 }
13389 if (round + 1 < test_config.num_auth_rounds) {
wezca1070932016-05-26 20:30:5213390 EXPECT_TRUE(response->auth_challenge);
[email protected]044de0642010-06-17 10:42:1513391 } else {
wezca1070932016-05-26 20:30:5213392 EXPECT_FALSE(response->auth_challenge);
asankae2257db2016-10-11 22:03:1613393 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]044de0642010-06-17 10:42:1513394 }
13395 }
[email protected]e5ae96a2010-04-14 20:12:4513396 }
13397}
13398
bncd16676a2016-07-20 16:23:0113399TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1413400 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1413401 HttpAuthHandlerMock::Factory* auth_factory(
13402 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0713403 session_deps_.http_auth_handler_factory.reset(auth_factory);
Bence Béky53a5aef2018-03-29 21:54:1213404 session_deps_.proxy_resolution_service =
13405 ProxyResolutionService::CreateDirect();
[email protected]bb88e1d32013-05-03 23:11:0713406 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
[email protected]c871bce92010-07-15 21:51:1413407
13408 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
13409 auth_handler->set_connection_based(true);
13410 std::string auth_challenge = "Mock realm=server";
13411 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2413412 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
13413 auth_challenge.end());
asanka5ffd5d72016-03-23 16:20:4913414 SSLInfo empty_ssl_info;
[email protected]c871bce92010-07-15 21:51:1413415 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2013416 empty_ssl_info, origin, NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0813417 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1413418
[email protected]c871bce92010-07-15 21:51:1413419 int rv = OK;
13420 const HttpResponseInfo* response = NULL;
13421 HttpRequestInfo request;
13422 request.method = "GET";
13423 request.url = origin;
Ramin Halavatib5e433e62018-02-07 07:41:1013424 request.traffic_annotation =
13425 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2713426
danakj1fd259a02016-04-16 03:17:0913427 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1013428
13429 // Use a TCP Socket Pool with only one connection per group. This is used
13430 // to validate that the TCP socket is not released to the pool between
13431 // each round of multi-round authentication.
mmenkee65e7af2015-10-13 17:16:4213432 HttpNetworkSessionPeer session_peer(session.get());
[email protected]ab739042011-04-07 15:22:2813433 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:1013434 50, // Max sockets for pool
13435 1, // Max sockets per group
tbansal7b403bcc2016-04-13 22:33:2113436 session_deps_.host_resolver.get(), session_deps_.socket_factory.get(),
13437 NULL, session_deps_.net_log);
Jeremy Roman0579ed62017-08-29 15:56:1913438 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
[email protected]a42dbd142011-11-17 16:42:0213439 mock_pool_manager->SetTransportSocketPool(transport_pool);
dchengc7eeda422015-12-26 03:56:4813440 session_peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]7ef4cbbb2011-02-06 11:19:1013441
bnc691fda62016-08-12 00:43:1613442 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4113443 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1413444
13445 const MockWrite kGet(
13446 "GET / HTTP/1.1\r\n"
13447 "Host: www.example.com\r\n"
13448 "Connection: keep-alive\r\n\r\n");
13449 const MockWrite kGetAuth(
13450 "GET / HTTP/1.1\r\n"
13451 "Host: www.example.com\r\n"
13452 "Connection: keep-alive\r\n"
13453 "Authorization: auth_token\r\n\r\n");
13454
13455 const MockRead kServerChallenge(
13456 "HTTP/1.1 401 Unauthorized\r\n"
13457 "WWW-Authenticate: Mock realm=server\r\n"
13458 "Content-Type: text/html; charset=iso-8859-1\r\n"
13459 "Content-Length: 14\r\n\r\n"
13460 "Unauthorized\r\n");
13461 const MockRead kSuccess(
13462 "HTTP/1.1 200 OK\r\n"
13463 "Content-Type: text/html; charset=iso-8859-1\r\n"
13464 "Content-Length: 3\r\n\r\n"
13465 "Yes");
13466
13467 MockWrite writes[] = {
13468 // First round
13469 kGet,
13470 // Second round
13471 kGetAuth,
13472 // Third round
13473 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3013474 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1013475 kGetAuth,
13476 // Competing request
13477 kGet,
[email protected]c871bce92010-07-15 21:51:1413478 };
13479 MockRead reads[] = {
13480 // First round
13481 kServerChallenge,
13482 // Second round
13483 kServerChallenge,
13484 // Third round
[email protected]eca50e122010-09-11 14:03:3013485 kServerChallenge,
13486 // Fourth round
[email protected]c871bce92010-07-15 21:51:1413487 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1013488 // Competing response
13489 kSuccess,
[email protected]c871bce92010-07-15 21:51:1413490 };
Ryan Sleevib8d7ea02018-05-07 20:01:0113491 StaticSocketDataProvider data_provider(reads, writes);
[email protected]bb88e1d32013-05-03 23:11:0713492 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1413493
thestig9d3bb0c2015-01-24 00:49:5113494 const char kSocketGroup[] = "www.example.com:80";
[email protected]7ef4cbbb2011-02-06 11:19:1013495
13496 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1413497 auth_handler->SetGenerateExpectation(false, OK);
tfarina42834112016-09-22 13:38:2013498 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]c871bce92010-07-15 21:51:1413499 if (rv == ERR_IO_PENDING)
13500 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113501 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613502 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213503 ASSERT_TRUE(response);
13504 EXPECT_TRUE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813505 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3113506 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
13507 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1413508
[email protected]7ef4cbbb2011-02-06 11:19:1013509 // In between rounds, another request comes in for the same domain.
13510 // It should not be able to grab the TCP socket that trans has already
13511 // claimed.
bnc691fda62016-08-12 00:43:1613512 HttpNetworkTransaction trans_compete(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4113513 TestCompletionCallback callback_compete;
tfarina42834112016-09-22 13:38:2013514 rv = trans_compete.Start(&request, callback_compete.callback(),
13515 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113516 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7ef4cbbb2011-02-06 11:19:1013517 // callback_compete.WaitForResult at this point would stall forever,
13518 // since the HttpNetworkTransaction does not release the request back to
13519 // the pool until after authentication completes.
13520
13521 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1413522 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1613523 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1413524 if (rv == ERR_IO_PENDING)
13525 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113526 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613527 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213528 ASSERT_TRUE(response);
13529 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813530 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3113531 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
13532 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1413533
[email protected]7ef4cbbb2011-02-06 11:19:1013534 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1413535 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1613536 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1413537 if (rv == ERR_IO_PENDING)
13538 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113539 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613540 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213541 ASSERT_TRUE(response);
13542 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813543 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3113544 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
13545 auth_handler->state());
[email protected]eca50e122010-09-11 14:03:3013546
[email protected]7ef4cbbb2011-02-06 11:19:1013547 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3013548 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1613549 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3013550 if (rv == ERR_IO_PENDING)
13551 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113552 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613553 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213554 ASSERT_TRUE(response);
13555 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813556 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1013557
asanka463ca4262016-11-16 02:34:3113558 // In WAIT_FOR_CHALLENGE, although in reality the auth handler is done. A real
13559 // auth handler should transition to a DONE state in concert with the remote
13560 // server. But that's not something we can test here with a mock handler.
13561 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_CHALLENGE,
13562 auth_handler->state());
13563
[email protected]7ef4cbbb2011-02-06 11:19:1013564 // Read the body since the fourth round was successful. This will also
13565 // release the socket back to the pool.
13566 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
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 if (rv == ERR_IO_PENDING)
13569 rv = callback.WaitForResult();
13570 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1613571 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1013572 EXPECT_EQ(0, rv);
13573 // There are still 0 idle sockets, since the trans_compete transaction
13574 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:2813575 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1013576
13577 // The competing request can now finish. Wait for the headers and then
13578 // read the body.
13579 rv = callback_compete.WaitForResult();
robpercival214763f2016-07-01 23:27:0113580 EXPECT_THAT(rv, IsOk());
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 if (rv == ERR_IO_PENDING)
13583 rv = callback.WaitForResult();
13584 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1613585 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1013586 EXPECT_EQ(0, rv);
13587
13588 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:2813589 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1413590}
13591
[email protected]65041fa2010-05-21 06:56:5313592// This tests the case that a request is issued via http instead of spdy after
13593// npn is negotiated.
bncd16676a2016-07-20 16:23:0113594TEST_F(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]65041fa2010-05-21 06:56:5313595 HttpRequestInfo request;
13596 request.method = "GET";
bncce36dca22015-04-21 22:11:2313597 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1013598 request.traffic_annotation =
13599 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]65041fa2010-05-21 06:56:5313600
13601 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2313602 MockWrite(
13603 "GET / HTTP/1.1\r\n"
13604 "Host: www.example.org\r\n"
13605 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5313606 };
13607
13608 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5213609 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4313610 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5213611 MockRead("\r\n"),
13612 MockRead("hello world"),
13613 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5313614 };
13615
[email protected]8ddf8322012-02-23 18:08:0613616 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613617 ssl.next_proto = kProtoHTTP11;
[email protected]65041fa2010-05-21 06:56:5313618
[email protected]bb88e1d32013-05-03 23:11:0713619 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5313620
Ryan Sleevib8d7ea02018-05-07 20:01:0113621 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0713622 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5313623
[email protected]49639fa2011-12-20 23:22:4113624 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5313625
danakj1fd259a02016-04-16 03:17:0913626 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613627 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]65041fa2010-05-21 06:56:5313628
tfarina42834112016-09-22 13:38:2013629 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]65041fa2010-05-21 06:56:5313630
robpercival214763f2016-07-01 23:27:0113631 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13632 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]65041fa2010-05-21 06:56:5313633
bnc691fda62016-08-12 00:43:1613634 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213635 ASSERT_TRUE(response);
13636 ASSERT_TRUE(response->headers);
[email protected]65041fa2010-05-21 06:56:5313637 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13638
13639 std::string response_data;
bnc691fda62016-08-12 00:43:1613640 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]65041fa2010-05-21 06:56:5313641 EXPECT_EQ("hello world", response_data);
13642
13643 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213644 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]65041fa2010-05-21 06:56:5313645}
[email protected]26ef6582010-06-24 02:30:4713646
bnc55ff9da2015-08-19 18:42:3513647// Simulate the SSL handshake completing with an NPN negotiation followed by an
13648// immediate server closing of the socket.
13649// Regression test for https://crbug.com/46369.
bncd16676a2016-07-20 16:23:0113650TEST_F(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:4713651 HttpRequestInfo request;
13652 request.method = "GET";
bncce36dca22015-04-21 22:11:2313653 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1013654 request.traffic_annotation =
13655 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]26ef6582010-06-24 02:30:4713656
[email protected]8ddf8322012-02-23 18:08:0613657 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613658 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0713659 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4713660
Ryan Hamilton0239aac2018-05-19 00:03:1313661 spdy::SpdySerializedFrame req(
13662 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4113663 MockWrite spdy_writes[] = {CreateMockWrite(req, 1)};
[email protected]26ef6582010-06-24 02:30:4713664
13665 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0613666 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4713667 };
13668
Ryan Sleevib8d7ea02018-05-07 20:01:0113669 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0713670 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4713671
[email protected]49639fa2011-12-20 23:22:4113672 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4713673
danakj1fd259a02016-04-16 03:17:0913674 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613675 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]26ef6582010-06-24 02:30:4713676
tfarina42834112016-09-22 13:38:2013677 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113678 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13679 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]26ef6582010-06-24 02:30:4713680}
[email protected]65d34382010-07-01 18:12:2613681
[email protected]795cbf82013-07-22 09:37:2713682// A subclass of HttpAuthHandlerMock that records the request URL when
13683// it gets it. This is needed since the auth handler may get destroyed
13684// before we get a chance to query it.
13685class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
13686 public:
13687 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
13688
Chris Watkins7a41d3552017-12-01 02:13:2713689 ~UrlRecordingHttpAuthHandlerMock() override = default;
[email protected]795cbf82013-07-22 09:37:2713690
13691 protected:
dchengb03027d2014-10-21 12:00:2013692 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
13693 const HttpRequestInfo* request,
Bence Béky7236fb72018-08-01 14:35:0913694 CompletionOnceCallback callback,
dchengb03027d2014-10-21 12:00:2013695 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2713696 *url_ = request->url;
13697 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
Bence Béky7236fb72018-08-01 14:35:0913698 credentials, request, std::move(callback), auth_token);
[email protected]795cbf82013-07-22 09:37:2713699 }
13700
13701 private:
13702 GURL* url_;
13703};
13704
[email protected]8e6441ca2010-08-19 05:56:3813705// Test that if we cancel the transaction as the connection is completing, that
13706// everything tears down correctly.
bncd16676a2016-07-20 16:23:0113707TEST_F(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3813708 // Setup everything about the connection to complete synchronously, so that
13709 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
13710 // for is the callback from the HttpStreamRequest.
13711 // Then cancel the transaction.
13712 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3613713 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3813714 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0613715 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
13716 MockRead(SYNCHRONOUS, "hello world"),
13717 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3813718 };
13719
[email protected]8e6441ca2010-08-19 05:56:3813720 HttpRequestInfo request;
13721 request.method = "GET";
bncce36dca22015-04-21 22:11:2313722 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1013723 request.traffic_annotation =
13724 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8e6441ca2010-08-19 05:56:3813725
danakj1fd259a02016-04-16 03:17:0913726 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5813727 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1913728 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2713729
Ryan Sleevib8d7ea02018-05-07 20:01:0113730 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]8e6441ca2010-08-19 05:56:3813731 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0713732 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3813733
[email protected]49639fa2011-12-20 23:22:4113734 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3813735
vishal.b62985ca92015-04-17 08:45:5113736 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4113737 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113738 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8e6441ca2010-08-19 05:56:3813739 trans.reset(); // Cancel the transaction here.
13740
fdoray92e35a72016-06-10 15:54:5513741 base::RunLoop().RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3013742}
13743
[email protected]ecab6e052014-05-16 14:58:1213744// Test that if a transaction is cancelled after receiving the headers, the
13745// stream is drained properly and added back to the socket pool. The main
13746// purpose of this test is to make sure that an HttpStreamParser can be read
13747// from after the HttpNetworkTransaction and the objects it owns have been
13748// deleted.
13749// See http://crbug.com/368418
bncd16676a2016-07-20 16:23:0113750TEST_F(HttpNetworkTransactionTest, CancelAfterHeaders) {
[email protected]ecab6e052014-05-16 14:58:1213751 MockRead data_reads[] = {
13752 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
13753 MockRead(ASYNC, "Content-Length: 2\r\n"),
13754 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
13755 MockRead(ASYNC, "1"),
13756 // 2 async reads are necessary to trigger a ReadResponseBody call after the
13757 // HttpNetworkTransaction has been deleted.
13758 MockRead(ASYNC, "2"),
13759 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
13760 };
Ryan Sleevib8d7ea02018-05-07 20:01:0113761 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]ecab6e052014-05-16 14:58:1213762 session_deps_.socket_factory->AddSocketDataProvider(&data);
13763
danakj1fd259a02016-04-16 03:17:0913764 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]ecab6e052014-05-16 14:58:1213765
13766 {
13767 HttpRequestInfo request;
13768 request.method = "GET";
bncce36dca22015-04-21 22:11:2313769 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1013770 request.traffic_annotation =
13771 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ecab6e052014-05-16 14:58:1213772
dcheng48459ac22014-08-26 00:46:4113773 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1213774 TestCompletionCallback callback;
13775
tfarina42834112016-09-22 13:38:2013776 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113777 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ecab6e052014-05-16 14:58:1213778 callback.WaitForResult();
13779
13780 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213781 ASSERT_TRUE(response);
13782 EXPECT_TRUE(response->headers);
[email protected]ecab6e052014-05-16 14:58:1213783 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13784
13785 // The transaction and HttpRequestInfo are deleted.
13786 }
13787
13788 // Let the HttpResponseBodyDrainer drain the socket.
fdoray92e35a72016-06-10 15:54:5513789 base::RunLoop().RunUntilIdle();
[email protected]ecab6e052014-05-16 14:58:1213790
13791 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4113792 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1213793}
13794
[email protected]76a505b2010-08-25 06:23:0013795// Test a basic GET request through a proxy.
bncd16676a2016-07-20 16:23:0113796TEST_F(HttpNetworkTransactionTest, ProxyGet) {
Lily Houghton8c2f97d2018-01-22 05:06:5913797 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4913798 ProxyResolutionService::CreateFixedFromPacResult(
13799 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5113800 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713801 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913802 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0013803
[email protected]76a505b2010-08-25 06:23:0013804 HttpRequestInfo request;
13805 request.method = "GET";
bncce36dca22015-04-21 22:11:2313806 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1013807 request.traffic_annotation =
13808 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0013809
13810 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2313811 MockWrite(
13812 "GET http://www.example.org/ HTTP/1.1\r\n"
13813 "Host: www.example.org\r\n"
13814 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013815 };
13816
13817 MockRead data_reads1[] = {
13818 MockRead("HTTP/1.1 200 OK\r\n"),
13819 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
13820 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0613821 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0013822 };
13823
Ryan Sleevib8d7ea02018-05-07 20:01:0113824 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:0713825 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0013826
[email protected]49639fa2011-12-20 23:22:4113827 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0013828
bnc691fda62016-08-12 00:43:1613829 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0913830 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1613831 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0913832 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
13833 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5013834
bnc691fda62016-08-12 00:43:1613835 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113836 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0013837
13838 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113839 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:0013840
bnc691fda62016-08-12 00:43:1613841 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213842 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0013843
13844 EXPECT_TRUE(response->headers->IsKeepAlive());
13845 EXPECT_EQ(200, response->headers->response_code());
13846 EXPECT_EQ(100, response->headers->GetContentLength());
13847 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4713848 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
13849 HostPortPair::FromString("myproxy:70")),
13850 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0913851 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
13852 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
13853 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0013854 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2013855
13856 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1613857 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2013858 TestLoadTimingNotReusedWithPac(load_timing_info,
13859 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0013860}
13861
13862// Test a basic HTTPS GET request through a proxy.
bncd16676a2016-07-20 16:23:0113863TEST_F(HttpNetworkTransactionTest, ProxyTunnelGet) {
Lily Houghton8c2f97d2018-01-22 05:06:5913864 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4913865 ProxyResolutionService::CreateFixedFromPacResult(
13866 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5113867 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713868 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913869 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0013870
[email protected]76a505b2010-08-25 06:23:0013871 HttpRequestInfo request;
13872 request.method = "GET";
bncce36dca22015-04-21 22:11:2313873 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1013874 request.traffic_annotation =
13875 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0013876
13877 // Since we have proxy, should try to establish tunnel.
13878 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1713879 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
13880 "Host: www.example.org:443\r\n"
13881 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013882
rsleevidb16bb02015-11-12 23:47:1713883 MockWrite("GET / HTTP/1.1\r\n"
13884 "Host: www.example.org\r\n"
13885 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013886 };
13887
13888 MockRead data_reads1[] = {
13889 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
13890
13891 MockRead("HTTP/1.1 200 OK\r\n"),
13892 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
13893 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0613894 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0013895 };
13896
Ryan Sleevib8d7ea02018-05-07 20:01:0113897 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:0713898 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0613899 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0713900 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0013901
[email protected]49639fa2011-12-20 23:22:4113902 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0013903
bnc691fda62016-08-12 00:43:1613904 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0913905 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1613906 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0913907 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
13908 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5013909
bnc691fda62016-08-12 00:43:1613910 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113911 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0013912
13913 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113914 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:4613915 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4013916 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0013917 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0013918 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
13919 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013920 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4013921 entries, pos,
mikecirone8b85c432016-09-08 19:11:0013922 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
13923 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013924
bnc691fda62016-08-12 00:43:1613925 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213926 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0013927
13928 EXPECT_TRUE(response->headers->IsKeepAlive());
13929 EXPECT_EQ(200, response->headers->response_code());
13930 EXPECT_EQ(100, response->headers->GetContentLength());
13931 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
13932 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4713933 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
13934 HostPortPair::FromString("myproxy:70")),
13935 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0913936 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
13937 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
13938 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]029c83b62013-01-24 05:28:2013939
13940 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1613941 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2013942 TestLoadTimingNotReusedWithPac(load_timing_info,
13943 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0013944}
13945
rsleevidb16bb02015-11-12 23:47:1713946// Test a basic HTTPS GET request through a proxy, connecting to an IPv6
13947// literal host.
bncd16676a2016-07-20 16:23:0113948TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetIPv6) {
Lily Houghton8c2f97d2018-01-22 05:06:5913949 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4913950 ProxyResolutionService::CreateFixedFromPacResult(
13951 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
rsleevidb16bb02015-11-12 23:47:1713952 BoundTestNetLog log;
13953 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913954 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
rsleevidb16bb02015-11-12 23:47:1713955
13956 HttpRequestInfo request;
13957 request.method = "GET";
13958 request.url = GURL("https://[::1]:443/");
Ramin Halavatib5e433e62018-02-07 07:41:1013959 request.traffic_annotation =
13960 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rsleevidb16bb02015-11-12 23:47:1713961
13962 // Since we have proxy, should try to establish tunnel.
13963 MockWrite data_writes1[] = {
13964 MockWrite("CONNECT [::1]:443 HTTP/1.1\r\n"
13965 "Host: [::1]:443\r\n"
13966 "Proxy-Connection: keep-alive\r\n\r\n"),
13967
13968 MockWrite("GET / HTTP/1.1\r\n"
13969 "Host: [::1]\r\n"
13970 "Connection: keep-alive\r\n\r\n"),
13971 };
13972
13973 MockRead data_reads1[] = {
13974 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
13975
13976 MockRead("HTTP/1.1 200 OK\r\n"),
13977 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
13978 MockRead("Content-Length: 100\r\n\r\n"),
13979 MockRead(SYNCHRONOUS, OK),
13980 };
13981
Ryan Sleevib8d7ea02018-05-07 20:01:0113982 StaticSocketDataProvider data1(data_reads1, data_writes1);
rsleevidb16bb02015-11-12 23:47:1713983 session_deps_.socket_factory->AddSocketDataProvider(&data1);
13984 SSLSocketDataProvider ssl(ASYNC, OK);
13985 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13986
13987 TestCompletionCallback callback1;
13988
bnc691fda62016-08-12 00:43:1613989 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
rsleevidb16bb02015-11-12 23:47:1713990
bnc691fda62016-08-12 00:43:1613991 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113992 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rsleevidb16bb02015-11-12 23:47:1713993
13994 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113995 EXPECT_THAT(rv, IsOk());
rsleevidb16bb02015-11-12 23:47:1713996 TestNetLogEntry::List entries;
13997 log.GetEntries(&entries);
13998 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0013999 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
14000 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1714001 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014002 entries, pos,
14003 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
14004 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1714005
bnc691fda62016-08-12 00:43:1614006 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214007 ASSERT_TRUE(response);
rsleevidb16bb02015-11-12 23:47:1714008
14009 EXPECT_TRUE(response->headers->IsKeepAlive());
14010 EXPECT_EQ(200, response->headers->response_code());
14011 EXPECT_EQ(100, response->headers->GetContentLength());
14012 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
14013 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4714014 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
14015 HostPortPair::FromString("myproxy:70")),
14016 response->proxy_server);
rsleevidb16bb02015-11-12 23:47:1714017
14018 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1614019 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
rsleevidb16bb02015-11-12 23:47:1714020 TestLoadTimingNotReusedWithPac(load_timing_info,
14021 CONNECT_TIMING_HAS_SSL_TIMES);
14022}
14023
[email protected]76a505b2010-08-25 06:23:0014024// Test a basic HTTPS GET request through a proxy, but the server hangs up
14025// while establishing the tunnel.
bncd16676a2016-07-20 16:23:0114026TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
Ramin Halavatica8d5252018-03-12 05:33:4914027 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
14028 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5114029 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714030 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0914031 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0014032
[email protected]76a505b2010-08-25 06:23:0014033 HttpRequestInfo request;
14034 request.method = "GET";
bncce36dca22015-04-21 22:11:2314035 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1014036 request.traffic_annotation =
14037 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0014038
14039 // Since we have proxy, should try to establish tunnel.
14040 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1714041 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
14042 "Host: www.example.org:443\r\n"
14043 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014044
rsleevidb16bb02015-11-12 23:47:1714045 MockWrite("GET / HTTP/1.1\r\n"
14046 "Host: www.example.org\r\n"
14047 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014048 };
14049
14050 MockRead data_reads1[] = {
[email protected]76a505b2010-08-25 06:23:0014051 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0614052 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0014053 };
14054
Ryan Sleevib8d7ea02018-05-07 20:01:0114055 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:0714056 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0614057 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0714058 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0014059
[email protected]49639fa2011-12-20 23:22:4114060 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0014061
bnc691fda62016-08-12 00:43:1614062 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5014063
bnc691fda62016-08-12 00:43:1614064 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114065 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0014066
14067 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0114068 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
mmenke43758e62015-05-04 21:09:4614069 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4014070 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0014071 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014072 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
14073 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0014074 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4014075 entries, pos,
mikecirone8b85c432016-09-08 19:11:0014076 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
14077 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0014078}
14079
[email protected]749eefa82010-09-13 22:14:0314080// Test for crbug.com/55424.
bncd16676a2016-07-20 16:23:0114081TEST_F(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
Ryan Hamilton0239aac2018-05-19 00:03:1314082 spdy::SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4914083 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4114084 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]749eefa82010-09-13 22:14:0314085
Ryan Hamilton0239aac2018-05-19 00:03:1314086 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
14087 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0314088 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114089 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0314090 };
14091
Ryan Sleevib8d7ea02018-05-07 20:01:0114092 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0714093 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0314094
[email protected]8ddf8322012-02-23 18:08:0614095 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614096 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0714097 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0314098
danakj1fd259a02016-04-16 03:17:0914099 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0314100
14101 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2314102 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4014103 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
Paul Jensena457017a2018-01-19 23:52:0414104 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]795cbf82013-07-22 09:37:2714105 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:5214106 CreateSpdySession(session.get(), key, NetLogWithSource());
[email protected]749eefa82010-09-13 22:14:0314107
14108 HttpRequestInfo request;
14109 request.method = "GET";
bncce36dca22015-04-21 22:11:2314110 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1014111 request.traffic_annotation =
14112 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]749eefa82010-09-13 22:14:0314113
bnc691fda62016-08-12 00:43:1614114 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]749eefa82010-09-13 22:14:0314115
[email protected]41d64e82013-07-03 22:44:2614116 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014117 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114118 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14119 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]749eefa82010-09-13 22:14:0314120}
14121
[email protected]73b8dd222010-11-11 19:55:2414122// Given a net error, cause that error to be returned from the first Write()
bnc691fda62016-08-12 00:43:1614123// call and verify that the HttpNetworkTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0214124void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0714125 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2914126 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2714127 request_info.url = GURL("https://www.example.com/");
14128 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914129 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:1014130 request_info.traffic_annotation =
14131 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2714132
[email protected]8ddf8322012-02-23 18:08:0614133 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2914134 MockWrite data_writes[] = {
14135 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2414136 };
Ryan Sleevib8d7ea02018-05-07 20:01:0114137 StaticSocketDataProvider data(base::span<MockRead>(), data_writes);
[email protected]bb88e1d32013-05-03 23:11:0714138 session_deps_.socket_factory->AddSocketDataProvider(&data);
14139 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2414140
danakj1fd259a02016-04-16 03:17:0914141 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614142 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]73b8dd222010-11-11 19:55:2414143
[email protected]49639fa2011-12-20 23:22:4114144 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014145 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
ttuttle859dc7a2015-04-23 19:42:2914146 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2414147 rv = callback.WaitForResult();
14148 ASSERT_EQ(error, rv);
14149}
14150
bncd16676a2016-07-20 16:23:0114151TEST_F(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2414152 // Just check a grab bag of cert errors.
14153 static const int kErrors[] = {
14154 ERR_CERT_COMMON_NAME_INVALID,
14155 ERR_CERT_AUTHORITY_INVALID,
14156 ERR_CERT_DATE_INVALID,
14157 };
14158 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0614159 CheckErrorIsPassedBack(kErrors[i], ASYNC);
14160 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2414161 }
14162}
14163
[email protected]bd0b6772011-01-11 19:59:3014164// Ensure that a client certificate is removed from the SSL client auth
14165// cache when:
14166// 1) No proxy is involved.
14167// 2) TLS False Start is disabled.
14168// 3) The initial TLS handshake requests a client certificate.
14169// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0114170TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_NoFalseStart) {
ttuttle859dc7a2015-04-23 19:42:2914171 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2714172 request_info.url = GURL("https://www.example.com/");
14173 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914174 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:1014175 request_info.traffic_annotation =
14176 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2714177
[email protected]bd0b6772011-01-11 19:59:3014178 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4114179 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3014180
14181 // [ssl_]data1 contains the data for the first SSL handshake. When a
14182 // CertificateRequest is received for the first time, the handshake will
14183 // be aborted to allow the caller to provide a certificate.
ttuttle859dc7a2015-04-23 19:42:2914184 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3014185 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714186 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
Ryan Sleevib8d7ea02018-05-07 20:01:0114187 StaticSocketDataProvider data1;
[email protected]bb88e1d32013-05-03 23:11:0714188 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3014189
14190 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
14191 // False Start is not being used, the result of the SSL handshake will be
14192 // returned as part of the SSLClientSocket::Connect() call. This test
14193 // matches the result of a server sending a handshake_failure alert,
14194 // rather than a Finished message, because it requires a client
14195 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2914196 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3014197 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714198 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
Ryan Sleevib8d7ea02018-05-07 20:01:0114199 StaticSocketDataProvider data2;
[email protected]bb88e1d32013-05-03 23:11:0714200 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3014201
14202 // [ssl_]data3 contains the data for the third SSL handshake. When a
14203 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4214204 // HttpNetworkTransaction will attempt to fallback to TLSv1.1 if the previous
14205 // connection was attempted with TLSv1.2. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3014206 // of the HttpNetworkTransaction. Because this test failure is due to
14207 // requiring a client certificate, this fallback handshake should also
14208 // fail.
ttuttle859dc7a2015-04-23 19:42:2914209 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3014210 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714211 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
Ryan Sleevib8d7ea02018-05-07 20:01:0114212 StaticSocketDataProvider data3;
[email protected]bb88e1d32013-05-03 23:11:0714213 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3014214
[email protected]80c75f682012-05-26 16:22:1714215 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
14216 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4214217 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
14218 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]80c75f682012-05-26 16:22:1714219 // of the HttpNetworkTransaction. Because this test failure is due to
14220 // requiring a client certificate, this fallback handshake should also
14221 // fail.
ttuttle859dc7a2015-04-23 19:42:2914222 SSLSocketDataProvider ssl_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1714223 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714224 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
Ryan Sleevib8d7ea02018-05-07 20:01:0114225 StaticSocketDataProvider data4;
[email protected]bb88e1d32013-05-03 23:11:0714226 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1714227
danakj1fd259a02016-04-16 03:17:0914228 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614229 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3014230
[email protected]bd0b6772011-01-11 19:59:3014231 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4114232 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014233 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114234 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3014235
14236 // Complete the SSL handshake, which should abort due to requiring a
14237 // client certificate.
14238 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114239 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3014240
14241 // Indicate that no certificate should be supplied. From the perspective
14242 // of SSLClientCertCache, NULL is just as meaningful as a real
14243 // certificate, so this is the same as supply a
14244 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1614245 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0114246 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3014247
14248 // Ensure the certificate was added to the client auth cache before
14249 // allowing the connection to continue restarting.
14250 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5414251 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4114252 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414253 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5214254 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3014255
14256 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1714257 // then consume ssl_data3 and ssl_data4, both of which should also fail.
14258 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3014259 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114260 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3014261
14262 // Ensure that the client certificate is removed from the cache on a
14263 // handshake failure.
[email protected]791879c2013-12-17 07:22:4114264 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414265 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3014266}
14267
14268// Ensure that a client certificate is removed from the SSL client auth
14269// cache when:
14270// 1) No proxy is involved.
14271// 2) TLS False Start is enabled.
14272// 3) The initial TLS handshake requests a client certificate.
14273// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0114274TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2914275 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2714276 request_info.url = GURL("https://www.example.com/");
14277 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914278 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:1014279 request_info.traffic_annotation =
14280 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2714281
[email protected]bd0b6772011-01-11 19:59:3014282 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4114283 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3014284
14285 // When TLS False Start is used, SSLClientSocket::Connect() calls will
14286 // return successfully after reading up to the peer's Certificate message.
14287 // This is to allow the caller to call SSLClientSocket::Write(), which can
14288 // enqueue application data to be sent in the same packet as the
14289 // ChangeCipherSpec and Finished messages.
14290 // The actual handshake will be finished when SSLClientSocket::Read() is
14291 // called, which expects to process the peer's ChangeCipherSpec and
14292 // Finished messages. If there was an error negotiating with the peer,
14293 // such as due to the peer requiring a client certificate when none was
14294 // supplied, the alert sent by the peer won't be processed until Read() is
14295 // called.
14296
14297 // Like the non-False Start case, when a client certificate is requested by
14298 // the peer, the handshake is aborted during the Connect() call.
14299 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2914300 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3014301 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714302 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
Ryan Sleevib8d7ea02018-05-07 20:01:0114303 StaticSocketDataProvider data1;
[email protected]bb88e1d32013-05-03 23:11:0714304 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3014305
14306 // When a client certificate is supplied, Connect() will not be aborted
14307 // when the peer requests the certificate. Instead, the handshake will
14308 // artificially succeed, allowing the caller to write the HTTP request to
14309 // the socket. The handshake messages are not processed until Read() is
14310 // called, which then detects that the handshake was aborted, due to the
14311 // peer sending a handshake_failure because it requires a client
14312 // certificate.
ttuttle859dc7a2015-04-23 19:42:2914313 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3014314 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714315 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2914316 MockRead data2_reads[] = {
14317 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3014318 };
Ryan Sleevib8d7ea02018-05-07 20:01:0114319 StaticSocketDataProvider data2(data2_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0714320 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3014321
14322 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1714323 // the data for the SSL handshake once the TLSv1.1 connection falls back to
14324 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2914325 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3014326 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714327 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
Ryan Sleevib8d7ea02018-05-07 20:01:0114328 StaticSocketDataProvider data3(data2_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0714329 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3014330
[email protected]80c75f682012-05-26 16:22:1714331 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
14332 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2914333 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1714334 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714335 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
Ryan Sleevib8d7ea02018-05-07 20:01:0114336 StaticSocketDataProvider data4(data2_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0714337 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1714338
[email protected]7799de12013-05-30 05:52:5114339 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2914340 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5114341 ssl_data5.cert_request_info = cert_request.get();
14342 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
Ryan Sleevib8d7ea02018-05-07 20:01:0114343 StaticSocketDataProvider data5(data2_reads, base::span<MockWrite>());
[email protected]7799de12013-05-30 05:52:5114344 session_deps_.socket_factory->AddSocketDataProvider(&data5);
14345
danakj1fd259a02016-04-16 03:17:0914346 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614347 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3014348
[email protected]bd0b6772011-01-11 19:59:3014349 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4114350 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014351 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114352 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3014353
14354 // Complete the SSL handshake, which should abort due to requiring a
14355 // client certificate.
14356 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114357 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3014358
14359 // Indicate that no certificate should be supplied. From the perspective
14360 // of SSLClientCertCache, NULL is just as meaningful as a real
14361 // certificate, so this is the same as supply a
14362 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1614363 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0114364 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3014365
14366 // Ensure the certificate was added to the client auth cache before
14367 // allowing the connection to continue restarting.
14368 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5414369 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4114370 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414371 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5214372 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3014373
[email protected]bd0b6772011-01-11 19:59:3014374 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1714375 // then consume ssl_data3 and ssl_data4, both of which should also fail.
14376 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3014377 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114378 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3014379
14380 // Ensure that the client certificate is removed from the cache on a
14381 // handshake failure.
[email protected]791879c2013-12-17 07:22:4114382 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414383 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3014384}
14385
[email protected]8c405132011-01-11 22:03:1814386// Ensure that a client certificate is removed from the SSL client auth
14387// cache when:
14388// 1) An HTTPS proxy is involved.
14389// 3) The HTTPS proxy requests a client certificate.
14390// 4) The client supplies an invalid/unacceptable certificate for the
14391// proxy.
14392// The test is repeated twice, first for connecting to an HTTPS endpoint,
14393// then for connecting to an HTTP endpoint.
bncd16676a2016-07-20 16:23:0114394TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
Ramin Halavatica8d5252018-03-12 05:33:4914395 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
14396 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5114397 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714398 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1814399
14400 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4114401 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1814402
14403 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
14404 // [ssl_]data[1-3]. Rather than represending the endpoint
14405 // (www.example.com:443), they represent failures with the HTTPS proxy
14406 // (proxy:70).
ttuttle859dc7a2015-04-23 19:42:2914407 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1814408 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714409 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
Ryan Sleevib8d7ea02018-05-07 20:01:0114410 StaticSocketDataProvider data1;
[email protected]bb88e1d32013-05-03 23:11:0714411 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1814412
ttuttle859dc7a2015-04-23 19:42:2914413 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1814414 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714415 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
Ryan Sleevib8d7ea02018-05-07 20:01:0114416 StaticSocketDataProvider data2;
[email protected]bb88e1d32013-05-03 23:11:0714417 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1814418
[email protected]80c75f682012-05-26 16:22:1714419 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
14420#if 0
ttuttle859dc7a2015-04-23 19:42:2914421 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1814422 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714423 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
Ryan Sleevib8d7ea02018-05-07 20:01:0114424 StaticSocketDataProvider data3;
[email protected]bb88e1d32013-05-03 23:11:0714425 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1714426#endif
[email protected]8c405132011-01-11 22:03:1814427
ttuttle859dc7a2015-04-23 19:42:2914428 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1814429 requests[0].url = GURL("https://www.example.com/");
14430 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914431 requests[0].load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:1014432 requests[0].traffic_annotation =
14433 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c405132011-01-11 22:03:1814434
14435 requests[1].url = GURL("http://www.example.com/");
14436 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914437 requests[1].load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:1014438 requests[1].traffic_annotation =
14439 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c405132011-01-11 22:03:1814440
14441 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0714442 session_deps_.socket_factory->ResetNextMockIndexes();
danakj1fd259a02016-04-16 03:17:0914443 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614444 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]8c405132011-01-11 22:03:1814445
14446 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4114447 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014448 int rv = trans.Start(&requests[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114449 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1814450
14451 // Complete the SSL handshake, which should abort due to requiring a
14452 // client certificate.
14453 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114454 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]8c405132011-01-11 22:03:1814455
14456 // Indicate that no certificate should be supplied. From the perspective
14457 // of SSLClientCertCache, NULL is just as meaningful as a real
14458 // certificate, so this is the same as supply a
14459 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1614460 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0114461 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1814462
14463 // Ensure the certificate was added to the client auth cache before
14464 // allowing the connection to continue restarting.
14465 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5414466 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4114467 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414468 HostPortPair("proxy", 70), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5214469 ASSERT_FALSE(client_cert);
[email protected]8c405132011-01-11 22:03:1814470 // Ensure the certificate was NOT cached for the endpoint. This only
14471 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4114472 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414473 HostPortPair("www.example.com", 443), &client_cert,
14474 &client_private_key));
[email protected]8c405132011-01-11 22:03:1814475
14476 // Restart the handshake. This will consume ssl_data2, which fails, and
14477 // then consume ssl_data3, which should also fail. The result code is
14478 // checked against what ssl_data3 should return.
14479 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114480 ASSERT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]8c405132011-01-11 22:03:1814481
14482 // Now that the new handshake has failed, ensure that the client
14483 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4114484 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414485 HostPortPair("proxy", 70), &client_cert, &client_private_key));
[email protected]791879c2013-12-17 07:22:4114486 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414487 HostPortPair("www.example.com", 443), &client_cert,
14488 &client_private_key));
[email protected]8c405132011-01-11 22:03:1814489 }
14490}
14491
bncd16676a2016-07-20 16:23:0114492TEST_F(HttpNetworkTransactionTest, UseIPConnectionPooling) {
[email protected]e3ceb682011-06-28 23:55:4614493 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1914494 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0914495 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4614496
bnc032658ba2016-09-26 18:17:1514497 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4614498
Ryan Hamilton0239aac2018-05-19 00:03:1314499 spdy::SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4914500 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3814501 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1314502 spdy::SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3714503 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4614504 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114505 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4614506 };
Ryan Hamilton0239aac2018-05-19 00:03:1314507 spdy::SpdySerializedFrame host1_resp(
14508 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
14509 spdy::SpdySerializedFrame host1_resp_body(
bncdf80d44fd2016-07-15 20:27:4114510 spdy_util_.ConstructSpdyDataFrame(1, true));
Ryan Hamilton0239aac2018-05-19 00:03:1314511 spdy::SpdySerializedFrame host2_resp(
14512 spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
14513 spdy::SpdySerializedFrame host2_resp_body(
bncdf80d44fd2016-07-15 20:27:4114514 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4614515 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114516 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
14517 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1314518 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4614519 };
14520
eroman36d84e54432016-03-17 03:23:0214521 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0214522 MockConnect connect(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0114523 SequencedSocketData spdy_data(connect, spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0714524 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4614525
[email protected]aa22b242011-11-16 18:58:2914526 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4614527 HttpRequestInfo request1;
14528 request1.method = "GET";
bncce36dca22015-04-21 22:11:2314529 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4614530 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1014531 request1.traffic_annotation =
14532 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5014533 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4614534
tfarina42834112016-09-22 13:38:2014535 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114536 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14537 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614538
14539 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5214540 ASSERT_TRUE(response);
14541 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214542 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4614543
14544 std::string response_data;
robpercival214763f2016-07-01 23:27:0114545 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614546 EXPECT_EQ("hello!", response_data);
14547
bnca4d611d2016-09-22 19:55:3714548 // Preload mail.example.com into HostCache.
14549 HostPortPair host_port("mail.example.com", 443);
[email protected]5109c1952013-08-20 18:44:1014550 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4614551 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1014552 std::unique_ptr<HostResolver::Request> request;
14553 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
14554 &ignored, callback.callback(),
tfarina42834112016-09-22 13:38:2014555 &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114556 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4714557 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114558 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4614559
14560 HttpRequestInfo request2;
14561 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3714562 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4614563 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1014564 request2.traffic_annotation =
14565 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5014566 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4614567
tfarina42834112016-09-22 13:38:2014568 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114569 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14570 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614571
14572 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5214573 ASSERT_TRUE(response);
14574 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214575 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4614576 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214577 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114578 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614579 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4614580}
14581
bncd16676a2016-07-20 16:23:0114582TEST_F(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d2b5f092012-06-08 23:55:0214583 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1914584 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0914585 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0214586
bnc032658ba2016-09-26 18:17:1514587 AddSSLSocketData();
[email protected]d2b5f092012-06-08 23:55:0214588
Ryan Hamilton0239aac2018-05-19 00:03:1314589 spdy::SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4914590 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3814591 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1314592 spdy::SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3714593 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0214594 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114595 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0214596 };
Ryan Hamilton0239aac2018-05-19 00:03:1314597 spdy::SpdySerializedFrame host1_resp(
14598 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
14599 spdy::SpdySerializedFrame host1_resp_body(
bncdf80d44fd2016-07-15 20:27:4114600 spdy_util_.ConstructSpdyDataFrame(1, true));
Ryan Hamilton0239aac2018-05-19 00:03:1314601 spdy::SpdySerializedFrame host2_resp(
14602 spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
14603 spdy::SpdySerializedFrame host2_resp_body(
bncdf80d44fd2016-07-15 20:27:4114604 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0214605 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114606 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
14607 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1314608 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0214609 };
14610
eroman36d84e54432016-03-17 03:23:0214611 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0214612 MockConnect connect(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0114613 SequencedSocketData spdy_data(connect, spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0714614 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0214615
14616 TestCompletionCallback callback;
14617 HttpRequestInfo request1;
14618 request1.method = "GET";
bncce36dca22015-04-21 22:11:2314619 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0214620 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1014621 request1.traffic_annotation =
14622 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5014623 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0214624
tfarina42834112016-09-22 13:38:2014625 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114626 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14627 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214628
14629 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5214630 ASSERT_TRUE(response);
14631 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214632 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0214633
14634 std::string response_data;
robpercival214763f2016-07-01 23:27:0114635 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214636 EXPECT_EQ("hello!", response_data);
14637
14638 HttpRequestInfo request2;
14639 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3714640 request2.url = GURL("https://mail.example.com/");
[email protected]d2b5f092012-06-08 23:55:0214641 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1014642 request2.traffic_annotation =
14643 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5014644 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0214645
tfarina42834112016-09-22 13:38:2014646 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114647 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14648 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214649
14650 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5214651 ASSERT_TRUE(response);
14652 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214653 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0214654 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214655 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114656 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214657 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0214658}
14659
bnc8016c1f2017-03-31 02:11:2914660// Regression test for https://crbug.com/546991.
14661// The server might not be able to serve an IP pooled request, and might send a
14662// 421 Misdirected Request response status to indicate this.
14663// HttpNetworkTransaction should reset the request and retry without IP pooling.
14664TEST_F(HttpNetworkTransactionTest, RetryWithoutConnectionPooling) {
14665 // Two hosts resolve to the same IP address.
14666 const std::string ip_addr = "1.2.3.4";
14667 IPAddress ip;
14668 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
14669 IPEndPoint peer_addr = IPEndPoint(ip, 443);
14670
Jeremy Roman0579ed62017-08-29 15:56:1914671 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
bnc8016c1f2017-03-31 02:11:2914672 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
14673 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
14674
14675 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14676
14677 // Two requests on the first connection.
Ryan Hamilton0239aac2018-05-19 00:03:1314678 spdy::SpdySerializedFrame req1(
bnc8016c1f2017-03-31 02:11:2914679 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
14680 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1314681 spdy::SpdySerializedFrame req2(
bnc8016c1f2017-03-31 02:11:2914682 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1314683 spdy::SpdySerializedFrame rst(
14684 spdy_util_.ConstructSpdyRstStream(3, spdy::ERROR_CODE_CANCEL));
bnc8016c1f2017-03-31 02:11:2914685 MockWrite writes1[] = {
14686 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
14687 CreateMockWrite(rst, 6),
14688 };
14689
14690 // The first one succeeds, the second gets error 421 Misdirected Request.
Ryan Hamilton0239aac2018-05-19 00:03:1314691 spdy::SpdySerializedFrame resp1(
14692 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
14693 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
14694 spdy::SpdyHeaderBlock response_headers;
14695 response_headers[spdy::kHttp2StatusHeader] = "421";
14696 spdy::SpdySerializedFrame resp2(
bnc8016c1f2017-03-31 02:11:2914697 spdy_util_.ConstructSpdyReply(3, std::move(response_headers)));
14698 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
14699 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
14700
14701 MockConnect connect1(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0114702 SequencedSocketData data1(connect1, reads1, writes1);
bnc8016c1f2017-03-31 02:11:2914703 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14704
14705 AddSSLSocketData();
14706
14707 // Retry the second request on a second connection.
14708 SpdyTestUtil spdy_util2;
Ryan Hamilton0239aac2018-05-19 00:03:1314709 spdy::SpdySerializedFrame req3(
bnc8016c1f2017-03-31 02:11:2914710 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
14711 MockWrite writes2[] = {
14712 CreateMockWrite(req3, 0),
14713 };
14714
Ryan Hamilton0239aac2018-05-19 00:03:1314715 spdy::SpdySerializedFrame resp3(
14716 spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
14717 spdy::SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
bnc8016c1f2017-03-31 02:11:2914718 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
14719 MockRead(ASYNC, 0, 3)};
14720
14721 MockConnect connect2(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0114722 SequencedSocketData data2(connect2, reads2, writes2);
bnc8016c1f2017-03-31 02:11:2914723 session_deps_.socket_factory->AddSocketDataProvider(&data2);
14724
14725 AddSSLSocketData();
14726
14727 // Preload mail.example.org into HostCache.
14728 HostPortPair host_port("mail.example.org", 443);
14729 HostResolver::RequestInfo resolve_info(host_port);
14730 AddressList ignored;
14731 std::unique_ptr<HostResolver::Request> request;
14732 TestCompletionCallback callback;
14733 int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
14734 &ignored, callback.callback(),
14735 &request, NetLogWithSource());
14736 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14737 rv = callback.WaitForResult();
14738 EXPECT_THAT(rv, IsOk());
14739
14740 HttpRequestInfo request1;
14741 request1.method = "GET";
14742 request1.url = GURL("https://www.example.org/");
14743 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1014744 request1.traffic_annotation =
14745 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8016c1f2017-03-31 02:11:2914746 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
14747
14748 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
14749 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14750 rv = callback.WaitForResult();
14751 EXPECT_THAT(rv, IsOk());
14752
14753 const HttpResponseInfo* response = trans1.GetResponseInfo();
14754 ASSERT_TRUE(response);
14755 ASSERT_TRUE(response->headers);
14756 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
14757 EXPECT_TRUE(response->was_fetched_via_spdy);
14758 EXPECT_TRUE(response->was_alpn_negotiated);
14759 std::string response_data;
14760 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
14761 EXPECT_EQ("hello!", response_data);
14762
14763 HttpRequestInfo request2;
14764 request2.method = "GET";
14765 request2.url = GURL("https://mail.example.org/");
14766 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1014767 request2.traffic_annotation =
14768 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8016c1f2017-03-31 02:11:2914769 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
14770
14771 BoundTestNetLog log;
14772 rv = trans2.Start(&request2, callback.callback(), log.bound());
14773 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14774 rv = callback.WaitForResult();
14775 EXPECT_THAT(rv, IsOk());
14776
14777 response = trans2.GetResponseInfo();
14778 ASSERT_TRUE(response);
14779 ASSERT_TRUE(response->headers);
14780 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
14781 EXPECT_TRUE(response->was_fetched_via_spdy);
14782 EXPECT_TRUE(response->was_alpn_negotiated);
14783 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
14784 EXPECT_EQ("hello!", response_data);
14785
14786 TestNetLogEntry::List entries;
14787 log.GetEntries(&entries);
davidbence688ae2017-05-04 15:12:5914788 ExpectLogContainsSomewhere(
14789 entries, 0, NetLogEventType::HTTP_TRANSACTION_RESTART_MISDIRECTED_REQUEST,
bnc8016c1f2017-03-31 02:11:2914790 NetLogEventPhase::NONE);
davidbence688ae2017-05-04 15:12:5914791}
14792
14793// Test that HTTP 421 responses are properly returned to the caller if received
14794// on the retry as well. HttpNetworkTransaction should not infinite loop or lose
14795// portions of the response.
14796TEST_F(HttpNetworkTransactionTest, ReturnHTTP421OnRetry) {
14797 // Two hosts resolve to the same IP address.
14798 const std::string ip_addr = "1.2.3.4";
14799 IPAddress ip;
14800 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
14801 IPEndPoint peer_addr = IPEndPoint(ip, 443);
14802
Jeremy Roman0579ed62017-08-29 15:56:1914803 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
davidbence688ae2017-05-04 15:12:5914804 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
14805 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
14806
14807 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14808
14809 // Two requests on the first connection.
Ryan Hamilton0239aac2018-05-19 00:03:1314810 spdy::SpdySerializedFrame req1(
davidbence688ae2017-05-04 15:12:5914811 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
14812 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1314813 spdy::SpdySerializedFrame req2(
davidbence688ae2017-05-04 15:12:5914814 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1314815 spdy::SpdySerializedFrame rst(
14816 spdy_util_.ConstructSpdyRstStream(3, spdy::ERROR_CODE_CANCEL));
davidbence688ae2017-05-04 15:12:5914817 MockWrite writes1[] = {
14818 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
14819 CreateMockWrite(rst, 6),
14820 };
14821
14822 // The first one succeeds, the second gets error 421 Misdirected Request.
Ryan Hamilton0239aac2018-05-19 00:03:1314823 spdy::SpdySerializedFrame resp1(
14824 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
14825 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
14826 spdy::SpdyHeaderBlock response_headers;
14827 response_headers[spdy::kHttp2StatusHeader] = "421";
14828 spdy::SpdySerializedFrame resp2(
davidbence688ae2017-05-04 15:12:5914829 spdy_util_.ConstructSpdyReply(3, response_headers.Clone()));
14830 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
14831 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
14832
14833 MockConnect connect1(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0114834 SequencedSocketData data1(connect1, reads1, writes1);
davidbence688ae2017-05-04 15:12:5914835 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14836
14837 AddSSLSocketData();
14838
14839 // Retry the second request on a second connection. It returns 421 Misdirected
14840 // Retry again.
14841 SpdyTestUtil spdy_util2;
Ryan Hamilton0239aac2018-05-19 00:03:1314842 spdy::SpdySerializedFrame req3(
davidbence688ae2017-05-04 15:12:5914843 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
14844 MockWrite writes2[] = {
14845 CreateMockWrite(req3, 0),
14846 };
14847
Ryan Hamilton0239aac2018-05-19 00:03:1314848 spdy::SpdySerializedFrame resp3(
davidbence688ae2017-05-04 15:12:5914849 spdy_util2.ConstructSpdyReply(1, std::move(response_headers)));
Ryan Hamilton0239aac2018-05-19 00:03:1314850 spdy::SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
davidbence688ae2017-05-04 15:12:5914851 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
14852 MockRead(ASYNC, 0, 3)};
14853
14854 MockConnect connect2(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0114855 SequencedSocketData data2(connect2, reads2, writes2);
davidbence688ae2017-05-04 15:12:5914856 session_deps_.socket_factory->AddSocketDataProvider(&data2);
14857
14858 AddSSLSocketData();
14859
14860 // Preload mail.example.org into HostCache.
14861 HostPortPair host_port("mail.example.org", 443);
14862 HostResolver::RequestInfo resolve_info(host_port);
14863 AddressList ignored;
14864 std::unique_ptr<HostResolver::Request> request;
14865 TestCompletionCallback callback;
14866 int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
14867 &ignored, callback.callback(),
14868 &request, NetLogWithSource());
14869 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14870 rv = callback.WaitForResult();
14871 EXPECT_THAT(rv, IsOk());
14872
14873 HttpRequestInfo request1;
14874 request1.method = "GET";
14875 request1.url = GURL("https://www.example.org/");
14876 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1014877 request1.traffic_annotation =
14878 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
davidbence688ae2017-05-04 15:12:5914879 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
14880
14881 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
14882 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14883 rv = callback.WaitForResult();
14884 EXPECT_THAT(rv, IsOk());
14885
14886 const HttpResponseInfo* response = trans1.GetResponseInfo();
14887 ASSERT_TRUE(response);
14888 ASSERT_TRUE(response->headers);
14889 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
14890 EXPECT_TRUE(response->was_fetched_via_spdy);
14891 EXPECT_TRUE(response->was_alpn_negotiated);
14892 std::string response_data;
14893 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
14894 EXPECT_EQ("hello!", response_data);
14895
14896 HttpRequestInfo request2;
14897 request2.method = "GET";
14898 request2.url = GURL("https://mail.example.org/");
14899 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1014900 request2.traffic_annotation =
14901 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
davidbence688ae2017-05-04 15:12:5914902 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
14903
14904 BoundTestNetLog log;
14905 rv = trans2.Start(&request2, callback.callback(), log.bound());
14906 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14907 rv = callback.WaitForResult();
14908 EXPECT_THAT(rv, IsOk());
14909
14910 // After a retry, the 421 Misdirected Request is reported back up to the
14911 // caller.
14912 response = trans2.GetResponseInfo();
14913 ASSERT_TRUE(response);
14914 ASSERT_TRUE(response->headers);
14915 EXPECT_EQ("HTTP/1.1 421", response->headers->GetStatusLine());
14916 EXPECT_TRUE(response->was_fetched_via_spdy);
14917 EXPECT_TRUE(response->was_alpn_negotiated);
14918 EXPECT_TRUE(response->ssl_info.cert);
14919 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
14920 EXPECT_EQ("hello!", response_data);
bnc8016c1f2017-03-31 02:11:2914921}
14922
bnc6dcd8192017-05-25 20:11:5014923class OneTimeCachingHostResolver : public MockHostResolverBase {
[email protected]e3ceb682011-06-28 23:55:4614924 public:
14925 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
bnc6dcd8192017-05-25 20:11:5014926 : MockHostResolverBase(/* use_caching = */ true), host_port_(host_port) {}
Chris Watkins7a41d3552017-12-01 02:13:2714927 ~OneTimeCachingHostResolver() override = default;
[email protected]e3ceb682011-06-28 23:55:4614928
dchengb03027d2014-10-21 12:00:2014929 int ResolveFromCache(const RequestInfo& info,
14930 AddressList* addresses,
tfarina42834112016-09-22 13:38:2014931 const NetLogWithSource& net_log) override {
bnc6dcd8192017-05-25 20:11:5014932 int rv = MockHostResolverBase::ResolveFromCache(info, addresses, net_log);
[email protected]95a214c2011-08-04 21:50:4014933 if (rv == OK && info.host_port_pair().Equals(host_port_))
bnc6dcd8192017-05-25 20:11:5014934 GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4614935 return rv;
14936 }
14937
[email protected]e3ceb682011-06-28 23:55:4614938 private:
[email protected]e3ceb682011-06-28 23:55:4614939 const HostPortPair host_port_;
14940};
14941
bncd16676a2016-07-20 16:23:0114942TEST_F(HttpNetworkTransactionTest,
mmenke5c642132015-06-02 16:05:1314943 UseIPConnectionPoolingWithHostCacheExpiration) {
[email protected]e3ceb682011-06-28 23:55:4614944 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1914945 session_deps_.host_resolver = std::make_unique<OneTimeCachingHostResolver>(
bnca4d611d2016-09-22 19:55:3714946 HostPortPair("mail.example.com", 443));
danakj1fd259a02016-04-16 03:17:0914947 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4614948
bnc032658ba2016-09-26 18:17:1514949 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4614950
Ryan Hamilton0239aac2018-05-19 00:03:1314951 spdy::SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4914952 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3814953 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1314954 spdy::SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3714955 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4614956 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114957 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4614958 };
Ryan Hamilton0239aac2018-05-19 00:03:1314959 spdy::SpdySerializedFrame host1_resp(
14960 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
14961 spdy::SpdySerializedFrame host1_resp_body(
bncdf80d44fd2016-07-15 20:27:4114962 spdy_util_.ConstructSpdyDataFrame(1, true));
Ryan Hamilton0239aac2018-05-19 00:03:1314963 spdy::SpdySerializedFrame host2_resp(
14964 spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
14965 spdy::SpdySerializedFrame host2_resp_body(
bncdf80d44fd2016-07-15 20:27:4114966 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4614967 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114968 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
14969 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1314970 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4614971 };
14972
eroman36d84e54432016-03-17 03:23:0214973 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0214974 MockConnect connect(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0114975 SequencedSocketData spdy_data(connect, spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0714976 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4614977
[email protected]aa22b242011-11-16 18:58:2914978 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4614979 HttpRequestInfo request1;
14980 request1.method = "GET";
bncce36dca22015-04-21 22:11:2314981 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4614982 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1014983 request1.traffic_annotation =
14984 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5014985 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4614986
tfarina42834112016-09-22 13:38:2014987 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114988 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14989 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614990
14991 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5214992 ASSERT_TRUE(response);
14993 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214994 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4614995
14996 std::string response_data;
robpercival214763f2016-07-01 23:27:0114997 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614998 EXPECT_EQ("hello!", response_data);
14999
15000 // Preload cache entries into HostCache.
bnca4d611d2016-09-22 19:55:3715001 HostResolver::RequestInfo resolve_info(HostPortPair("mail.example.com", 443));
[email protected]e3ceb682011-06-28 23:55:4615002 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1015003 std::unique_ptr<HostResolver::Request> request;
bnc6dcd8192017-05-25 20:11:5015004 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
15005 &ignored, callback.callback(),
15006 &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115007 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4715008 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115009 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4615010
15011 HttpRequestInfo request2;
15012 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3715013 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4615014 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015015 request2.traffic_annotation =
15016 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015017 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4615018
tfarina42834112016-09-22 13:38:2015019 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115020 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15021 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615022
15023 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215024 ASSERT_TRUE(response);
15025 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215026 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4615027 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215028 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115029 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615030 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4615031}
15032
bncd16676a2016-07-20 16:23:0115033TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2315034 const std::string https_url = "https://www.example.org:8080/";
15035 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0415036
15037 // SPDY GET for HTTPS URL
Ryan Hamilton0239aac2018-05-19 00:03:1315038 spdy::SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4915039 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0415040
15041 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4115042 CreateMockWrite(req1, 0),
[email protected]8450d722012-07-02 19:14:0415043 };
15044
Ryan Hamilton0239aac2018-05-19 00:03:1315045 spdy::SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
15046 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
bncdf80d44fd2016-07-15 20:27:4115047 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
mmenkee24011922015-12-17 22:12:5915048 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)};
[email protected]8450d722012-07-02 19:14:0415049
Ryan Sleevib8d7ea02018-05-07 20:01:0115050 SequencedSocketData data1(reads1, writes1);
[email protected]8450d722012-07-02 19:14:0415051 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5715052 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0415053
15054 // HTTP GET for the HTTP URL
15055 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1315056 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3415057 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2315058 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3415059 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0415060 };
15061
15062 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1315063 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
15064 MockRead(ASYNC, 2, "hello"),
15065 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0415066 };
15067
Ryan Sleevib8d7ea02018-05-07 20:01:0115068 SequencedSocketData data2(reads2, writes2);
[email protected]8450d722012-07-02 19:14:0415069
[email protected]8450d722012-07-02 19:14:0415070 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615071 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0715072 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15073 session_deps_.socket_factory->AddSocketDataProvider(&data1);
15074 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0415075
danakj1fd259a02016-04-16 03:17:0915076 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0415077
15078 // Start the first transaction to set up the SpdySession
15079 HttpRequestInfo request1;
15080 request1.method = "GET";
15081 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0415082 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015083 request1.traffic_annotation =
15084 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015085 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0415086 TestCompletionCallback callback1;
15087 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015088 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5515089 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0415090
robpercival214763f2016-07-01 23:27:0115091 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0415092 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
15093
15094 // Now, start the HTTP request
15095 HttpRequestInfo request2;
15096 request2.method = "GET";
15097 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0415098 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015099 request2.traffic_annotation =
15100 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015101 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0415102 TestCompletionCallback callback2;
15103 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015104 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5515105 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0415106
robpercival214763f2016-07-01 23:27:0115107 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0415108 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
15109}
15110
bnc5452e2a2015-05-08 16:27:4215111// Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
15112// with the alternative server. That connection should not be used.
bncd16676a2016-07-20 16:23:0115113TEST_F(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
bnc8bef8da22016-05-30 01:28:2515114 url::SchemeHostPort server("https", "www.example.org", 443);
15115 HostPortPair alternative("www.example.org", 444);
bnc5452e2a2015-05-08 16:27:4215116
bnc8bef8da22016-05-30 01:28:2515117 // Negotiate HTTP/1.1 with alternative.
bnc5452e2a2015-05-08 16:27:4215118 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615119 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4215120 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15121
15122 // No data should be read from the alternative, because HTTP/1.1 is
15123 // negotiated.
15124 StaticSocketDataProvider data;
15125 session_deps_.socket_factory->AddSocketDataProvider(&data);
15126
15127 // This test documents that an alternate Job should not be used if HTTP/1.1 is
zhongyi3d4a55e72016-04-22 20:36:4615128 // negotiated. In order to test this, a failed connection to the server is
bnc5452e2a2015-05-08 16:27:4215129 // mocked. This way the request relies on the alternate Job.
15130 StaticSocketDataProvider data_refused;
15131 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
15132 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
15133
zhongyi3d4a55e72016-04-22 20:36:4615134 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0915135 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4015136 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4215137 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2115138 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1215139 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2115140 http_server_properties->SetHttp2AlternativeService(
15141 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4215142
bnc5452e2a2015-05-08 16:27:4215143 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4615144 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4215145 request.method = "GET";
bnc8bef8da22016-05-30 01:28:2515146 request.url = GURL("https://www.example.org:443");
Ramin Halavatib5e433e62018-02-07 07:41:1015147 request.traffic_annotation =
15148 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4215149 TestCompletionCallback callback;
15150
15151 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
bnc94c92842016-09-21 15:22:5215152 // negotiated, the alternate Job should fail with ERR_ALPN_NEGOTIATION_FAILED.
tfarina42834112016-09-22 13:38:2015153 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc94c92842016-09-21 15:22:5215154 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_ALPN_NEGOTIATION_FAILED));
bnc5452e2a2015-05-08 16:27:4215155}
15156
bnc40448a532015-05-11 19:13:1415157// A request to a server with an alternative service fires two Jobs: one to the
zhongyi3d4a55e72016-04-22 20:36:4615158// server, and an alternate one to the alternative server. If the former
bnc40448a532015-05-11 19:13:1415159// succeeds, the request should succeed, even if the latter fails because
15160// HTTP/1.1 is negotiated which is insufficient for alternative service.
bncd16676a2016-07-20 16:23:0115161TEST_F(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
bnc8bef8da22016-05-30 01:28:2515162 url::SchemeHostPort server("https", "www.example.org", 443);
15163 HostPortPair alternative("www.example.org", 444);
bnc40448a532015-05-11 19:13:1415164
15165 // Negotiate HTTP/1.1 with alternative.
15166 SSLSocketDataProvider alternative_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615167 alternative_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1415168 session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
15169
15170 // No data should be read from the alternative, because HTTP/1.1 is
15171 // negotiated.
15172 StaticSocketDataProvider data;
15173 session_deps_.socket_factory->AddSocketDataProvider(&data);
15174
zhongyi3d4a55e72016-04-22 20:36:4615175 // Negotiate HTTP/1.1 with server.
bnc40448a532015-05-11 19:13:1415176 SSLSocketDataProvider origin_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615177 origin_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1415178 session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
15179
15180 MockWrite http_writes[] = {
bnc8bef8da22016-05-30 01:28:2515181 MockWrite("GET / HTTP/1.1\r\n"
15182 "Host: www.example.org\r\n"
15183 "Connection: keep-alive\r\n\r\n"),
15184 MockWrite("GET /second HTTP/1.1\r\n"
15185 "Host: www.example.org\r\n"
15186 "Connection: keep-alive\r\n\r\n"),
bnc40448a532015-05-11 19:13:1415187 };
15188
15189 MockRead http_reads[] = {
15190 MockRead("HTTP/1.1 200 OK\r\n"),
15191 MockRead("Content-Type: text/html\r\n"),
15192 MockRead("Content-Length: 6\r\n\r\n"),
15193 MockRead("foobar"),
15194 MockRead("HTTP/1.1 200 OK\r\n"),
15195 MockRead("Content-Type: text/html\r\n"),
15196 MockRead("Content-Length: 7\r\n\r\n"),
15197 MockRead("another"),
15198 };
Ryan Sleevib8d7ea02018-05-07 20:01:0115199 StaticSocketDataProvider http_data(http_reads, http_writes);
bnc40448a532015-05-11 19:13:1415200 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15201
zhongyi3d4a55e72016-04-22 20:36:4615202 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0915203 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4015204 HttpServerProperties* http_server_properties =
bnc40448a532015-05-11 19:13:1415205 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2115206 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1215207 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2115208 http_server_properties->SetHttp2AlternativeService(
15209 server, alternative_service, expiration);
bnc40448a532015-05-11 19:13:1415210
15211 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
15212 HttpRequestInfo request1;
15213 request1.method = "GET";
bnc8bef8da22016-05-30 01:28:2515214 request1.url = GURL("https://www.example.org:443");
bnc40448a532015-05-11 19:13:1415215 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015216 request1.traffic_annotation =
15217 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc40448a532015-05-11 19:13:1415218 TestCompletionCallback callback1;
15219
tfarina42834112016-09-22 13:38:2015220 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1415221 rv = callback1.GetResult(rv);
robpercival214763f2016-07-01 23:27:0115222 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1415223
15224 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5215225 ASSERT_TRUE(response1);
15226 ASSERT_TRUE(response1->headers);
bnc40448a532015-05-11 19:13:1415227 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
15228
15229 std::string response_data1;
robpercival214763f2016-07-01 23:27:0115230 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc40448a532015-05-11 19:13:1415231 EXPECT_EQ("foobar", response_data1);
15232
15233 // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
15234 // for alternative service.
15235 EXPECT_TRUE(
15236 http_server_properties->IsAlternativeServiceBroken(alternative_service));
15237
zhongyi3d4a55e72016-04-22 20:36:4615238 // Since |alternative_service| is broken, a second transaction to server
bnc40448a532015-05-11 19:13:1415239 // should not start an alternate Job. It should pool to existing connection
zhongyi3d4a55e72016-04-22 20:36:4615240 // to server.
bnc40448a532015-05-11 19:13:1415241 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
15242 HttpRequestInfo request2;
15243 request2.method = "GET";
bnc8bef8da22016-05-30 01:28:2515244 request2.url = GURL("https://www.example.org:443/second");
bnc40448a532015-05-11 19:13:1415245 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015246 request2.traffic_annotation =
15247 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc40448a532015-05-11 19:13:1415248 TestCompletionCallback callback2;
15249
tfarina42834112016-09-22 13:38:2015250 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1415251 rv = callback2.GetResult(rv);
robpercival214763f2016-07-01 23:27:0115252 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1415253
15254 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215255 ASSERT_TRUE(response2);
15256 ASSERT_TRUE(response2->headers);
bnc40448a532015-05-11 19:13:1415257 EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
15258
15259 std::string response_data2;
robpercival214763f2016-07-01 23:27:0115260 ASSERT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
bnc40448a532015-05-11 19:13:1415261 EXPECT_EQ("another", response_data2);
15262}
15263
bnc5452e2a2015-05-08 16:27:4215264// Alternative service requires HTTP/2 (or SPDY), but there is already a
15265// HTTP/1.1 socket open to the alternative server. That socket should not be
15266// used.
bncd16676a2016-07-20 16:23:0115267TEST_F(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
zhongyi3d4a55e72016-04-22 20:36:4615268 url::SchemeHostPort server("https", "origin.example.org", 443);
bnc5452e2a2015-05-08 16:27:4215269 HostPortPair alternative("alternative.example.org", 443);
15270 std::string origin_url = "https://origin.example.org:443";
15271 std::string alternative_url = "https://alternative.example.org:443";
15272
15273 // Negotiate HTTP/1.1 with alternative.example.org.
15274 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615275 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4215276 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15277
15278 // HTTP/1.1 data for |request1| and |request2|.
15279 MockWrite http_writes[] = {
15280 MockWrite(
15281 "GET / HTTP/1.1\r\n"
15282 "Host: alternative.example.org\r\n"
15283 "Connection: keep-alive\r\n\r\n"),
15284 MockWrite(
15285 "GET / HTTP/1.1\r\n"
15286 "Host: alternative.example.org\r\n"
15287 "Connection: keep-alive\r\n\r\n"),
15288 };
15289
15290 MockRead http_reads[] = {
15291 MockRead(
15292 "HTTP/1.1 200 OK\r\n"
15293 "Content-Type: text/html; charset=iso-8859-1\r\n"
15294 "Content-Length: 40\r\n\r\n"
15295 "first HTTP/1.1 response from alternative"),
15296 MockRead(
15297 "HTTP/1.1 200 OK\r\n"
15298 "Content-Type: text/html; charset=iso-8859-1\r\n"
15299 "Content-Length: 41\r\n\r\n"
15300 "second HTTP/1.1 response from alternative"),
15301 };
Ryan Sleevib8d7ea02018-05-07 20:01:0115302 StaticSocketDataProvider http_data(http_reads, http_writes);
bnc5452e2a2015-05-08 16:27:4215303 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15304
15305 // This test documents that an alternate Job should not pool to an already
15306 // existing HTTP/1.1 connection. In order to test this, a failed connection
zhongyi3d4a55e72016-04-22 20:36:4615307 // to the server is mocked. This way |request2| relies on the alternate Job.
bnc5452e2a2015-05-08 16:27:4215308 StaticSocketDataProvider data_refused;
15309 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
15310 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
15311
zhongyi3d4a55e72016-04-22 20:36:4615312 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0915313 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4015314 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4215315 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2115316 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1215317 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2115318 http_server_properties->SetHttp2AlternativeService(
15319 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4215320
15321 // First transaction to alternative to open an HTTP/1.1 socket.
bnc5452e2a2015-05-08 16:27:4215322 HttpRequestInfo request1;
krasinc06a72a2016-12-21 03:42:4615323 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4215324 request1.method = "GET";
15325 request1.url = GURL(alternative_url);
15326 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015327 request1.traffic_annotation =
15328 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4215329 TestCompletionCallback callback1;
15330
tfarina42834112016-09-22 13:38:2015331 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115332 EXPECT_THAT(callback1.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1615333 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4215334 ASSERT_TRUE(response1);
wezca1070932016-05-26 20:30:5215335 ASSERT_TRUE(response1->headers);
bnc5452e2a2015-05-08 16:27:4215336 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5215337 EXPECT_TRUE(response1->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4215338 EXPECT_FALSE(response1->was_fetched_via_spdy);
15339 std::string response_data1;
bnc691fda62016-08-12 00:43:1615340 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc5452e2a2015-05-08 16:27:4215341 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
15342
15343 // Request for origin.example.org, which has an alternative service. This
15344 // will start two Jobs: the alternative looks for connections to pool to,
15345 // finds one which is HTTP/1.1, and should ignore it, and should not try to
zhongyi3d4a55e72016-04-22 20:36:4615346 // open other connections to alternative server. The Job to server fails, so
bnc5452e2a2015-05-08 16:27:4215347 // this request fails.
bnc5452e2a2015-05-08 16:27:4215348 HttpRequestInfo request2;
krasinc06a72a2016-12-21 03:42:4615349 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4215350 request2.method = "GET";
15351 request2.url = GURL(origin_url);
15352 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015353 request2.traffic_annotation =
15354 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4215355 TestCompletionCallback callback2;
15356
tfarina42834112016-09-22 13:38:2015357 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115358 EXPECT_THAT(callback2.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc5452e2a2015-05-08 16:27:4215359
15360 // Another transaction to alternative. This is to test that the HTTP/1.1
15361 // socket is still open and in the pool.
bnc5452e2a2015-05-08 16:27:4215362 HttpRequestInfo request3;
krasinc06a72a2016-12-21 03:42:4615363 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4215364 request3.method = "GET";
15365 request3.url = GURL(alternative_url);
15366 request3.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015367 request3.traffic_annotation =
15368 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4215369 TestCompletionCallback callback3;
15370
tfarina42834112016-09-22 13:38:2015371 rv = trans3.Start(&request3, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115372 EXPECT_THAT(callback3.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1615373 const HttpResponseInfo* response3 = trans3.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4215374 ASSERT_TRUE(response3);
wezca1070932016-05-26 20:30:5215375 ASSERT_TRUE(response3->headers);
bnc5452e2a2015-05-08 16:27:4215376 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5215377 EXPECT_TRUE(response3->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4215378 EXPECT_FALSE(response3->was_fetched_via_spdy);
15379 std::string response_data3;
bnc691fda62016-08-12 00:43:1615380 ASSERT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
bnc5452e2a2015-05-08 16:27:4215381 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
15382}
15383
bncd16676a2016-07-20 16:23:0115384TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2315385 const std::string https_url = "https://www.example.org:8080/";
15386 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0415387
rdsmithebb50aa2015-11-12 03:44:3815388 // Separate SPDY util instance for naked and wrapped requests.
bncd16676a2016-07-20 16:23:0115389 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:3815390
[email protected]8450d722012-07-02 19:14:0415391 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2315392 const HostPortPair host_port_pair("www.example.org", 8080);
Ryan Hamilton0239aac2018-05-19 00:03:1315393 spdy::SpdySerializedFrame connect(
lgarrona91df87f2014-12-05 00:51:3415394 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
Ryan Hamilton0239aac2018-05-19 00:03:1315395 spdy::SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4915396 spdy_util_wrapped.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1315397 spdy::SpdySerializedFrame wrapped_req1(
[email protected]23e482282013-06-14 16:08:0215398 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3915399
15400 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
Ryan Hamilton0239aac2018-05-19 00:03:1315401 spdy::SpdyHeaderBlock req2_block;
15402 req2_block[spdy::kHttp2MethodHeader] = "GET";
15403 req2_block[spdy::kHttp2AuthorityHeader] = "www.example.org:8080";
15404 req2_block[spdy::kHttp2SchemeHeader] = "http";
15405 req2_block[spdy::kHttp2PathHeader] = "/";
15406 spdy::SpdySerializedFrame req2(
bnc42331402016-07-25 13:36:1515407 spdy_util_.ConstructSpdyHeaders(3, std::move(req2_block), MEDIUM, true));
[email protected]8450d722012-07-02 19:14:0415408
15409 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4115410 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_req1, 2),
15411 CreateMockWrite(req2, 6),
[email protected]8450d722012-07-02 19:14:0415412 };
15413
Ryan Hamilton0239aac2018-05-19 00:03:1315414 spdy::SpdySerializedFrame conn_resp(
bnc42331402016-07-25 13:36:1515415 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1315416 spdy::SpdySerializedFrame resp1(
bnc42331402016-07-25 13:36:1515417 spdy_util_wrapped.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1315418 spdy::SpdySerializedFrame body1(
15419 spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
15420 spdy::SpdySerializedFrame wrapped_resp1(
rdsmithebb50aa2015-11-12 03:44:3815421 spdy_util_wrapped.ConstructWrappedSpdyFrame(resp1, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1315422 spdy::SpdySerializedFrame wrapped_body1(
rdsmithebb50aa2015-11-12 03:44:3815423 spdy_util_wrapped.ConstructWrappedSpdyFrame(body1, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1315424 spdy::SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
15425 spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
mmenke666a6fea2015-12-19 04:16:3315426 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4115427 CreateMockRead(conn_resp, 1),
mmenke666a6fea2015-12-19 04:16:3315428 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:4115429 CreateMockRead(wrapped_resp1, 4),
15430 CreateMockRead(wrapped_body1, 5),
mmenke666a6fea2015-12-19 04:16:3315431 MockRead(ASYNC, ERR_IO_PENDING, 7),
bncdf80d44fd2016-07-15 20:27:4115432 CreateMockRead(resp2, 8),
15433 CreateMockRead(body2, 9),
mmenke666a6fea2015-12-19 04:16:3315434 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 10),
15435 };
[email protected]8450d722012-07-02 19:14:0415436
Ryan Sleevib8d7ea02018-05-07 20:01:0115437 SequencedSocketData data1(reads1, writes1);
[email protected]8450d722012-07-02 19:14:0415438 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5715439 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0415440
Lily Houghton8c2f97d2018-01-22 05:06:5915441 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4915442 ProxyResolutionService::CreateFixedFromPacResult(
15443 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5115444 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0715445 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0415446 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3615447 ssl1.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3315448 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0415449 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3615450 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3315451 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15452 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0415453
danakj1fd259a02016-04-16 03:17:0915454 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]8450d722012-07-02 19:14:0415455
15456 // Start the first transaction to set up the SpdySession
15457 HttpRequestInfo request1;
15458 request1.method = "GET";
15459 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0415460 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015461 request1.traffic_annotation =
15462 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015463 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0415464 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:2015465 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0415466
mmenke666a6fea2015-12-19 04:16:3315467 // This pause is a hack to avoid running into https://crbug.com/497228.
15468 data1.RunUntilPaused();
15469 base::RunLoop().RunUntilIdle();
15470 data1.Resume();
robpercival214763f2016-07-01 23:27:0115471 EXPECT_THAT(callback1.GetResult(rv), IsOk());
[email protected]8450d722012-07-02 19:14:0415472 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
15473
[email protected]f6c63db52013-02-02 00:35:2215474 LoadTimingInfo load_timing_info1;
15475 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
15476 TestLoadTimingNotReusedWithPac(load_timing_info1,
15477 CONNECT_TIMING_HAS_SSL_TIMES);
15478
mmenke666a6fea2015-12-19 04:16:3315479 // Now, start the HTTP request.
[email protected]8450d722012-07-02 19:14:0415480 HttpRequestInfo request2;
15481 request2.method = "GET";
15482 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0415483 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015484 request2.traffic_annotation =
15485 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015486 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0415487 TestCompletionCallback callback2;
tfarina42834112016-09-22 13:38:2015488 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0415489
mmenke666a6fea2015-12-19 04:16:3315490 // This pause is a hack to avoid running into https://crbug.com/497228.
15491 data1.RunUntilPaused();
15492 base::RunLoop().RunUntilIdle();
15493 data1.Resume();
robpercival214763f2016-07-01 23:27:0115494 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenke666a6fea2015-12-19 04:16:3315495
[email protected]8450d722012-07-02 19:14:0415496 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2215497
15498 LoadTimingInfo load_timing_info2;
15499 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
15500 // The established SPDY sessions is considered reused by the HTTP request.
15501 TestLoadTimingReusedWithPac(load_timing_info2);
15502 // HTTP requests over a SPDY session should have a different connection
15503 // socket_log_id than requests over a tunnel.
15504 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0415505}
15506
[email protected]2d88e7d2012-07-19 17:55:1715507// Test that in the case where we have a SPDY session to a SPDY proxy
15508// that we do not pool other origins that resolve to the same IP when
15509// the certificate does not match the new origin.
15510// http://crbug.com/134690
bncd16676a2016-07-20 16:23:0115511TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2315512 const std::string url1 = "http://www.example.org/";
15513 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1715514 const std::string ip_addr = "1.2.3.4";
15515
rdsmithebb50aa2015-11-12 03:44:3815516 // Second SpdyTestUtil instance for the second socket.
bncd16676a2016-07-20 16:23:0115517 SpdyTestUtil spdy_util_secure;
rdsmithebb50aa2015-11-12 03:44:3815518
[email protected]2d88e7d2012-07-19 17:55:1715519 // SPDY GET for HTTP URL (through SPDY proxy)
Ryan Hamilton0239aac2018-05-19 00:03:1315520 spdy::SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:2315521 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
Ryan Hamilton0239aac2018-05-19 00:03:1315522 spdy::SpdySerializedFrame req1(
bnc42331402016-07-25 13:36:1515523 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
[email protected]2d88e7d2012-07-19 17:55:1715524
15525 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4115526 CreateMockWrite(req1, 0),
[email protected]2d88e7d2012-07-19 17:55:1715527 };
15528
Ryan Hamilton0239aac2018-05-19 00:03:1315529 spdy::SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
15530 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1715531 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4115532 MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(resp1, 2),
15533 CreateMockRead(body1, 3), MockRead(ASYNC, OK, 4), // EOF
[email protected]2d88e7d2012-07-19 17:55:1715534 };
15535
Ryan Sleevib8d7ea02018-05-07 20:01:0115536 SequencedSocketData data1(reads1, writes1);
martijnfe9636e2016-02-06 14:33:3215537 IPAddress ip;
martijn654c8c42016-02-10 22:10:5915538 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
[email protected]2d88e7d2012-07-19 17:55:1715539 IPEndPoint peer_addr = IPEndPoint(ip, 443);
15540 MockConnect connect_data1(ASYNC, OK, peer_addr);
mmenke666a6fea2015-12-19 04:16:3315541 data1.set_connect_data(connect_data1);
[email protected]2d88e7d2012-07-19 17:55:1715542
15543 // SPDY GET for HTTPS URL (direct)
Ryan Hamilton0239aac2018-05-19 00:03:1315544 spdy::SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4915545 spdy_util_secure.ConstructSpdyGet(url2.c_str(), 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1715546
15547 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4115548 CreateMockWrite(req2, 0),
[email protected]2d88e7d2012-07-19 17:55:1715549 };
15550
Ryan Hamilton0239aac2018-05-19 00:03:1315551 spdy::SpdySerializedFrame resp2(
15552 spdy_util_secure.ConstructSpdyGetReply(NULL, 0, 1));
15553 spdy::SpdySerializedFrame body2(
15554 spdy_util_secure.ConstructSpdyDataFrame(1, true));
bncdf80d44fd2016-07-15 20:27:4115555 MockRead reads2[] = {CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
mmenke666a6fea2015-12-19 04:16:3315556 MockRead(ASYNC, OK, 3)};
[email protected]2d88e7d2012-07-19 17:55:1715557
Ryan Sleevib8d7ea02018-05-07 20:01:0115558 SequencedSocketData data2(reads2, writes2);
[email protected]2d88e7d2012-07-19 17:55:1715559 MockConnect connect_data2(ASYNC, OK);
mmenke666a6fea2015-12-19 04:16:3315560 data2.set_connect_data(connect_data2);
[email protected]2d88e7d2012-07-19 17:55:1715561
15562 // Set up a proxy config that sends HTTP requests to a proxy, and
15563 // all others direct.
15564 ProxyConfig proxy_config;
15565 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
Ramin Halavatica8d5252018-03-12 05:33:4915566 session_deps_.proxy_resolution_service =
15567 std::make_unique<ProxyResolutionService>(
15568 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
15569 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
15570 nullptr, nullptr);
[email protected]2d88e7d2012-07-19 17:55:1715571
bncce36dca22015-04-21 22:11:2315572 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3615573 ssl1.next_proto = kProtoHTTP2;
[email protected]2d88e7d2012-07-19 17:55:1715574 // Load a valid cert. Note, that this does not need to
15575 // be valid for proxy because the MockSSLClientSocket does
15576 // not actually verify it. But SpdySession will use this
15577 // to see if it is valid for the new origin
Ryan Sleevi4f832092017-11-21 23:25:4915578 ssl1.ssl_info.cert =
15579 ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
15580 ASSERT_TRUE(ssl1.ssl_info.cert);
mmenke666a6fea2015-12-19 04:16:3315581 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
15582 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d88e7d2012-07-19 17:55:1715583
15584 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3615585 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3315586 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15587 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d88e7d2012-07-19 17:55:1715588
Jeremy Roman0579ed62017-08-29 15:56:1915589 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
bncce36dca22015-04-21 22:11:2315590 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0715591 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1715592
danakj1fd259a02016-04-16 03:17:0915593 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]2d88e7d2012-07-19 17:55:1715594
15595 // Start the first transaction to set up the SpdySession
15596 HttpRequestInfo request1;
15597 request1.method = "GET";
15598 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1715599 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015600 request1.traffic_annotation =
15601 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015602 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1715603 TestCompletionCallback callback1;
15604 ASSERT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015605 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
mmenke666a6fea2015-12-19 04:16:3315606 // This pause is a hack to avoid running into https://crbug.com/497228.
15607 data1.RunUntilPaused();
15608 base::RunLoop().RunUntilIdle();
15609 data1.Resume();
[email protected]2d88e7d2012-07-19 17:55:1715610
robpercival214763f2016-07-01 23:27:0115611 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1715612 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
15613
15614 // Now, start the HTTP request
15615 HttpRequestInfo request2;
15616 request2.method = "GET";
15617 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1715618 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015619 request2.traffic_annotation =
15620 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015621 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1715622 TestCompletionCallback callback2;
15623 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015624 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5515625 base::RunLoop().RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1715626
15627 ASSERT_TRUE(callback2.have_result());
robpercival214763f2016-07-01 23:27:0115628 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1715629 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
15630}
15631
[email protected]85f97342013-04-17 06:12:2415632// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
15633// error) in SPDY session, removes the socket from pool and closes the SPDY
15634// session. Verify that new url's from the same HttpNetworkSession (and a new
15635// SpdySession) do work. http://crbug.com/224701
bncd16676a2016-07-20 16:23:0115636TEST_F(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2315637 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2415638
15639 MockRead reads1[] = {
15640 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
15641 };
15642
Ryan Sleevib8d7ea02018-05-07 20:01:0115643 SequencedSocketData data1(reads1, base::span<MockWrite>());
[email protected]85f97342013-04-17 06:12:2415644
Ryan Hamilton0239aac2018-05-19 00:03:1315645 spdy::SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4915646 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2415647 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4115648 CreateMockWrite(req2, 0),
[email protected]85f97342013-04-17 06:12:2415649 };
15650
Ryan Hamilton0239aac2018-05-19 00:03:1315651 spdy::SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
15652 spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]85f97342013-04-17 06:12:2415653 MockRead reads2[] = {
bncdf80d44fd2016-07-15 20:27:4115654 CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
15655 MockRead(ASYNC, OK, 3) // EOF
[email protected]85f97342013-04-17 06:12:2415656 };
15657
Ryan Sleevib8d7ea02018-05-07 20:01:0115658 SequencedSocketData data2(reads2, writes2);
[email protected]85f97342013-04-17 06:12:2415659
[email protected]85f97342013-04-17 06:12:2415660 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615661 ssl1.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5015662 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
15663 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]85f97342013-04-17 06:12:2415664
15665 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615666 ssl2.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5015667 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15668 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]85f97342013-04-17 06:12:2415669
danakj1fd259a02016-04-16 03:17:0915670 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:5015671 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]85f97342013-04-17 06:12:2415672
15673 // Start the first transaction to set up the SpdySession and verify that
15674 // connection was closed.
15675 HttpRequestInfo request1;
15676 request1.method = "GET";
15677 request1.url = GURL(https_url);
15678 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015679 request1.traffic_annotation =
15680 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015681 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2415682 TestCompletionCallback callback1;
15683 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015684 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0115685 EXPECT_THAT(callback1.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]85f97342013-04-17 06:12:2415686
15687 // Now, start the second request and make sure it succeeds.
15688 HttpRequestInfo request2;
15689 request2.method = "GET";
15690 request2.url = GURL(https_url);
15691 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015692 request2.traffic_annotation =
15693 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015694 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2415695 TestCompletionCallback callback2;
15696 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015697 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
[email protected]85f97342013-04-17 06:12:2415698
robpercival214763f2016-07-01 23:27:0115699 ASSERT_THAT(callback2.WaitForResult(), IsOk());
[email protected]85f97342013-04-17 06:12:2415700 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
15701}
15702
bncd16676a2016-07-20 16:23:0115703TEST_F(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]483fa202013-05-14 01:07:0315704 ClientSocketPoolManager::set_max_sockets_per_group(
15705 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15706 ClientSocketPoolManager::set_max_sockets_per_pool(
15707 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15708
15709 // Use two different hosts with different IPs so they don't get pooled.
15710 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
15711 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
danakj1fd259a02016-04-16 03:17:0915712 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]483fa202013-05-14 01:07:0315713
15714 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615715 ssl1.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0315716 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615717 ssl2.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0315718 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
15719 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15720
Ryan Hamilton0239aac2018-05-19 00:03:1315721 spdy::SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4915722 spdy_util_.ConstructSpdyGet("https://www.a.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0315723 MockWrite spdy1_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115724 CreateMockWrite(host1_req, 0),
[email protected]483fa202013-05-14 01:07:0315725 };
Ryan Hamilton0239aac2018-05-19 00:03:1315726 spdy::SpdySerializedFrame host1_resp(
15727 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
15728 spdy::SpdySerializedFrame host1_resp_body(
bncdf80d44fd2016-07-15 20:27:4115729 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0315730 MockRead spdy1_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115731 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
mmenkee24011922015-12-17 22:12:5915732 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0315733 };
15734
rdsmithebb50aa2015-11-12 03:44:3815735 // Use a separate test instance for the separate SpdySession that will be
15736 // created.
bncd16676a2016-07-20 16:23:0115737 SpdyTestUtil spdy_util_2;
Ryan Sleevib8d7ea02018-05-07 20:01:0115738 SequencedSocketData spdy1_data(spdy1_reads, spdy1_writes);
Bence Béky53a5aef2018-03-29 21:54:1215739 session_deps_.socket_factory->AddSocketDataProvider(&spdy1_data);
[email protected]483fa202013-05-14 01:07:0315740
Ryan Hamilton0239aac2018-05-19 00:03:1315741 spdy::SpdySerializedFrame host2_req(
bnc38dcd392016-02-09 23:19:4915742 spdy_util_2.ConstructSpdyGet("https://www.b.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0315743 MockWrite spdy2_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115744 CreateMockWrite(host2_req, 0),
[email protected]483fa202013-05-14 01:07:0315745 };
Ryan Hamilton0239aac2018-05-19 00:03:1315746 spdy::SpdySerializedFrame host2_resp(
15747 spdy_util_2.ConstructSpdyGetReply(NULL, 0, 1));
15748 spdy::SpdySerializedFrame host2_resp_body(
bncdf80d44fd2016-07-15 20:27:4115749 spdy_util_2.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0315750 MockRead spdy2_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115751 CreateMockRead(host2_resp, 1), CreateMockRead(host2_resp_body, 2),
mmenkee24011922015-12-17 22:12:5915752 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0315753 };
15754
Ryan Sleevib8d7ea02018-05-07 20:01:0115755 SequencedSocketData spdy2_data(spdy2_reads, spdy2_writes);
Bence Béky53a5aef2018-03-29 21:54:1215756 session_deps_.socket_factory->AddSocketDataProvider(&spdy2_data);
[email protected]483fa202013-05-14 01:07:0315757
15758 MockWrite http_write[] = {
15759 MockWrite("GET / HTTP/1.1\r\n"
15760 "Host: www.a.com\r\n"
15761 "Connection: keep-alive\r\n\r\n"),
15762 };
15763
15764 MockRead http_read[] = {
15765 MockRead("HTTP/1.1 200 OK\r\n"),
15766 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
15767 MockRead("Content-Length: 6\r\n\r\n"),
15768 MockRead("hello!"),
15769 };
Ryan Sleevib8d7ea02018-05-07 20:01:0115770 StaticSocketDataProvider http_data(http_read, http_write);
[email protected]483fa202013-05-14 01:07:0315771 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15772
15773 HostPortPair host_port_pair_a("www.a.com", 443);
Paul Jensena457017a2018-01-19 23:52:0415774 SpdySessionKey spdy_session_key_a(host_port_pair_a, ProxyServer::Direct(),
15775 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]483fa202013-05-14 01:07:0315776 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615777 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315778
15779 TestCompletionCallback callback;
15780 HttpRequestInfo request1;
15781 request1.method = "GET";
15782 request1.url = GURL("https://www.a.com/");
15783 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015784 request1.traffic_annotation =
15785 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5815786 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1915787 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0315788
tfarina42834112016-09-22 13:38:2015789 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115790 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15791 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0315792
15793 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215794 ASSERT_TRUE(response);
15795 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215796 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0315797 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215798 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]483fa202013-05-14 01:07:0315799
15800 std::string response_data;
robpercival214763f2016-07-01 23:27:0115801 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0315802 EXPECT_EQ("hello!", response_data);
15803 trans.reset();
15804 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2615805 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315806
15807 HostPortPair host_port_pair_b("www.b.com", 443);
Paul Jensena457017a2018-01-19 23:52:0415808 SpdySessionKey spdy_session_key_b(host_port_pair_b, ProxyServer::Direct(),
15809 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]483fa202013-05-14 01:07:0315810 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615811 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0315812 HttpRequestInfo request2;
15813 request2.method = "GET";
15814 request2.url = GURL("https://www.b.com/");
15815 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015816 request2.traffic_annotation =
15817 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5815818 trans =
Jeremy Roman0579ed62017-08-29 15:56:1915819 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0315820
tfarina42834112016-09-22 13:38:2015821 rv = trans->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115822 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15823 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0315824
15825 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215826 ASSERT_TRUE(response);
15827 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215828 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0315829 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215830 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115831 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0315832 EXPECT_EQ("hello!", response_data);
15833 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615834 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315835 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2615836 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0315837
15838 HostPortPair host_port_pair_a1("www.a.com", 80);
Paul Jensena457017a2018-01-19 23:52:0415839 SpdySessionKey spdy_session_key_a1(host_port_pair_a1, ProxyServer::Direct(),
15840 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]483fa202013-05-14 01:07:0315841 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615842 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0315843 HttpRequestInfo request3;
15844 request3.method = "GET";
15845 request3.url = GURL("http://www.a.com/");
15846 request3.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015847 request3.traffic_annotation =
15848 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5815849 trans =
Jeremy Roman0579ed62017-08-29 15:56:1915850 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0315851
tfarina42834112016-09-22 13:38:2015852 rv = trans->Start(&request3, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115853 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15854 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0315855
15856 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215857 ASSERT_TRUE(response);
15858 ASSERT_TRUE(response->headers);
[email protected]483fa202013-05-14 01:07:0315859 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
15860 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215861 EXPECT_FALSE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115862 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0315863 EXPECT_EQ("hello!", response_data);
15864 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615865 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315866 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615867 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0315868}
15869
bncd16676a2016-07-20 16:23:0115870TEST_F(HttpNetworkTransactionTest, HttpSyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0415871 HttpRequestInfo request;
15872 request.method = "GET";
bncce36dca22015-04-21 22:11:2315873 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1015874 request.traffic_annotation =
15875 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0415876
danakj1fd259a02016-04-16 03:17:0915877 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615878 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415879
ttuttled9dbc652015-09-29 20:00:5915880 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0415881 StaticSocketDataProvider data;
15882 data.set_connect_data(mock_connect);
15883 session_deps_.socket_factory->AddSocketDataProvider(&data);
15884
15885 TestCompletionCallback callback;
15886
tfarina42834112016-09-22 13:38:2015887 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115888 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415889
15890 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115891 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0415892
[email protected]79e1fd62013-06-20 06:50:0415893 // We don't care whether this succeeds or fails, but it shouldn't crash.
15894 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615895 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4715896
15897 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1615898 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4715899 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0115900 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5915901
15902 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1615903 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5915904 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0415905}
15906
bncd16676a2016-07-20 16:23:0115907TEST_F(HttpNetworkTransactionTest, HttpAsyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0415908 HttpRequestInfo request;
15909 request.method = "GET";
bncce36dca22015-04-21 22:11:2315910 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1015911 request.traffic_annotation =
15912 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0415913
danakj1fd259a02016-04-16 03:17:0915914 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615915 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415916
ttuttled9dbc652015-09-29 20:00:5915917 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0415918 StaticSocketDataProvider data;
15919 data.set_connect_data(mock_connect);
15920 session_deps_.socket_factory->AddSocketDataProvider(&data);
15921
15922 TestCompletionCallback callback;
15923
tfarina42834112016-09-22 13:38:2015924 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115925 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415926
15927 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115928 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0415929
[email protected]79e1fd62013-06-20 06:50:0415930 // We don't care whether this succeeds or fails, but it shouldn't crash.
15931 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615932 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4715933
15934 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1615935 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4715936 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0115937 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5915938
15939 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1615940 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5915941 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0415942}
15943
bncd16676a2016-07-20 16:23:0115944TEST_F(HttpNetworkTransactionTest, HttpSyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0415945 HttpRequestInfo request;
15946 request.method = "GET";
bncce36dca22015-04-21 22:11:2315947 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1015948 request.traffic_annotation =
15949 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0415950
danakj1fd259a02016-04-16 03:17:0915951 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615952 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415953
15954 MockWrite data_writes[] = {
15955 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15956 };
15957 MockRead data_reads[] = {
15958 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
15959 };
15960
Ryan Sleevib8d7ea02018-05-07 20:01:0115961 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0415962 session_deps_.socket_factory->AddSocketDataProvider(&data);
15963
15964 TestCompletionCallback callback;
15965
tfarina42834112016-09-22 13:38:2015966 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115967 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415968
15969 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115970 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0415971
[email protected]79e1fd62013-06-20 06:50:0415972 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615973 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0415974 EXPECT_TRUE(request_headers.HasHeader("Host"));
15975}
15976
bncd16676a2016-07-20 16:23:0115977TEST_F(HttpNetworkTransactionTest, HttpAsyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0415978 HttpRequestInfo request;
15979 request.method = "GET";
bncce36dca22015-04-21 22:11:2315980 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1015981 request.traffic_annotation =
15982 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0415983
danakj1fd259a02016-04-16 03:17:0915984 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615985 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415986
15987 MockWrite data_writes[] = {
15988 MockWrite(ASYNC, ERR_CONNECTION_RESET),
15989 };
15990 MockRead data_reads[] = {
15991 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
15992 };
15993
Ryan Sleevib8d7ea02018-05-07 20:01:0115994 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0415995 session_deps_.socket_factory->AddSocketDataProvider(&data);
15996
15997 TestCompletionCallback callback;
15998
tfarina42834112016-09-22 13:38:2015999 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116000 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416001
16002 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116003 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416004
[email protected]79e1fd62013-06-20 06:50:0416005 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616006 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416007 EXPECT_TRUE(request_headers.HasHeader("Host"));
16008}
16009
bncd16676a2016-07-20 16:23:0116010TEST_F(HttpNetworkTransactionTest, HttpSyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0416011 HttpRequestInfo request;
16012 request.method = "GET";
bncce36dca22015-04-21 22:11:2316013 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016014 request.traffic_annotation =
16015 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416016
danakj1fd259a02016-04-16 03:17:0916017 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616018 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416019
16020 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2316021 MockWrite(
16022 "GET / HTTP/1.1\r\n"
16023 "Host: www.example.org\r\n"
16024 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0416025 };
16026 MockRead data_reads[] = {
16027 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
16028 };
16029
Ryan Sleevib8d7ea02018-05-07 20:01:0116030 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0416031 session_deps_.socket_factory->AddSocketDataProvider(&data);
16032
16033 TestCompletionCallback callback;
16034
tfarina42834112016-09-22 13:38:2016035 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116036 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416037
16038 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116039 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416040
[email protected]79e1fd62013-06-20 06:50:0416041 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616042 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416043 EXPECT_TRUE(request_headers.HasHeader("Host"));
16044}
16045
bncd16676a2016-07-20 16:23:0116046TEST_F(HttpNetworkTransactionTest, HttpAsyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0416047 HttpRequestInfo request;
16048 request.method = "GET";
bncce36dca22015-04-21 22:11:2316049 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016050 request.traffic_annotation =
16051 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416052
danakj1fd259a02016-04-16 03:17:0916053 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616054 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416055
16056 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2316057 MockWrite(
16058 "GET / HTTP/1.1\r\n"
16059 "Host: www.example.org\r\n"
16060 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0416061 };
16062 MockRead data_reads[] = {
16063 MockRead(ASYNC, ERR_CONNECTION_RESET),
16064 };
16065
Ryan Sleevib8d7ea02018-05-07 20:01:0116066 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0416067 session_deps_.socket_factory->AddSocketDataProvider(&data);
16068
16069 TestCompletionCallback callback;
16070
tfarina42834112016-09-22 13:38:2016071 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116072 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416073
16074 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116075 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416076
[email protected]79e1fd62013-06-20 06:50:0416077 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616078 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416079 EXPECT_TRUE(request_headers.HasHeader("Host"));
16080}
16081
bncd16676a2016-07-20 16:23:0116082TEST_F(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
[email protected]79e1fd62013-06-20 06:50:0416083 HttpRequestInfo request;
16084 request.method = "GET";
bncce36dca22015-04-21 22:11:2316085 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0416086 request.extra_headers.SetHeader("X-Foo", "bar");
Ramin Halavatib5e433e62018-02-07 07:41:1016087 request.traffic_annotation =
16088 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416089
danakj1fd259a02016-04-16 03:17:0916090 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616091 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416092
16093 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2316094 MockWrite(
16095 "GET / HTTP/1.1\r\n"
16096 "Host: www.example.org\r\n"
16097 "Connection: keep-alive\r\n"
16098 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0416099 };
16100 MockRead data_reads[] = {
16101 MockRead("HTTP/1.1 200 OK\r\n"
16102 "Content-Length: 5\r\n\r\n"
16103 "hello"),
16104 MockRead(ASYNC, ERR_UNEXPECTED),
16105 };
16106
Ryan Sleevib8d7ea02018-05-07 20:01:0116107 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0416108 session_deps_.socket_factory->AddSocketDataProvider(&data);
16109
16110 TestCompletionCallback callback;
16111
tfarina42834112016-09-22 13:38:2016112 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116113 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416114
16115 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116116 EXPECT_THAT(rv, IsOk());
[email protected]79e1fd62013-06-20 06:50:0416117
16118 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616119 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416120 std::string foo;
16121 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
16122 EXPECT_EQ("bar", foo);
16123}
16124
[email protected]043b68c82013-08-22 23:41:5216125// Tests that when a used socket is returned to the SSL socket pool, it's closed
16126// if the transport socket pool is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0116127TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
[email protected]043b68c82013-08-22 23:41:5216128 ClientSocketPoolManager::set_max_sockets_per_group(
16129 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16130 ClientSocketPoolManager::set_max_sockets_per_pool(
16131 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16132
16133 // Set up SSL request.
16134
16135 HttpRequestInfo ssl_request;
16136 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2316137 ssl_request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016138 ssl_request.traffic_annotation =
16139 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5216140
16141 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2316142 MockWrite(
16143 "GET / HTTP/1.1\r\n"
16144 "Host: www.example.org\r\n"
16145 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5216146 };
16147 MockRead ssl_reads[] = {
16148 MockRead("HTTP/1.1 200 OK\r\n"),
16149 MockRead("Content-Length: 11\r\n\r\n"),
16150 MockRead("hello world"),
16151 MockRead(SYNCHRONOUS, OK),
16152 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116153 StaticSocketDataProvider ssl_data(ssl_reads, ssl_writes);
[email protected]043b68c82013-08-22 23:41:5216154 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
16155
16156 SSLSocketDataProvider ssl(ASYNC, OK);
16157 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16158
16159 // Set up HTTP request.
16160
16161 HttpRequestInfo http_request;
16162 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2316163 http_request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016164 http_request.traffic_annotation =
16165 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5216166
16167 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2316168 MockWrite(
16169 "GET / HTTP/1.1\r\n"
16170 "Host: www.example.org\r\n"
16171 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5216172 };
16173 MockRead http_reads[] = {
16174 MockRead("HTTP/1.1 200 OK\r\n"),
16175 MockRead("Content-Length: 7\r\n\r\n"),
16176 MockRead("falafel"),
16177 MockRead(SYNCHRONOUS, OK),
16178 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116179 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]043b68c82013-08-22 23:41:5216180 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16181
danakj1fd259a02016-04-16 03:17:0916182 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5216183
16184 // Start the SSL request.
16185 TestCompletionCallback ssl_callback;
bnc691fda62016-08-12 00:43:1616186 HttpNetworkTransaction ssl_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016187 ASSERT_EQ(ERR_IO_PENDING,
16188 ssl_trans.Start(&ssl_request, ssl_callback.callback(),
16189 NetLogWithSource()));
[email protected]043b68c82013-08-22 23:41:5216190
16191 // Start the HTTP request. Pool should stall.
16192 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1616193 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016194 ASSERT_EQ(ERR_IO_PENDING,
16195 http_trans.Start(&http_request, http_callback.callback(),
16196 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4116197 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5216198
16199 // Wait for response from SSL request.
robpercival214763f2016-07-01 23:27:0116200 ASSERT_THAT(ssl_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5216201 std::string response_data;
bnc691fda62016-08-12 00:43:1616202 ASSERT_THAT(ReadTransaction(&ssl_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5216203 EXPECT_EQ("hello world", response_data);
16204
16205 // The SSL socket should automatically be closed, so the HTTP request can
16206 // start.
dcheng48459ac22014-08-26 00:46:4116207 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
16208 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5216209
16210 // The HTTP request can now complete.
robpercival214763f2016-07-01 23:27:0116211 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
bnc691fda62016-08-12 00:43:1616212 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5216213 EXPECT_EQ("falafel", response_data);
16214
dcheng48459ac22014-08-26 00:46:4116215 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5216216}
16217
16218// Tests that when a SSL connection is established but there's no corresponding
16219// request that needs it, the new socket is closed if the transport socket pool
16220// is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0116221TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
[email protected]043b68c82013-08-22 23:41:5216222 ClientSocketPoolManager::set_max_sockets_per_group(
16223 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16224 ClientSocketPoolManager::set_max_sockets_per_pool(
16225 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16226
16227 // Set up an ssl request.
16228
16229 HttpRequestInfo ssl_request;
16230 ssl_request.method = "GET";
16231 ssl_request.url = GURL("https://www.foopy.com/");
Ramin Halavatib5e433e62018-02-07 07:41:1016232 ssl_request.traffic_annotation =
16233 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5216234
16235 // No data will be sent on the SSL socket.
16236 StaticSocketDataProvider ssl_data;
16237 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
16238
16239 SSLSocketDataProvider ssl(ASYNC, OK);
16240 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16241
16242 // Set up HTTP request.
16243
16244 HttpRequestInfo http_request;
16245 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2316246 http_request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016247 http_request.traffic_annotation =
16248 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5216249
16250 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2316251 MockWrite(
16252 "GET / HTTP/1.1\r\n"
16253 "Host: www.example.org\r\n"
16254 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5216255 };
16256 MockRead http_reads[] = {
16257 MockRead("HTTP/1.1 200 OK\r\n"),
16258 MockRead("Content-Length: 7\r\n\r\n"),
16259 MockRead("falafel"),
16260 MockRead(SYNCHRONOUS, OK),
16261 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116262 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]043b68c82013-08-22 23:41:5216263 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16264
danakj1fd259a02016-04-16 03:17:0916265 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5216266
16267 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
16268 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2916269 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
nharper8cdb0fb2016-04-22 21:34:5916270 http_stream_factory->PreconnectStreams(1, ssl_request);
dcheng48459ac22014-08-26 00:46:4116271 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5216272
16273 // Start the HTTP request. Pool should stall.
16274 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1616275 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016276 ASSERT_EQ(ERR_IO_PENDING,
16277 http_trans.Start(&http_request, http_callback.callback(),
16278 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4116279 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5216280
16281 // The SSL connection will automatically be closed once the connection is
16282 // established, to let the HTTP request start.
robpercival214763f2016-07-01 23:27:0116283 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5216284 std::string response_data;
bnc691fda62016-08-12 00:43:1616285 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5216286 EXPECT_EQ("falafel", response_data);
16287
dcheng48459ac22014-08-26 00:46:4116288 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5216289}
16290
bncd16676a2016-07-20 16:23:0116291TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0916292 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216293 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916294 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216295 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416296
16297 HttpRequestInfo request;
16298 request.method = "POST";
16299 request.url = GURL("http://www.foo.com/");
16300 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1016301 request.traffic_annotation =
16302 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416303
danakj1fd259a02016-04-16 03:17:0916304 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616305 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416306 // Send headers successfully, but get an error while sending the body.
16307 MockWrite data_writes[] = {
16308 MockWrite("POST / HTTP/1.1\r\n"
16309 "Host: www.foo.com\r\n"
16310 "Connection: keep-alive\r\n"
16311 "Content-Length: 3\r\n\r\n"),
16312 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16313 };
16314
16315 MockRead data_reads[] = {
16316 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16317 MockRead("hello world"),
16318 MockRead(SYNCHRONOUS, OK),
16319 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116320 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5416321 session_deps_.socket_factory->AddSocketDataProvider(&data);
16322
16323 TestCompletionCallback callback;
16324
tfarina42834112016-09-22 13:38:2016325 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116326 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416327
16328 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116329 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416330
bnc691fda62016-08-12 00:43:1616331 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216332 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416333
wezca1070932016-05-26 20:30:5216334 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416335 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16336
16337 std::string response_data;
bnc691fda62016-08-12 00:43:1616338 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116339 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416340 EXPECT_EQ("hello world", response_data);
16341}
16342
16343// This test makes sure the retry logic doesn't trigger when reading an error
16344// response from a server that rejected a POST with a CONNECTION_RESET.
bncd16676a2016-07-20 16:23:0116345TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5416346 PostReadsErrorResponseAfterResetOnReusedSocket) {
danakj1fd259a02016-04-16 03:17:0916347 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5416348 MockWrite data_writes[] = {
16349 MockWrite("GET / HTTP/1.1\r\n"
16350 "Host: www.foo.com\r\n"
16351 "Connection: keep-alive\r\n\r\n"),
16352 MockWrite("POST / HTTP/1.1\r\n"
16353 "Host: www.foo.com\r\n"
16354 "Connection: keep-alive\r\n"
16355 "Content-Length: 3\r\n\r\n"),
16356 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16357 };
16358
16359 MockRead data_reads[] = {
16360 MockRead("HTTP/1.1 200 Peachy\r\n"
16361 "Content-Length: 14\r\n\r\n"),
16362 MockRead("first response"),
16363 MockRead("HTTP/1.1 400 Not OK\r\n"
16364 "Content-Length: 15\r\n\r\n"),
16365 MockRead("second response"),
16366 MockRead(SYNCHRONOUS, OK),
16367 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116368 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5416369 session_deps_.socket_factory->AddSocketDataProvider(&data);
16370
16371 TestCompletionCallback callback;
16372 HttpRequestInfo request1;
16373 request1.method = "GET";
16374 request1.url = GURL("http://www.foo.com/");
16375 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016376 request1.traffic_annotation =
16377 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416378
bnc87dcefc2017-05-25 12:47:5816379 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:1916380 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016381 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116382 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416383
16384 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116385 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416386
16387 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:5216388 ASSERT_TRUE(response1);
[email protected]02d74a02014-04-23 18:10:5416389
wezca1070932016-05-26 20:30:5216390 EXPECT_TRUE(response1->headers);
[email protected]02d74a02014-04-23 18:10:5416391 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
16392
16393 std::string response_data1;
16394 rv = ReadTransaction(trans1.get(), &response_data1);
robpercival214763f2016-07-01 23:27:0116395 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416396 EXPECT_EQ("first response", response_data1);
16397 // Delete the transaction to release the socket back into the socket pool.
16398 trans1.reset();
16399
danakj1fd259a02016-04-16 03:17:0916400 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216401 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916402 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216403 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416404
16405 HttpRequestInfo request2;
16406 request2.method = "POST";
16407 request2.url = GURL("http://www.foo.com/");
16408 request2.upload_data_stream = &upload_data_stream;
16409 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016410 request2.traffic_annotation =
16411 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416412
bnc691fda62016-08-12 00:43:1616413 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016414 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116415 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416416
16417 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116418 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416419
bnc691fda62016-08-12 00:43:1616420 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5216421 ASSERT_TRUE(response2);
[email protected]02d74a02014-04-23 18:10:5416422
wezca1070932016-05-26 20:30:5216423 EXPECT_TRUE(response2->headers);
[email protected]02d74a02014-04-23 18:10:5416424 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
16425
16426 std::string response_data2;
bnc691fda62016-08-12 00:43:1616427 rv = ReadTransaction(&trans2, &response_data2);
robpercival214763f2016-07-01 23:27:0116428 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416429 EXPECT_EQ("second response", response_data2);
16430}
16431
bncd16676a2016-07-20 16:23:0116432TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5416433 PostReadsErrorResponseAfterResetPartialBodySent) {
danakj1fd259a02016-04-16 03:17:0916434 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216435 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916436 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216437 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416438
16439 HttpRequestInfo request;
16440 request.method = "POST";
16441 request.url = GURL("http://www.foo.com/");
16442 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1016443 request.traffic_annotation =
16444 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416445
danakj1fd259a02016-04-16 03:17:0916446 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616447 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416448 // Send headers successfully, but get an error while sending the body.
16449 MockWrite data_writes[] = {
16450 MockWrite("POST / HTTP/1.1\r\n"
16451 "Host: www.foo.com\r\n"
16452 "Connection: keep-alive\r\n"
16453 "Content-Length: 3\r\n\r\n"
16454 "fo"),
16455 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16456 };
16457
16458 MockRead data_reads[] = {
16459 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16460 MockRead("hello world"),
16461 MockRead(SYNCHRONOUS, OK),
16462 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116463 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5416464 session_deps_.socket_factory->AddSocketDataProvider(&data);
16465
16466 TestCompletionCallback callback;
16467
tfarina42834112016-09-22 13:38:2016468 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116469 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416470
16471 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116472 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416473
bnc691fda62016-08-12 00:43:1616474 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216475 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416476
wezca1070932016-05-26 20:30:5216477 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416478 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16479
16480 std::string response_data;
bnc691fda62016-08-12 00:43:1616481 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116482 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416483 EXPECT_EQ("hello world", response_data);
16484}
16485
16486// This tests the more common case than the previous test, where headers and
16487// body are not merged into a single request.
bncd16676a2016-07-20 16:23:0116488TEST_F(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
mmenkecbc2b712014-10-09 20:29:0716489 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5416490
16491 HttpRequestInfo request;
16492 request.method = "POST";
16493 request.url = GURL("http://www.foo.com/");
16494 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1016495 request.traffic_annotation =
16496 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416497
danakj1fd259a02016-04-16 03:17:0916498 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616499 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416500 // Send headers successfully, but get an error while sending the body.
16501 MockWrite data_writes[] = {
16502 MockWrite("POST / HTTP/1.1\r\n"
16503 "Host: www.foo.com\r\n"
16504 "Connection: keep-alive\r\n"
16505 "Transfer-Encoding: chunked\r\n\r\n"),
16506 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16507 };
16508
16509 MockRead data_reads[] = {
16510 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16511 MockRead("hello world"),
16512 MockRead(SYNCHRONOUS, OK),
16513 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116514 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5416515 session_deps_.socket_factory->AddSocketDataProvider(&data);
16516
16517 TestCompletionCallback callback;
16518
tfarina42834112016-09-22 13:38:2016519 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116520 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416521 // Make sure the headers are sent before adding a chunk. This ensures that
16522 // they can't be merged with the body in a single send. Not currently
16523 // necessary since a chunked body is never merged with headers, but this makes
16524 // the test more future proof.
16525 base::RunLoop().RunUntilIdle();
16526
mmenkecbc2b712014-10-09 20:29:0716527 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5416528
16529 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116530 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416531
bnc691fda62016-08-12 00:43:1616532 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216533 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416534
wezca1070932016-05-26 20:30:5216535 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416536 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16537
16538 std::string response_data;
bnc691fda62016-08-12 00:43:1616539 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116540 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416541 EXPECT_EQ("hello world", response_data);
16542}
16543
bncd16676a2016-07-20 16:23:0116544TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0916545 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216546 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916547 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216548 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416549
16550 HttpRequestInfo request;
16551 request.method = "POST";
16552 request.url = GURL("http://www.foo.com/");
16553 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1016554 request.traffic_annotation =
16555 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416556
danakj1fd259a02016-04-16 03:17:0916557 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616558 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416559
16560 MockWrite data_writes[] = {
16561 MockWrite("POST / HTTP/1.1\r\n"
16562 "Host: www.foo.com\r\n"
16563 "Connection: keep-alive\r\n"
16564 "Content-Length: 3\r\n\r\n"),
16565 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16566 };
16567
16568 MockRead data_reads[] = {
16569 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
16570 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16571 MockRead("hello world"),
16572 MockRead(SYNCHRONOUS, OK),
16573 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116574 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5416575 session_deps_.socket_factory->AddSocketDataProvider(&data);
16576
16577 TestCompletionCallback callback;
16578
tfarina42834112016-09-22 13:38:2016579 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116580 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416581
16582 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116583 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416584
bnc691fda62016-08-12 00:43:1616585 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216586 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416587
wezca1070932016-05-26 20:30:5216588 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416589 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16590
16591 std::string response_data;
bnc691fda62016-08-12 00:43:1616592 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116593 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416594 EXPECT_EQ("hello world", response_data);
16595}
16596
bncd16676a2016-07-20 16:23:0116597TEST_F(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0916598 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216599 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916600 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216601 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416602
16603 HttpRequestInfo request;
16604 request.method = "POST";
16605 request.url = GURL("http://www.foo.com/");
16606 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1016607 request.traffic_annotation =
16608 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416609
danakj1fd259a02016-04-16 03:17:0916610 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616611 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416612 // Send headers successfully, but get an error while sending the body.
16613 MockWrite data_writes[] = {
16614 MockWrite("POST / HTTP/1.1\r\n"
16615 "Host: www.foo.com\r\n"
16616 "Connection: keep-alive\r\n"
16617 "Content-Length: 3\r\n\r\n"),
16618 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16619 };
16620
16621 MockRead data_reads[] = {
16622 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
16623 MockRead("hello world"),
16624 MockRead(SYNCHRONOUS, OK),
16625 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116626 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5416627 session_deps_.socket_factory->AddSocketDataProvider(&data);
16628
16629 TestCompletionCallback callback;
16630
tfarina42834112016-09-22 13:38:2016631 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116632 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416633
16634 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116635 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416636}
16637
bncd16676a2016-07-20 16:23:0116638TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5416639 PostIgnoresNonErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0916640 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216641 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916642 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216643 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416644
16645 HttpRequestInfo request;
16646 request.method = "POST";
16647 request.url = GURL("http://www.foo.com/");
16648 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1016649 request.traffic_annotation =
16650 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416651
danakj1fd259a02016-04-16 03:17:0916652 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616653 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416654 // Send headers successfully, but get an error while sending the body.
16655 MockWrite data_writes[] = {
16656 MockWrite("POST / HTTP/1.1\r\n"
16657 "Host: www.foo.com\r\n"
16658 "Connection: keep-alive\r\n"
16659 "Content-Length: 3\r\n\r\n"),
16660 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16661 };
16662
16663 MockRead data_reads[] = {
16664 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
16665 MockRead("HTTP/1.0 302 Redirect\r\n"),
16666 MockRead("Location: http://somewhere-else.com/\r\n"),
16667 MockRead("Content-Length: 0\r\n\r\n"),
16668 MockRead(SYNCHRONOUS, OK),
16669 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116670 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5416671 session_deps_.socket_factory->AddSocketDataProvider(&data);
16672
16673 TestCompletionCallback callback;
16674
tfarina42834112016-09-22 13:38:2016675 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116676 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416677
16678 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116679 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416680}
16681
bncd16676a2016-07-20 16:23:0116682TEST_F(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0916683 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216684 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916685 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216686 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416687
16688 HttpRequestInfo request;
16689 request.method = "POST";
16690 request.url = GURL("http://www.foo.com/");
16691 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1016692 request.traffic_annotation =
16693 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416694
danakj1fd259a02016-04-16 03:17:0916695 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616696 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416697 // Send headers successfully, but get an error while sending the body.
16698 MockWrite data_writes[] = {
16699 MockWrite("POST / HTTP/1.1\r\n"
16700 "Host: www.foo.com\r\n"
16701 "Connection: keep-alive\r\n"
16702 "Content-Length: 3\r\n\r\n"),
16703 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16704 };
16705
16706 MockRead data_reads[] = {
16707 MockRead("HTTP 0.9 rocks!"),
16708 MockRead(SYNCHRONOUS, OK),
16709 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116710 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5416711 session_deps_.socket_factory->AddSocketDataProvider(&data);
16712
16713 TestCompletionCallback callback;
16714
tfarina42834112016-09-22 13:38:2016715 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116716 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416717
16718 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116719 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416720}
16721
bncd16676a2016-07-20 16:23:0116722TEST_F(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
danakj1fd259a02016-04-16 03:17:0916723 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216724 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916725 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216726 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416727
16728 HttpRequestInfo request;
16729 request.method = "POST";
16730 request.url = GURL("http://www.foo.com/");
16731 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1016732 request.traffic_annotation =
16733 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416734
danakj1fd259a02016-04-16 03:17:0916735 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616736 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416737 // Send headers successfully, but get an error while sending the body.
16738 MockWrite data_writes[] = {
16739 MockWrite("POST / HTTP/1.1\r\n"
16740 "Host: www.foo.com\r\n"
16741 "Connection: keep-alive\r\n"
16742 "Content-Length: 3\r\n\r\n"),
16743 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16744 };
16745
16746 MockRead data_reads[] = {
16747 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
16748 MockRead(SYNCHRONOUS, OK),
16749 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116750 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5416751 session_deps_.socket_factory->AddSocketDataProvider(&data);
16752
16753 TestCompletionCallback callback;
16754
tfarina42834112016-09-22 13:38:2016755 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116756 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416757
16758 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116759 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416760}
16761
Bence Békydca6bd92018-01-30 13:43:0616762#if BUILDFLAG(ENABLE_WEBSOCKETS)
16763
16764namespace {
16765
16766void AddWebSocketHeaders(HttpRequestHeaders* headers) {
16767 headers->SetHeader("Connection", "Upgrade");
16768 headers->SetHeader("Upgrade", "websocket");
16769 headers->SetHeader("Origin", "http://www.example.org");
16770 headers->SetHeader("Sec-WebSocket-Version", "13");
Bence Békydca6bd92018-01-30 13:43:0616771}
16772
16773} // namespace
16774
16775TEST_F(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
Bence Béky2fcf4fa2018-04-06 20:06:0116776 for (bool secure : {true, false}) {
16777 MockWrite data_writes[] = {
16778 MockWrite("GET / HTTP/1.1\r\n"
16779 "Host: www.example.org\r\n"
16780 "Connection: Upgrade\r\n"
16781 "Upgrade: websocket\r\n"
16782 "Origin: http://www.example.org\r\n"
16783 "Sec-WebSocket-Version: 13\r\n"
16784 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
16785 "Sec-WebSocket-Extensions: permessage-deflate; "
16786 "client_max_window_bits\r\n\r\n")};
16787
16788 MockRead data_reads[] = {
16789 MockRead("HTTP/1.1 101 Switching Protocols\r\n"
16790 "Upgrade: websocket\r\n"
16791 "Connection: Upgrade\r\n"
16792 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
16793
Ryan Sleevib8d7ea02018-05-07 20:01:0116794 StaticSocketDataProvider data(data_reads, data_writes);
Bence Béky2fcf4fa2018-04-06 20:06:0116795 session_deps_.socket_factory->AddSocketDataProvider(&data);
16796 SSLSocketDataProvider ssl(ASYNC, OK);
16797 if (secure)
16798 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
Bence Békydca6bd92018-01-30 13:43:0616799
16800 HttpRequestInfo request;
16801 request.method = "GET";
Bence Béky2fcf4fa2018-04-06 20:06:0116802 request.url =
16803 GURL(secure ? "ws://www.example.org/" : "wss://www.example.org/");
16804 AddWebSocketHeaders(&request.extra_headers);
Ramin Halavatib5e433e62018-02-07 07:41:1016805 request.traffic_annotation =
16806 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Békydca6bd92018-01-30 13:43:0616807
Bence Béky2fcf4fa2018-04-06 20:06:0116808 TestWebSocketHandshakeStreamCreateHelper
16809 websocket_handshake_stream_create_helper;
Bence Béky8d1c6052018-02-07 12:48:1516810
Bence Béky2fcf4fa2018-04-06 20:06:0116811 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Bence Békydca6bd92018-01-30 13:43:0616812 HttpNetworkTransaction trans(LOW, session.get());
16813 trans.SetWebSocketHandshakeStreamCreateHelper(
Bence Béky2fcf4fa2018-04-06 20:06:0116814 &websocket_handshake_stream_create_helper);
Bence Békydca6bd92018-01-30 13:43:0616815
16816 TestCompletionCallback callback;
Bence Béky2fcf4fa2018-04-06 20:06:0116817 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
16818 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Bence Békydca6bd92018-01-30 13:43:0616819
Bence Béky2fcf4fa2018-04-06 20:06:0116820 const HttpStreamRequest* stream_request = trans.stream_request_.get();
16821 ASSERT_TRUE(stream_request);
16822 EXPECT_EQ(&websocket_handshake_stream_create_helper,
16823 stream_request->websocket_handshake_stream_create_helper());
16824
16825 rv = callback.WaitForResult();
16826 EXPECT_THAT(rv, IsOk());
16827
16828 EXPECT_TRUE(data.AllReadDataConsumed());
16829 EXPECT_TRUE(data.AllWriteDataConsumed());
Bence Békydca6bd92018-01-30 13:43:0616830 }
16831}
16832
Adam Rice425cf122015-01-19 06:18:2416833// Verify that proxy headers are not sent to the destination server when
16834// establishing a tunnel for a secure WebSocket connection.
bncd16676a2016-07-20 16:23:0116835TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
Adam Rice425cf122015-01-19 06:18:2416836 HttpRequestInfo request;
16837 request.method = "GET";
bncce36dca22015-04-21 22:11:2316838 request.url = GURL("wss://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016839 request.traffic_annotation =
16840 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2416841 AddWebSocketHeaders(&request.extra_headers);
16842
16843 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:5916844 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4916845 ProxyResolutionService::CreateFixedFromPacResult(
16846 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2416847
danakj1fd259a02016-04-16 03:17:0916848 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2416849
16850 // Since a proxy is configured, try to establish a tunnel.
16851 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1716852 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
16853 "Host: www.example.org:443\r\n"
16854 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416855
16856 // After calling trans->RestartWithAuth(), this is the request we should
16857 // be issuing -- the final header line contains the credentials.
rsleevidb16bb02015-11-12 23:47:1716858 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
16859 "Host: www.example.org:443\r\n"
16860 "Proxy-Connection: keep-alive\r\n"
16861 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416862
rsleevidb16bb02015-11-12 23:47:1716863 MockWrite("GET / HTTP/1.1\r\n"
16864 "Host: www.example.org\r\n"
16865 "Connection: Upgrade\r\n"
16866 "Upgrade: websocket\r\n"
16867 "Origin: http://www.example.org\r\n"
16868 "Sec-WebSocket-Version: 13\r\n"
Bence Béky8d1c6052018-02-07 12:48:1516869 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
16870 "Sec-WebSocket-Extensions: permessage-deflate; "
16871 "client_max_window_bits\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2416872
16873 // The proxy responds to the connect with a 407, using a persistent
16874 // connection.
16875 MockRead data_reads[] = {
16876 // No credentials.
Bence Béky8d1c6052018-02-07 12:48:1516877 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"
16878 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
16879 "Content-Length: 0\r\n"
16880 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416881
16882 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
16883
Bence Béky8d1c6052018-02-07 12:48:1516884 MockRead("HTTP/1.1 101 Switching Protocols\r\n"
16885 "Upgrade: websocket\r\n"
16886 "Connection: Upgrade\r\n"
16887 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2416888
Ryan Sleevib8d7ea02018-05-07 20:01:0116889 StaticSocketDataProvider data(data_reads, data_writes);
Adam Rice425cf122015-01-19 06:18:2416890 session_deps_.socket_factory->AddSocketDataProvider(&data);
16891 SSLSocketDataProvider ssl(ASYNC, OK);
16892 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16893
Bence Béky8d1c6052018-02-07 12:48:1516894 TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
16895
bnc87dcefc2017-05-25 12:47:5816896 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1916897 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2416898 trans->SetWebSocketHandshakeStreamCreateHelper(
16899 &websocket_stream_create_helper);
16900
16901 {
16902 TestCompletionCallback callback;
16903
tfarina42834112016-09-22 13:38:2016904 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116905 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2416906
16907 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116908 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2416909 }
16910
16911 const HttpResponseInfo* response = trans->GetResponseInfo();
16912 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5216913 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2416914 EXPECT_EQ(407, response->headers->response_code());
16915
16916 {
16917 TestCompletionCallback callback;
16918
16919 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
16920 callback.callback());
robpercival214763f2016-07-01 23:27:0116921 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2416922
16923 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116924 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2416925 }
16926
16927 response = trans->GetResponseInfo();
16928 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5216929 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2416930
16931 EXPECT_EQ(101, response->headers->response_code());
16932
16933 trans.reset();
16934 session->CloseAllConnections();
16935}
16936
16937// Verify that proxy headers are not sent to the destination server when
16938// establishing a tunnel for an insecure WebSocket connection.
16939// This requires the authentication info to be injected into the auth cache
16940// due to crbug.com/395064
16941// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
bncd16676a2016-07-20 16:23:0116942TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
Adam Rice425cf122015-01-19 06:18:2416943 HttpRequestInfo request;
16944 request.method = "GET";
bncce36dca22015-04-21 22:11:2316945 request.url = GURL("ws://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016946 request.traffic_annotation =
16947 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2416948 AddWebSocketHeaders(&request.extra_headers);
16949
16950 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:5916951 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4916952 ProxyResolutionService::CreateFixedFromPacResult(
16953 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2416954
danakj1fd259a02016-04-16 03:17:0916955 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2416956
16957 MockWrite data_writes[] = {
16958 // Try to establish a tunnel for the WebSocket connection, with
16959 // credentials. Because WebSockets have a separate set of socket pools,
16960 // they cannot and will not use the same TCP/IP connection as the
16961 // preflight HTTP request.
Bence Béky8d1c6052018-02-07 12:48:1516962 MockWrite("CONNECT www.example.org:80 HTTP/1.1\r\n"
16963 "Host: www.example.org:80\r\n"
16964 "Proxy-Connection: keep-alive\r\n"
16965 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416966
Bence Béky8d1c6052018-02-07 12:48:1516967 MockWrite("GET / HTTP/1.1\r\n"
16968 "Host: www.example.org\r\n"
16969 "Connection: Upgrade\r\n"
16970 "Upgrade: websocket\r\n"
16971 "Origin: http://www.example.org\r\n"
16972 "Sec-WebSocket-Version: 13\r\n"
16973 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
16974 "Sec-WebSocket-Extensions: permessage-deflate; "
16975 "client_max_window_bits\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2416976
16977 MockRead data_reads[] = {
16978 // HTTP CONNECT with credentials.
16979 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
16980
16981 // WebSocket connection established inside tunnel.
Bence Béky8d1c6052018-02-07 12:48:1516982 MockRead("HTTP/1.1 101 Switching Protocols\r\n"
16983 "Upgrade: websocket\r\n"
16984 "Connection: Upgrade\r\n"
16985 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2416986
Ryan Sleevib8d7ea02018-05-07 20:01:0116987 StaticSocketDataProvider data(data_reads, data_writes);
Adam Rice425cf122015-01-19 06:18:2416988 session_deps_.socket_factory->AddSocketDataProvider(&data);
16989
16990 session->http_auth_cache()->Add(
16991 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
16992 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
16993
Bence Béky8d1c6052018-02-07 12:48:1516994 TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
16995
bnc87dcefc2017-05-25 12:47:5816996 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1916997 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2416998 trans->SetWebSocketHandshakeStreamCreateHelper(
16999 &websocket_stream_create_helper);
17000
17001 TestCompletionCallback callback;
17002
tfarina42834112016-09-22 13:38:2017003 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117004 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2417005
17006 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117007 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2417008
17009 const HttpResponseInfo* response = trans->GetResponseInfo();
17010 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5217011 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2417012
17013 EXPECT_EQ(101, response->headers->response_code());
17014
17015 trans.reset();
17016 session->CloseAllConnections();
17017}
17018
Bence Békydca6bd92018-01-30 13:43:0617019#endif // BUILDFLAG(ENABLE_WEBSOCKETS)
17020
bncd16676a2016-07-20 16:23:0117021TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost) {
danakj1fd259a02016-04-16 03:17:0917022 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217023 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917024 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217025 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2217026
17027 HttpRequestInfo request;
17028 request.method = "POST";
17029 request.url = GURL("http://www.foo.com/");
17030 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017031 request.traffic_annotation =
17032 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2217033
danakj1fd259a02016-04-16 03:17:0917034 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617035 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2217036 MockWrite data_writes[] = {
17037 MockWrite("POST / HTTP/1.1\r\n"
17038 "Host: www.foo.com\r\n"
17039 "Connection: keep-alive\r\n"
17040 "Content-Length: 3\r\n\r\n"),
17041 MockWrite("foo"),
17042 };
17043
17044 MockRead data_reads[] = {
17045 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
17046 MockRead(SYNCHRONOUS, OK),
17047 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117048 StaticSocketDataProvider data(data_reads, data_writes);
sclittlefb249892015-09-10 21:33:2217049 session_deps_.socket_factory->AddSocketDataProvider(&data);
17050
17051 TestCompletionCallback callback;
17052
17053 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017054 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0117055 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2217056
17057 std::string response_data;
bnc691fda62016-08-12 00:43:1617058 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2217059
Ryan Sleevib8d7ea02018-05-07 20:01:0117060 EXPECT_EQ(CountWriteBytes(data_writes), trans.GetTotalSentBytes());
17061 EXPECT_EQ(CountReadBytes(data_reads), trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2217062}
17063
bncd16676a2016-07-20 16:23:0117064TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost100Continue) {
danakj1fd259a02016-04-16 03:17:0917065 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217066 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917067 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217068 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2217069
17070 HttpRequestInfo request;
17071 request.method = "POST";
17072 request.url = GURL("http://www.foo.com/");
17073 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017074 request.traffic_annotation =
17075 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2217076
danakj1fd259a02016-04-16 03:17:0917077 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617078 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2217079 MockWrite data_writes[] = {
17080 MockWrite("POST / HTTP/1.1\r\n"
17081 "Host: www.foo.com\r\n"
17082 "Connection: keep-alive\r\n"
17083 "Content-Length: 3\r\n\r\n"),
17084 MockWrite("foo"),
17085 };
17086
17087 MockRead data_reads[] = {
17088 MockRead("HTTP/1.1 100 Continue\r\n\r\n"),
17089 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
17090 MockRead(SYNCHRONOUS, OK),
17091 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117092 StaticSocketDataProvider data(data_reads, data_writes);
sclittlefb249892015-09-10 21:33:2217093 session_deps_.socket_factory->AddSocketDataProvider(&data);
17094
17095 TestCompletionCallback callback;
17096
17097 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017098 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0117099 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2217100
17101 std::string response_data;
bnc691fda62016-08-12 00:43:1617102 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2217103
Ryan Sleevib8d7ea02018-05-07 20:01:0117104 EXPECT_EQ(CountWriteBytes(data_writes), trans.GetTotalSentBytes());
17105 EXPECT_EQ(CountReadBytes(data_reads), trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2217106}
17107
bncd16676a2016-07-20 16:23:0117108TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) {
sclittlefb249892015-09-10 21:33:2217109 ChunkedUploadDataStream upload_data_stream(0);
17110
17111 HttpRequestInfo request;
17112 request.method = "POST";
17113 request.url = GURL("http://www.foo.com/");
17114 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017115 request.traffic_annotation =
17116 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2217117
danakj1fd259a02016-04-16 03:17:0917118 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617119 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2217120 // Send headers successfully, but get an error while sending the body.
17121 MockWrite data_writes[] = {
17122 MockWrite("POST / HTTP/1.1\r\n"
17123 "Host: www.foo.com\r\n"
17124 "Connection: keep-alive\r\n"
17125 "Transfer-Encoding: chunked\r\n\r\n"),
17126 MockWrite("1\r\nf\r\n"), MockWrite("2\r\noo\r\n"), MockWrite("0\r\n\r\n"),
17127 };
17128
17129 MockRead data_reads[] = {
17130 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
17131 MockRead(SYNCHRONOUS, OK),
17132 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117133 StaticSocketDataProvider data(data_reads, data_writes);
sclittlefb249892015-09-10 21:33:2217134 session_deps_.socket_factory->AddSocketDataProvider(&data);
17135
17136 TestCompletionCallback callback;
17137
17138 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017139 trans.Start(&request, callback.callback(), NetLogWithSource()));
sclittlefb249892015-09-10 21:33:2217140
17141 base::RunLoop().RunUntilIdle();
17142 upload_data_stream.AppendData("f", 1, false);
17143
17144 base::RunLoop().RunUntilIdle();
17145 upload_data_stream.AppendData("oo", 2, true);
17146
robpercival214763f2016-07-01 23:27:0117147 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2217148
17149 std::string response_data;
bnc691fda62016-08-12 00:43:1617150 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2217151
Ryan Sleevib8d7ea02018-05-07 20:01:0117152 EXPECT_EQ(CountWriteBytes(data_writes), trans.GetTotalSentBytes());
17153 EXPECT_EQ(CountReadBytes(data_reads), trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2217154}
17155
nharperb7441ef2016-01-25 23:54:1417156#if !defined(OS_IOS)
bncd16676a2016-07-20 16:23:0117157TEST_F(HttpNetworkTransactionTest, TokenBindingSpdy) {
nharperb7441ef2016-01-25 23:54:1417158 const std::string https_url = "https://www.example.com";
17159 HttpRequestInfo request;
17160 request.url = GURL(https_url);
17161 request.method = "GET";
Ramin Halavatib5e433e62018-02-07 07:41:1017162 request.traffic_annotation =
17163 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
nharperb7441ef2016-01-25 23:54:1417164
17165 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4917166 ssl.ssl_info.token_binding_negotiated = true;
17167 ssl.ssl_info.token_binding_key_param = TB_PARAM_ECDSAP256;
bnc3cf2a592016-08-11 14:48:3617168 ssl.next_proto = kProtoHTTP2;
nharperb7441ef2016-01-25 23:54:1417169 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
17170
Ryan Hamilton0239aac2018-05-19 00:03:1317171 spdy::SpdySerializedFrame resp(
17172 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
17173 spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
bncdf80d44fd2016-07-15 20:27:4117174 MockRead reads[] = {CreateMockRead(resp), CreateMockRead(body),
nharperb7441ef2016-01-25 23:54:1417175 MockRead(ASYNC, ERR_IO_PENDING)};
Ryan Sleevib8d7ea02018-05-07 20:01:0117176 StaticSocketDataProvider data(reads, base::span<MockWrite>());
nharperb7441ef2016-01-25 23:54:1417177 session_deps_.socket_factory->AddSocketDataProvider(&data);
bnc87dcefc2017-05-25 12:47:5817178 session_deps_.channel_id_service =
Jeremy Roman0579ed62017-08-29 15:56:1917179 std::make_unique<ChannelIDService>(new DefaultChannelIDStore(nullptr));
danakj1fd259a02016-04-16 03:17:0917180 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
nharperb7441ef2016-01-25 23:54:1417181
17182 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17183 TestCompletionCallback callback;
17184 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017185 trans.Start(&request, callback.callback(), NetLogWithSource()));
fdorayf33fede2017-05-11 21:18:1017186
Bence Béky98447b12018-05-08 03:14:0117187 RunUntilIdle();
nharperb7441ef2016-01-25 23:54:1417188
17189 EXPECT_TRUE(trans.GetResponseInfo()->was_fetched_via_spdy);
17190 HttpRequestHeaders headers;
17191 ASSERT_TRUE(trans.GetFullRequestHeaders(&headers));
17192 EXPECT_TRUE(headers.HasHeader(HttpRequestHeaders::kTokenBinding));
17193}
17194#endif // !defined(OS_IOS)
17195
eustasc7d27da2017-04-06 10:33:2017196void CheckContentEncodingMatching(SpdySessionDependencies* session_deps,
17197 const std::string& accept_encoding,
17198 const std::string& content_encoding,
sky50576f32017-05-01 19:28:0317199 const std::string& location,
eustasc7d27da2017-04-06 10:33:2017200 bool should_match) {
17201 HttpRequestInfo request;
17202 request.method = "GET";
17203 request.url = GURL("http://www.foo.com/");
17204 request.extra_headers.SetHeader(HttpRequestHeaders::kAcceptEncoding,
17205 accept_encoding);
Ramin Halavatib5e433e62018-02-07 07:41:1017206 request.traffic_annotation =
17207 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
eustasc7d27da2017-04-06 10:33:2017208
17209 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps));
17210 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17211 // Send headers successfully, but get an error while sending the body.
17212 MockWrite data_writes[] = {
17213 MockWrite("GET / HTTP/1.1\r\n"
17214 "Host: www.foo.com\r\n"
17215 "Connection: keep-alive\r\n"
17216 "Accept-Encoding: "),
17217 MockWrite(accept_encoding.data()), MockWrite("\r\n\r\n"),
17218 };
17219
sky50576f32017-05-01 19:28:0317220 std::string response_code = "200 OK";
17221 std::string extra;
17222 if (!location.empty()) {
17223 response_code = "301 Redirect\r\nLocation: ";
17224 response_code.append(location);
17225 }
17226
eustasc7d27da2017-04-06 10:33:2017227 MockRead data_reads[] = {
sky50576f32017-05-01 19:28:0317228 MockRead("HTTP/1.0 "),
17229 MockRead(response_code.data()),
17230 MockRead("\r\nContent-Encoding: "),
17231 MockRead(content_encoding.data()),
17232 MockRead("\r\n\r\n"),
eustasc7d27da2017-04-06 10:33:2017233 MockRead(SYNCHRONOUS, OK),
17234 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117235 StaticSocketDataProvider data(data_reads, data_writes);
eustasc7d27da2017-04-06 10:33:2017236 session_deps->socket_factory->AddSocketDataProvider(&data);
17237
17238 TestCompletionCallback callback;
17239
17240 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17241 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17242
17243 rv = callback.WaitForResult();
17244 if (should_match) {
17245 EXPECT_THAT(rv, IsOk());
17246 } else {
17247 EXPECT_THAT(rv, IsError(ERR_CONTENT_DECODING_FAILED));
17248 }
17249}
17250
17251TEST_F(HttpNetworkTransactionTest, MatchContentEncoding1) {
sky50576f32017-05-01 19:28:0317252 CheckContentEncodingMatching(&session_deps_, "gzip,sdch", "br", "", false);
eustasc7d27da2017-04-06 10:33:2017253}
17254
17255TEST_F(HttpNetworkTransactionTest, MatchContentEncoding2) {
sky50576f32017-05-01 19:28:0317256 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "", "",
17257 true);
eustasc7d27da2017-04-06 10:33:2017258}
17259
17260TEST_F(HttpNetworkTransactionTest, MatchContentEncoding3) {
17261 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
sky50576f32017-05-01 19:28:0317262 "", false);
17263}
17264
17265TEST_F(HttpNetworkTransactionTest, MatchContentEncoding4) {
17266 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
17267 "www.foo.com/other", true);
eustasc7d27da2017-04-06 10:33:2017268}
17269
xunjieli96f2a402017-06-05 17:24:2717270TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsSync) {
17271 ProxyConfig proxy_config;
17272 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
17273 proxy_config.set_pac_mandatory(true);
17274 MockAsyncProxyResolver resolver;
Lily Houghton8c2f97d2018-01-22 05:06:5917275 session_deps_.proxy_resolution_service.reset(new ProxyResolutionService(
Ramin Halavatica8d5252018-03-12 05:33:4917276 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
17277 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
Bence Béky8f9d7d3952017-10-09 19:58:0417278 std::make_unique<FailingProxyResolverFactory>(), nullptr));
xunjieli96f2a402017-06-05 17:24:2717279
17280 HttpRequestInfo request;
17281 request.method = "GET";
17282 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1017283 request.traffic_annotation =
17284 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2717285
17286 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17287 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17288
17289 TestCompletionCallback callback;
17290
17291 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17292 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17293 EXPECT_THAT(callback.WaitForResult(),
17294 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
17295}
17296
17297TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsAsync) {
17298 ProxyConfig proxy_config;
17299 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
17300 proxy_config.set_pac_mandatory(true);
17301 MockAsyncProxyResolverFactory* proxy_resolver_factory =
17302 new MockAsyncProxyResolverFactory(false);
17303 MockAsyncProxyResolver resolver;
Lily Houghton8c2f97d2018-01-22 05:06:5917304 session_deps_.proxy_resolution_service.reset(new ProxyResolutionService(
Ramin Halavatica8d5252018-03-12 05:33:4917305 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
17306 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
Lily Houghton8c2f97d2018-01-22 05:06:5917307 base::WrapUnique(proxy_resolver_factory), nullptr));
xunjieli96f2a402017-06-05 17:24:2717308 HttpRequestInfo request;
17309 request.method = "GET";
17310 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1017311 request.traffic_annotation =
17312 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2717313
17314 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17315 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17316
17317 TestCompletionCallback callback;
17318 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17319 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17320
17321 proxy_resolver_factory->pending_requests()[0]->CompleteNowWithForwarder(
17322 ERR_FAILED, &resolver);
17323 EXPECT_THAT(callback.WaitForResult(),
17324 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
17325}
17326
17327TEST_F(HttpNetworkTransactionTest, NoSupportedProxies) {
Lily Houghton8c2f97d2018-01-22 05:06:5917328 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4917329 ProxyResolutionService::CreateFixedFromPacResult(
17330 "QUIC myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2717331 session_deps_.enable_quic = false;
17332 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17333
17334 HttpRequestInfo request;
17335 request.method = "GET";
17336 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1017337 request.traffic_annotation =
17338 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2717339
17340 TestCompletionCallback callback;
17341 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17342 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17343 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17344
17345 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NO_SUPPORTED_PROXIES));
17346}
17347
[email protected]89ceba9a2009-03-21 03:46:0617348} // namespace net